calcolare il tempo in cui il sole è X gradi sotto / sopra l'orizzonte

Voglio sapere qual è l'ora in cui il sole è X gradi sotto / sopra l'orizzonte.

Ad esempio, voglio trovare il momento in cui il sole è 19,75 gradi sotto l'orizzonte. Penso che abbia qualcosa a che fare con lo zenith nella function date_sunrise / date_sunset ma non ne sono sicuro.

Grazie in anticipo!

  1. raccogli dati di effemeridi di Sun per il giorno che ti serve

    fai 1 ora di step e ottieni la posizione di Suns in coordinate azimutali per la geo-localizzazione di cui hai bisogno. Utilizza le equazioni che hai trovato o utilizza qualche servizio WEB come:

    • A JPL Horizons non piace questo dato che usano alcuni fotogrammi di riferimento di output strani che non corrispondono alle mie misurazioni, ma è più probabile che io trasformi qualcosa di sbagliato lungo la strada …
    • L'osservatorio di Presov è il mio preferito (ma è in slovacco). L'output è facilmente riconducibile ai motori delle miniere e l'output è corrispondente a osservazioni, calcoli, stime e misurazioni di mine. Compila semplicemente:

      • geo-localizzazione (Miesto pozorovania)
      • data, ora (Dátum a čas pozorovania)
      • in basso da sinistra: intervallo [giorni], intervallo intervallo [giorni]
      • clicca sul button per Sun (Slnko), Moon (Mesiac), Planets (Planety)

    ci sono molte pagine di questo tipo, ma guardate sempre se emettono dati corretti. Uso le leggi / equazioni di Keplero per formare movimenti planetari (precisione inferiore ma per Terra-Sole dovrebbe essere OK). Al giorno d'oggi i motori usano invece il model gravitazionale (ma questo è instabile con tempi più lunghi da epoca)

  2. gestire i dati come set di punti 3D lungo polilinea (azimut, altezza, tempo)

  3. ora basta trovare nei dati 2 punti

    uno sotto l'angolo desiderato e il successivo sopra l'angolo desiderato. I punti di stand devono essere vicini. Se qualsiasi punto si trova sull'angolazione desiderata, allora hai già la soluzione, quindi fermati

  4. interpolare il tempo di attraversamento dell'angolo di altezza

    inserisci la descrizione dell'immagine qui

    quindi se l'angolo di altezza desiderato è b e il tempo desiderato t allora:

    • a0 , a1 sono angoli azimutali
    • b0 , b1 sono angoli di altezza
    • t0 , t1 sono volte

    quindi basta risolvere questo sistema lineare:

     b=b0+(b1-b0)*u t=t0+(t1-t0)*u 

    quindi se non ho fatto qualche errore stupido:

     t=t0+((t1-t0)*(b-b0)/(b1-b0)) 

[Gli appunti]

se non hai bisogno di una precisione troppo alta (e un utilizzo superiore a 100 anni) e la geo-localizzazione è fissa, puoi periodicamente eseguire l'anno e utilizzare questi dati periodicamente. In questo modo non avrai bisogno del passaggio 1 in fase di esecuzione.

[Modifica1] Legge di Keplero

se vuoi andare da questa parte guarda qui . Avrai bisogno dei parametri orbitali e di rotazione della Terra. Questi sono estratti dal mio motore di effemeridi * .ini per il sistema solare:

 [Earth] txr_map=Earth_Map.jpg txr_nor=Earth_Normal.jpg txr_clouds=Earth_Cloud.jpg txr_lights=Earth_Light.jpg txr_ring_map= txr_ring_alpha= is_star=0 mother=Sun re=6378141.2 rp=6356754.79506139 r0=-1 r1=-1 ha=60000 vd=250000 B0r=0.1981 B0g=0.4656 B0b=0.8625 B0a=0.75 t0=-0.0833333333333333 ; this means 1.1.2000 00:00:00 UT a=149597896927.617 da=-0.122872993839836 e=0.01673163 de=-1.00232717316906E-9 i=-9.48516635288838E-6 di=-6.38963964003634E-9 O=-0.004695 dO=-1.15274665428334E-7 o=1.79646842620403 do=1.51932094052745E-7 M =1.7464 dM =0.0172021242603194 ddM=0 rota0 =3.0707963267949 rotda =6.30038738085328 prea0 =1.5707963267949 preda =-6.68704522111755E-7 prei =0.409124584728753 predi =0 nuta =0 nutda =0 nutia =0 nutdia=0 nutii =0 nutdii=0 

e qui ci sono le spiegazioni:

 [Name] [string id] object ID name txr_map [filename] surface texture txr_nor [filename] surface normal/bump texture txr_clouds [filename] cloud blend texture (white cloud, black clear sky) txr_lights [filename] night surface texture txr_ring_map [filename] rings color texture txr_ring_alpha [filename] rings alpha texture (alpha0 transparent, alpha1 solid) is_star [0/1] is star ? mother [string] "" or owner object name re [m] equator radius rp [m] polar radius r0 [m] -1 or rings inner radius r1 [m] -1 or rings outer radius ha [m] 0 or atmosphere thickness vd [m] -1 or atmosphere view depth B0r <0,1> star R light or atmosphere color B0g <0,1> star G light or atmosphere color B0b <0,1> star B light or atmosphere color B0a <0,1> overglow of star below horizont t0 [day] t0 time the parameters are taken after 1.1.2000 00:00:00 a [m] a main semiaxis da [m/day] a change in time e [-] e eccentricity de [-/day] e change in time i [rad] i inclination di [rad/day] i change in time O [rad] O (node n) position of inclination axis dO [rad/day] O node shift (pi2/T) o [rad] o perihelium (no change in inclination position) do [rad/day] o perihelium shift (pi2/T) M [rad] M rotation around owner position in t0 dM [rad/day] dM orbital rotation (pi2/draconic month) ddM0 [rad/day^2] dM change in time rota0 [rad] rota0 rotation around self axis position in t0 rotda [rad/day] rotda mean rotation around self axis prea0 [rad] prea rotation axis position in t0 preda [rad/day] preda precession rotation (pi2/Platonic year) prei [rad] prei equator inclination to ecliptic predi [rad/day] prei change in time nuta [rad] nuta angle position on nutation ellipse nutda [rad/day] nutation rotation (pi2/T) nutia [rad] nutia nutation (of rotation axis) ellipse semiaxis axis in ecliptic plane nutdia [rad/day] nutia change in time nutii [rad] nutii nutation (of rotation axis) ellipse semiaxis axis in rotation axis direction nutdii [rad/day] nutii change in time 

