407 lines
15 KiB
ObjectPascal
407 lines
15 KiB
ObjectPascal
unit framegrafico;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Forms, Controls, ExtCtrls, Astronomy, DateUtils, Graphics,
|
|
StdCtrls, LResources;
|
|
|
|
|
|
procedure calcolapianeti;
|
|
function FormattaOraDaMinutiGiorno(minutigiorno:integer):string;
|
|
|
|
type
|
|
|
|
{ TPianetiGraph }
|
|
|
|
TPianetiGraph = class(TFrame)
|
|
Label1: TLabel;
|
|
PaintBox1: TPaintBox;
|
|
procedure FrameMouseLeave(Sender: TObject);
|
|
procedure ImpostaTempoClick(Sender: TObject; Tempo:TDateTime; lat, long:double);
|
|
procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer);
|
|
procedure PaintBox1Paint(Sender: TObject);
|
|
|
|
private
|
|
|
|
public
|
|
var colorform:TColor;
|
|
end;
|
|
|
|
type
|
|
TNomePianeta= (Sole, Luna, Mercurio, Venere, Marte, Giove, Saturno, Urano, Nettuno);
|
|
TPianeta= record
|
|
colore:Tcolor;
|
|
sorge:integer; //minuti da inizio giornata
|
|
tramonta:integer; //minuti da inizio giornata
|
|
distanza:double; //distanza in unità astronomiche
|
|
testo:string;
|
|
isinsky: boolean; // variabile che dice se l'oggetto è nel cielo nel caso sia l'alba che il tramonto non siano ottenibili
|
|
illumData:astro_illum_t;
|
|
|
|
case nome: TNomePianeta of //questo record genera i campi per il crepuscolo civile solo se il nome è Sole
|
|
Sole: (civildawn, civildusk, nauticaldawn, nauticaldusk, astronomicaldawn, astronomicaldusk :integer);
|
|
Luna, Mercurio, Venere, Marte, Giove, Saturno, Urano, Nettuno: ( );
|
|
end;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
{ TPianetiGraph }
|
|
|
|
var
|
|
//Array dei vari oggetti celesti $00090909
|
|
oggetticelesti:array of TPianeta=
|
|
(( colore: $003AE1FE; sorge: 0; tramonta: 0; distanza: 0; testo: 'Sole'; isinsky: False; illumData:(); nome: Sole; civildawn: 0; civildusk:0; nauticaldawn:0; nauticaldusk:0; astronomicaldawn:0; astronomicaldusk:0 ),
|
|
( colore: $00EADBCD; sorge:0; tramonta: 0; distanza: 0; testo: 'Luna'; isinsky: False;illumData:(); nome: Luna;),
|
|
( colore: $00A1D11D; sorge:0; tramonta: 0; distanza: 0; testo: 'Mercurio'; isinsky: False;illumData:(); nome: Mercurio;),
|
|
( colore: $00D3D200; sorge:0; tramonta: 0; distanza: 0; testo: 'Venere'; isinsky: False;illumData:(); nome: Venere; ),
|
|
( colore: $005352EE; sorge: 0; tramonta: 0; distanza: 0; testo: 'Marte'; isinsky: False;illumData:(); nome: Marte;),
|
|
( colore: $00628EFF; sorge: 0; tramonta: 0; distanza: 0; testo: 'Giove'; isinsky: False;illumData:(); nome: Giove; ),
|
|
( colore: $00439FFF; sorge: 0; tramonta: 0; distanza: 0; testo: 'Saturno'; isinsky: False;illumData:(); nome: Saturno;),
|
|
( colore: $00FFA054; sorge: 0; tramonta: 0; distanza: 0; testo: 'Urano'; isinsky: False;illumData:(); nome: Urano;),
|
|
( colore: $00CD275F; sorge: 0; tramonta: 0; distanza: 0; testo: 'Nettuno'; isinsky: False;illumData:(); nome: Nettuno;)
|
|
);
|
|
|
|
oggetto:string;
|
|
durataora:double;
|
|
durataminuto:double;
|
|
duratamezzora:double;
|
|
durataorai:integer; //la durata ora per la variabile i
|
|
orafine:integer;
|
|
altezzarighe:double;
|
|
|
|
|
|
//variabili di posizione
|
|
latitudine:double;
|
|
longitudine:double;
|
|
altitudine:integer=500;
|
|
|
|
tempoinizio:TDateTime;//tempo di inizio della giornata coincide con le 0.0 della giornata corrente oppure quello impostato dall'utente
|
|
isFirstTime:boolean=True;
|
|
|
|
const
|
|
|
|
xtesto=10;
|
|
xgrafico=50; // cordinata x di inizio del grafico
|
|
distrighetop=30;
|
|
spesspianeti=13; //spessore righe sorgere e tramonto PianetiGraph
|
|
aggpospianeti=2; //aggiusta la posizione del rettangolo PianetiGraph rispetto al testo
|
|
ridpaint=60; //indica quanto è più piccolo in pixel il grafico (dal righello in poi) rispetto alla larghezza della paintbox
|
|
|
|
distrighellotop=25;
|
|
altezzarighello=6;
|
|
mezzorighello=5;
|
|
roundrett=5; //arrottondamento angoli rettangoli
|
|
|
|
procedure TPianetiGraph.PaintBox1Paint(Sender: TObject);
|
|
|
|
|
|
var
|
|
i:integer=1;
|
|
corpo:TPianeta;
|
|
orafine2:integer;
|
|
begin
|
|
|
|
|
|
|
|
|
|
if isFirstTime then
|
|
begin
|
|
tempoinizio:=EncodeDate(YearOf(Now), MonthOf(Now), DayOf(Now));
|
|
calcolapianeti;
|
|
isFirstTime:=False;
|
|
end;
|
|
|
|
|
|
orafine:=PaintBox1.Width-ridpaint+xgrafico; //calcola gli ultimi pixel da rappresentare nel righello
|
|
orafine2:=PaintBox1.Width-ridpaint;
|
|
durataora:=(PaintBox1.Width-ridpaint)/24; //calcola il numero di pixel che sono rappresentati da un ora
|
|
durataminuto:=durataora/60; //calcola il numero di pixel che rappresentano un minuto
|
|
duratamezzora:=(PaintBox1.Width-ridpaint)/48;
|
|
altezzarighe:=(PaintBox1.height/11); //calcola la distanza che vi è tra le diverse righe che rappresentano il sorg e il tramont dei PianetiGraph
|
|
|
|
PaintBox1.Canvas.Brush.Color:=colorform; //decide il colore di sfondo del canvas
|
|
PaintBox1.Canvas.Font.Color:=clWhite; //mette il font bianco di default perchè cambia colore dal tema chiaro a scuro del sistema
|
|
|
|
for corpo in oggetticelesti do //scrive i nomi degli oggetti celesti e rettangoli
|
|
begin
|
|
PaintBox1.Canvas.Pen.Color:=clWhite;
|
|
PaintBox1.Canvas.Font.Size:=11;
|
|
PaintBox1.Canvas.TextOut(xtesto,round(altezzarighe*i+distRighetop), copy(corpo.testo,0,3));
|
|
|
|
|
|
if corpo.nome= Sole then
|
|
begin //i crepuscoli vanno messi in ordine dall'astronomio al civile per non fare in modo che si sovrascrivano a vicenda
|
|
//crepuscolo astronomico
|
|
PaintBox1.Canvas.Brush.Color:=$00300A00;
|
|
PaintBox1.Canvas.Pen.Color:=clWhite;
|
|
PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.astronomicaldusk/1440),round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+orafine2*corpo.astronomicaldawn/1440),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett);
|
|
|
|
|
|
//crepuscolo nautico
|
|
PaintBox1.Canvas.Brush.Color:=$009E2200;
|
|
PaintBox1.Canvas.Pen.Color:=clWhite;
|
|
PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.nauticaldusk/1440),round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+orafine2*corpo.nauticaldawn/1440),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett);
|
|
|
|
|
|
//crepuscolo civile
|
|
PaintBox1.Canvas.Brush.Color:=$00FF3700;
|
|
PaintBox1.Canvas.Pen.Color:=clWhite;
|
|
PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.civildusk/1440),round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+orafine2*corpo.civildawn/1440),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett);
|
|
end;
|
|
|
|
PaintBox1.Canvas.Brush.Color:=corpo.colore;
|
|
PaintBox1.Canvas.Pen.Color:=clWhite;
|
|
if (corpo.sorge=-1) and (corpo.tramonta>=0) then
|
|
begin
|
|
PaintBox1.Canvas.RoundRect(xgrafico,round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+(orafine2*corpo.tramonta/1440)),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett);
|
|
end else
|
|
begin
|
|
if (corpo.sorge>=0) and (corpo.tramonta=-1) then
|
|
begin
|
|
PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.sorge/1440),round(altezzarighe*i+aggpospianeti+distrighetop),orafine,round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett);
|
|
end else
|
|
|
|
begin
|
|
|
|
if (corpo.sorge=-1) and (corpo.tramonta=-1) then
|
|
begin
|
|
if corpo.isinsky=True then
|
|
PaintBox1.Canvas.RoundRect(xgrafico,round(altezzarighe*i+aggpospianeti+distrighetop),orafine,round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett);
|
|
end else
|
|
|
|
begin
|
|
|
|
if corpo.sorge<corpo.tramonta then
|
|
PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.sorge/1440),round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+orafine2*corpo.tramonta/1440),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett)
|
|
else
|
|
begin
|
|
PaintBox1.Canvas.RoundRect(xgrafico,round(altezzarighe*i+aggpospianeti+distrighetop),round(xgrafico+(orafine2*corpo.tramonta/1440)),round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett);
|
|
PaintBox1.Canvas.RoundRect(round(xgrafico+orafine2*corpo.sorge/1440),round(altezzarighe*i+aggpospianeti+distrighetop),orafine,round(altezzarighe*i+aggpospianeti+spesspianeti+distrighetop),roundrett,roundrett);
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
PaintBox1.Canvas.Brush.Color:=colorform; //decide il colore di sfondo del canvas
|
|
i:=i+1;
|
|
|
|
end;
|
|
|
|
for i:=0 to 24 do //crea le tacche delle ore
|
|
begin
|
|
durataorai:=round( durataora*i);
|
|
PaintBox1.Canvas.Pen.Color:=clwhite;
|
|
PaintBox1.Canvas.Line(durataorai+xgrafico,distrighellotop,durataorai+xgrafico,distrighellotop+altezzarighello);
|
|
|
|
PaintBox1.Canvas.Pen.Color:=clNone;
|
|
PaintBox1.Canvas.TextOut(durataorai+xgrafico-6,5, inttostr(i));
|
|
end;
|
|
|
|
for i:=0 to 23 do //crea le tacche delle mezzore
|
|
begin
|
|
durataorai:=round( durataora*i+duratamezzora);
|
|
PaintBox1.Canvas.Pen.Color:=clwhite;
|
|
PaintBox1.Canvas.Line(durataorai+xgrafico,distrighellotop+round(mezzorighello/2),durataorai+xgrafico,distrighellotop+round(mezzorighello));
|
|
|
|
|
|
end;
|
|
|
|
PaintBox1.Canvas.Line(xgrafico,distrighellotop+mezzorighello,orafine, distrighellotop+mezzorighello);//disegna la riga sulle tacche
|
|
|
|
|
|
end;
|
|
|
|
procedure TPianetiGraph.ImpostaTempoClick(Sender: TObject; Tempo:TDateTime; lat, long:double);
|
|
begin
|
|
|
|
tempoinizio:=Tempo;
|
|
latitudine:=lat;
|
|
longitudine:=long;
|
|
calcolapianeti;
|
|
PaintBox1.Refresh;
|
|
end;
|
|
|
|
procedure TPianetiGraph.FrameMouseLeave(Sender: TObject);
|
|
begin
|
|
Label1.Caption:='';
|
|
end;
|
|
|
|
|
|
var
|
|
stop:boolean;
|
|
|
|
procedure TPianetiGraph.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
elementi:TPianeta;
|
|
valoreriga: integer;
|
|
magnitudine:string;
|
|
fasepianetiinterni:string;
|
|
saturnoring:string;
|
|
orasorge:string;
|
|
oratramonta:string;
|
|
crepuscoli:string;
|
|
i:integer;
|
|
begin
|
|
i:=0;
|
|
for elementi in oggetticelesti do
|
|
begin
|
|
i:=i+1;
|
|
valoreriga:=round(altezzarighe*i+aggpospianeti+distrighetop);
|
|
if (Y>valoreriga) and (Y<valoreriga+spesspianeti) then
|
|
begin
|
|
if elementi.nome=Sole then
|
|
begin
|
|
crepuscoli:=' Crepuscoli:';
|
|
crepuscoli:=crepuscoli+' Astronomico '+ FormattaOraDaMinutiGiorno(elementi.astronomicaldusk)+ '-'+ FormattaOraDaMinutiGiorno(elementi.astronomicaldawn);
|
|
crepuscoli:=crepuscoli+' Nautico '+ FormattaOraDaMinutiGiorno(elementi.nauticaldusk)+ '-'+ FormattaOraDaMinutiGiorno(elementi.nauticaldawn);
|
|
crepuscoli:=crepuscoli+' Civile '+ FormattaOraDaMinutiGiorno(elementi.civildusk)+ '-'+ FormattaOraDaMinutiGiorno(elementi.civildawn);
|
|
end;
|
|
|
|
|
|
|
|
magnitudine:=' Magnitudine: '+ SysUtils.FormatFloat('0.00', elementi.illumData.mag);
|
|
if (elementi.nome=Mercurio) or (elementi.nome=Venere) then fasepianetiinterni:=' Fase: '+FormatFloat('0.00', elementi.illumData.phase_fraction) ;
|
|
if (elementi.nome=Saturno) then saturnoring:=' Inclinazione Anelli: '+FormatFloat('0.00', elementi.illumData.ring_tilt);
|
|
if elementi.sorge=-1 then orasorge:='--'
|
|
else orasorge:=FormattaOraDaMinutiGiorno(elementi.sorge);
|
|
|
|
if elementi.tramonta=-1 then oratramonta:='--'
|
|
else oratramonta:=FormattaOraDaMinutiGiorno(elementi.tramonta) ;
|
|
|
|
Label1.Caption:=elementi.testo+magnitudine+fasepianetiinterni+saturnoring+Crepuscoli+' Sorge alle: '+orasorge + ' Tramonta alle: ' + oratramonta+' Distanza '+SysUtils.FormatFloat('0.000',elementi.distanza)+'UA'; ;
|
|
|
|
break;
|
|
end
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
function FormattaOraDaMinutiGiorno(minutigiorno:integer):string;
|
|
begin
|
|
result:= SysUtils.FormatFloat('00',(minutigiorno div 60))+':'+ sysUtils.FormatCurr('00', (minutigiorno mod 60) );
|
|
|
|
end;
|
|
|
|
procedure calcolapianeti;
|
|
var
|
|
i:integer;
|
|
alba:TDateTime;
|
|
tramonto:TDateTime;
|
|
crepalba:TDateTime;//crepuscolo civile alba
|
|
creptram:TDateTime;//crepuscolo tramonto alba
|
|
|
|
minutidainizio:integer; //indica il numero di minuti da inizio giorno
|
|
numerocorpo:integer; //serve per corrispondenza tra gli enum in TPianeta e quelli contenuti in astro_body_t
|
|
|
|
ognicrepuscolo:TCrepuscolo;
|
|
datecrep:TDateTime;
|
|
segnaposto:integer;
|
|
|
|
albaerror:boolean=False; //variabili utilizzate per segnare in caso di errore;
|
|
tramontoerror:boolean=False;
|
|
altezzaoggetto:double=0;
|
|
begin
|
|
|
|
|
|
for i:=0 to 8 do //serve per corrispondenza tra gli enum in TPianeta e quelli contenuti in astro_body_t
|
|
begin
|
|
|
|
albaerror:=False;
|
|
tramontoerror:=False;
|
|
|
|
case oggetticelesti[i].nome of
|
|
Mercurio: numerocorpo:=0;
|
|
Venere: numerocorpo:=1;
|
|
Marte: numerocorpo:=3;
|
|
Giove: numerocorpo:=4;
|
|
Saturno: numerocorpo:=5;
|
|
Urano: numerocorpo:=6;
|
|
Nettuno: numerocorpo:=7;
|
|
Sole: numerocorpo:=9;
|
|
Luna: numerocorpo:=10;
|
|
end;
|
|
|
|
|
|
oggetticelesti[i].distanza:=astronomy.DistanzaOggetto(numerocorpo, latitudine, longitudine, altitudine, DateUtils.IncHour(tempoinizio, 12));
|
|
oggetticelesti[i].illumData:=astronomy.Illuminazione(numerocorpo, DateUtils.IncHour(tempoinizio, 12));
|
|
|
|
if oggetticelesti[i].nome=Sole then
|
|
begin
|
|
//il sole presenta anche i crepuscoli a differenza degli altri oggetti
|
|
|
|
for ognicrepuscolo in Tcrepuscolo do
|
|
begin
|
|
|
|
|
|
datecrep:=Astronomy.Crepuscolo(latitudine, longitudine, altitudine, 1, tempoinizio, ognicrepuscolo);
|
|
segnaposto:=DateUtils.MinutesBetween(tempoinizio, datecrep);
|
|
|
|
case ognicrepuscolo of
|
|
civildawn:oggetticelesti[i].civildawn:=segnaposto;
|
|
civildusk:oggetticelesti[i].civildusk:=segnaposto;
|
|
nauticaldawn:oggetticelesti[i].nauticaldawn:=segnaposto;
|
|
nauticaldusk:oggetticelesti[i].nauticaldusk:=segnaposto;
|
|
astronomicaldawn:oggetticelesti[i].astronomicaldawn:=segnaposto;
|
|
astronomicaldusk:oggetticelesti[i].astronomicaldusk:=segnaposto;
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
try
|
|
alba:=Astronomy.TrovaSorgereOggetto(numerocorpo, latitudine, longitudine, altitudine, tempoinizio, 1);
|
|
except
|
|
on E:exception do
|
|
begin
|
|
albaerror:=True;
|
|
oggetticelesti[i].sorge:=-1;
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
try
|
|
tramonto:=Astronomy.TrovaTramontoOggetto(numerocorpo, latitudine, longitudine, altitudine, tempoinizio, 1);
|
|
except
|
|
on E:exception do
|
|
begin
|
|
|
|
tramontoerror:=True;
|
|
oggetticelesti[i].tramonta:=-1;
|
|
end;
|
|
end;
|
|
|
|
|
|
if albaerror=False then oggetticelesti[i].sorge:=DateUtils.MinutesBetween(tempoinizio, alba);
|
|
|
|
if tramontoerror=False then oggetticelesti[i].tramonta:=DateUtils.MinutesBetween(tempoinizio, tramonto);
|
|
|
|
if albaerror and tramontoerror then
|
|
begin
|
|
|
|
end;
|
|
altezzaoggetto:= astronomy.AltitudineOggetto(numerocorpo, latitudine, longitudine, altitudine, DateUtils.IncHour(tempoinizio, 12));
|
|
if altezzaoggetto>0 then
|
|
oggetticelesti[i].isinsky:=True else oggetticelesti[i].isinsky:=False;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end.
|
|
|