Per completare il nucleo essenziale delle funzioni usate per pilotare l'accesso al jpl toolkit scriviamo tre nuove, e per il momento, ultime, funzioni. Il toolkit è molto ampio, c'è ancora parecchio da sviluppare, ma per l'astrologia serve molto poco.
Spekzr_c
Questa funzione serve per il calcolo di posizione, espressa in coordinate rettangolari e vettore velocità, di un corpo celeste dati il corpo obiettivo, il punto di osservazione, l'istante temporale e alcune altre variabili che non utilizzeremo. Vediamo per prima cosa la signature, ripetendo quello che abbiamo già visto con le ctypes di Python:
void spkezr_c ( ConstSpiceChar *targ, SpiceDouble et, ConstSpiceChar *ref, ConstSpiceChar *abcorr, ConstSpiceChar *obs, SpiceDouble starg[6], SpiceDouble *lt ) Variable I/O Description -------- --- -------------------------------------------------- targ I Target body name. et I Observer epoch. ref I Reference frame of output state vector. abcorr I Aberration correction flag. obs I Observing body name. starg O State of target. lt O One way light time between observer and target. starg is a Cartesian state vector representing the position and velocity of the target body relative to the specified observer. `starg' is corrected for the specified aberrations, and is expressed with respect to the reference frame specified by `ref'. The first three components of `starg' represent the x-, y- and z-components of the target's position; the last three components form the corresponding velocity vector. The position component of `starg' points from the observer's location at `et' to the aberration-corrected location of the target. Note that the sense of the position vector is independent of the direction of radiation travel implied by the aberration correction. The velocity component of `starg' is the derivative with respect to time of the position component of `starg.' Units are always km and km/sec.
La documentazione ci dice che, dati il target body name (stringa), l'observer epoch (double), il reference frame (il nostro opzionale kernel), il flag di correzione dell'aberrazione (che non usiamo), il nome del corpo di osservazione (la Terra nel nostro caso - Stringa) e dun vettore double di 6 elementi e un eventuale puntatore a double (light time, non utilizzato), possiamo accedere ad un vettore posizione (coordinate x,y,z) e un vettore velocità (vx, vy, vz) deferenziando il vettore double che abbiamo fornito in input).
Siccome il codice sta diventando troppo lungo per incorporarlo per intero, scrivo solo i segmenti, avrete capito che i suguenti frammenti vanno accodati al codice già scritto nei post precedenti, uno all'interno della public interface CLibrary e uno in coda. Attenti però a come definiamo il valore di ritorno, nel caso vogliamo dereferenziare un vettore: nella dichiarazione dentro l'interface indicheremo solo il tipo di dati, nella definizione il double sarà dichiarato come array:
public class CSpice { private static final CLibrary INSTANCE; static { INSTANCE = Native.load("cspice", CLibrary.class); } public interface CLibrary extends Library { ........... double spkezr_c(String targ, double et, String ref, String abcorr, String obs, double[] starg, DoubleByReference lt); } // funzione spekzr_c } double[] spkezr_c(String targ, double et, String ref, String abcorr, String obs, double[] starg, DoubleByReference lt){ for (int i = 0; i < 6; i++){ starg[0] = 0.0; } INSTANCE.spkezr_c(targ, et, ref, abcorr, obs, starg, lt); return starg; }
L'array starg, come valore di ritorno, andrà scandito con un ciclo for per recuperare i singoli valori dei due vettori.
Estendiamo il file Main.java:
.... DoubleByReference p = new DoubleByReference(); System.out.println("Secondi dal J2000: "+spice.str2et_c("2000-01-01T12:00:00", p)); System.out.println("\n"); // spkezr_c String timestring = "2017-08-10T18:53:22"; double et = spice.str2et_c(timestring, p); String ref = "J2000"; String target = "SATURN_BARYCENTER"; String observer = "EARTH"; String abcorr = "NONE"; double[] starg = new double[6]; DoubleByReference lt = new DoubleByReference(); double[] d = new double[6]; d = spice.spkezr_c(target, et, ref, abcorr, observer, starg, lt); String[] elem = {" x: "," y: "," z: ","vx: ","vy: ","vz: "}; System.out.println("Vettore posizione e velocità di Saturno baricentro per il " + timestring + "\n"); for (int i = 0; i < 6; i++){ System.out.println(elem[i]+ " " + d[i]); } System.out.println("\n");
In breve, inizializziamo le variabili di input, comprese quelle che serviranno per estrarre i valori di ritorno, secondo il loro tipo, chiamiamo la funzione e scompattiamo l'array.
Facciamo una prova:
ubuntu@ubuntu-desktop:~/Scrivania/CSpice$ javac -classpath .:jna-5.2.0.jar -g Main.java ubuntu@ubuntu-desktop:~/Scrivania/CSpice$ java -classpath .:jna-5.2.0.jar Main Valore di Pi greco: 3.141592653589793 Secondi in un giorno: 86400.0 Numero di gradi per radiante: 57.29577951308232 OK Kernel caricati Secondi dal J2000: 64.18392728473108 Vettore posizione e velocità di Saturno baricentro per il 2017-08-10T18:53:22 x: -2.1891291720093992E8 y: -1.2962750669325852E9 z: -5.289702916654781E8 vx: -10.299865176779855 vy: -20.74633831944049 vz: -9.37634837706102 OK Kernel dismessi ubuntu@ubuntu-desktop:~/Scrivania/CSpice$
Come potete verificare, ho ottenuto gli stessi valori, ma in notazione decimale anzichè esponenziale, che avevo ottenuto con python ctypes; per le verifiche di accuratezza potere rifarvi a questo post precedente. Gli input erano identici, quindi non occorre ripetere le verifiche di accuratezza.
Nei prossimi post aggiungeremo le funzioni di conversione da coordinate rettangoli a sferiche equatoriali ed eclittiche utilizzando due diversi frame di riferimento.
No comments:
Post a Comment