Ignora i parametri is_star, trame, anelli e atmosfera. Così:

  1. port Sun in posizione (0,0,0) in coordinate cartesiane
  2. calcolare la posizione della Terra (x,y,z) dalla legge di Keplero

    Sun è quindi (-x,-y,-z) in coordinate geocentriche

  3. ruota indietro di rotazione giornaliera, precessione, nutazione (-x,-y,-z) -> (x',y',z')

  4. calcola il frame NEH per la tua geolocalizzazione (North,East,High(Up))
  5. converti (x',y',z') in coordinate locali NEH (xx,yy,zz)
  6. calcolare:

     azimut=atanxy(-xx,-yy) height=atanxy(sqrt((xx*xx)+(yy*yy)),-zz) 

    e questo è tutto

ecco il mio calcolo eliocentrico astro della posizione del corpo:

 void astro_body::compute(double t) { // t is time in days after 1.1.2000 00:00:00 // double pos[3] is output heliocentric position [m] // reper rep is output heliocentric position [m] and orientation transform matrix (mine class) where Z is rotation axis (North pole) and X is long=0,lat=0 rot_a.compute(t); // compute actual value for orbital parameters changing in time pre_a.compute(t); // the actual parameter is in XXX.a you can ignore this part pre_i.compute(t); nut_a.compute(t); nut_ia.compute(t); nut_ii.compute(t); // pre_a=pre_a0+(pre_da.a*dt)+(nut_ia*cos(nut_a)); // some old legacy dead code // pre_i=pre_i0+(pre_di.a*sin(pre_e))+(nut_ii*sin(nut_a)); rep.reset(); // rep is the transform matrix representing body coordinate system (orientation and position) rep.lrotz(pre_a.a); // local rotation around reps Z axis by pre_a.a [rad] angle rep.lroty(pre_i.a); rep.lrotx(nut_ia.a*cos(nut_a.a)); rep.lroty(nut_ii.a*sin(nut_a.a)); rep.lrotz(rot_a.a); a.compute(t); // the same as above can ignore this part e.compute(t); i.compute(t); O.compute(t); o.compute(t); M.compute(t); M.compute(t); double c0,c1,c2,sO,si,cO,ci,b; // trajectory constants double x,y; int q; if (ea>=1.0) ea=0; c0=sqrt((1.0-ea)/(1.0+ea)); // some helper constants computation c1=sqrt((1.0+ea)/(1.0-ea)); c2=aa*(1-ea*ea); sO=sin(Oa); cO=cos(Oa); si=sin(-ia); ci=cos(-ia); b=aa*sqrt(1.0-ea); Ma-=oa; // correction Ma=Ma-pi2*floor(Ma/pi2); E=Ma; for (q=0;q<20;q++) E=M.a+ea*sin(E); // Kepler's equation V=2.0*atan(c1*tan(E/2.0)); r=c2/(1.0+ea*cos(V)); pos[0]=r*cos(V+oa-Oa); // now just compute heliocentric position along ecliptic ellipse pos[1]=r*sin(V+oa-Oa); // and then rotate by inclination pos[2]=-pos[1]*si; pos[1]=+pos[1]*ci; x=pos[0]; y=pos[1]; pos[0]=x*cO-y*sO; pos[1]=x*sO+y*cO; if ((mother>=0)&&(tab!=NULL)) vector_add(pos,pos,tab[mother].pos); // if satelite like Moon add owners position rep.gpos_set(pos); // set the global position to transform matrix also } //--------------------------------------------------------------------------- 

reper class reper è abbastanza complicata (qualcosa come GLM) l'unica cosa di cui hai bisogno sono le rotazioni locali (tutte le altre cose sono fondamentali). questo è il modo in cui lrotx funziona:

 double c=cos(ang),s=sin(ang); double rot[16],inv[16]; // rot is the rotation around x transform matrix rot=(1, 0, 0, 0, 0, c,-s, 0, 0, s, c, 0, 0, 0, 0, 1); inv=inverse(rep); // inverse is inverse matrix 4x4 inv=inv*rot rep=inverse(inv); 
  • rep è la matrix di input e output
  • ang è l'angolo di rotazione [rad]

ora puoi usare rep per convertire in / dal sistema di coordinate locali della Terra

  • Da LCS a GCS (l2g) ... (gx,gy,gz)=rep*(lx,ly,lz)
  • Da GCS a LCS (g2l) ... (lx,ly,lz)=inverse(rep)*(gx,gy,gz)

local è il sistema di coordinate terrestri e il sistema di coordinate globali del Sole