1use crate::macros as pa_m;
2use crate::planetdata as pa_pd;
3use crate::util as pa_u;
4
5pub fn approximate_position_of_planet(
26 lct_hour: f64,
27 lct_min: f64,
28 lct_sec: f64,
29 is_daylight_saving: bool,
30 zone_correction_hours: i32,
31 local_date_day: f64,
32 local_date_month: u32,
33 local_date_year: u32,
34 planet_name: String,
35) -> (f64, f64, f64, f64, f64, f64) {
36 let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
37
38 let (planet_info, _planet_info_status) = pa_pd::get_planet_info_vector(planet_name);
39
40 let planet_tp_from_table = planet_info.tp;
41 let planet_long_from_table = planet_info.long;
42 let planet_peri_from_table = planet_info.peri;
43 let planet_ecc_from_table = planet_info.ecc;
44 let planet_axis_from_table = planet_info.axis;
45 let planet_incl_from_table = planet_info.incl;
46 let planet_node_from_table = planet_info.node;
47
48 let gdate_day = pa_m::lct_gday(
49 lct_hour,
50 lct_min,
51 lct_sec,
52 daylight_saving,
53 zone_correction_hours,
54 local_date_day,
55 local_date_month,
56 local_date_year,
57 );
58 let gdate_month = pa_m::lct_gmonth(
59 lct_hour,
60 lct_min,
61 lct_sec,
62 daylight_saving,
63 zone_correction_hours,
64 local_date_day,
65 local_date_month,
66 local_date_year,
67 );
68 let gdate_year = pa_m::lct_gyear(
69 lct_hour,
70 lct_min,
71 lct_sec,
72 daylight_saving,
73 zone_correction_hours,
74 local_date_day,
75 local_date_month,
76 local_date_year,
77 );
78
79 let ut_hours = pa_m::lct_ut(
80 lct_hour,
81 lct_min,
82 lct_sec,
83 daylight_saving,
84 zone_correction_hours,
85 local_date_day,
86 local_date_month,
87 local_date_year,
88 );
89 let d_days = pa_m::cd_jd(gdate_day + (ut_hours / 24.0), gdate_month, gdate_year)
90 - pa_m::cd_jd(0.0, 1, 2010);
91 let np_deg1 = 360.0 * d_days / (365.242191 * planet_tp_from_table);
92 let np_deg2 = np_deg1 - 360.0 * (np_deg1 / 360.0).floor();
93 let mp_deg = np_deg2 + planet_long_from_table - planet_peri_from_table;
94 let lp_deg1 = np_deg2
95 + (360.0 * planet_ecc_from_table * mp_deg.to_radians().sin() / std::f64::consts::PI)
96 + planet_long_from_table;
97 let lp_deg2 = lp_deg1 - 360.0 * (lp_deg1 / 360.0).floor();
98 let planet_true_anomaly_deg = lp_deg2 - planet_peri_from_table;
99 let r_au = planet_axis_from_table * (1.0 - num::pow(planet_ecc_from_table, 2))
100 / (1.0 + planet_ecc_from_table * planet_true_anomaly_deg.to_radians().cos());
101
102 let (earth_info, _earth_info_status) = pa_pd::get_planet_info_vector("Earth".to_string());
103
104 let earth_tp_from_table = earth_info.tp;
105 let earth_long_from_table = earth_info.long;
106 let earth_peri_from_table = earth_info.peri;
107 let earth_ecc_from_table = earth_info.ecc;
108 let earth_axis_from_table = earth_info.axis;
109
110 let ne_deg1 = 360.0 * d_days / (365.242191 * earth_tp_from_table);
111 let ne_deg2 = ne_deg1 - 360.0 * (ne_deg1 / 360.0).floor();
112 let me_deg = ne_deg2 + earth_long_from_table - earth_peri_from_table;
113 let le_deg1 = ne_deg2
114 + earth_long_from_table
115 + 360.0 * earth_ecc_from_table * me_deg.to_radians().sin() / std::f64::consts::PI;
116 let le_deg2 = le_deg1 - 360.0 * (le_deg1 / 360.0).floor();
117 let earth_true_anomaly_deg = le_deg2 - earth_peri_from_table;
118 let r_au2 = earth_axis_from_table * (1.0 - num::pow(earth_ecc_from_table, 2))
119 / (1.0 + earth_ecc_from_table * earth_true_anomaly_deg.to_radians().cos());
120 let lp_node_rad = (lp_deg2 - planet_node_from_table).to_radians();
121 let psi_rad = ((lp_node_rad).sin() * planet_incl_from_table.to_radians().sin()).asin();
122 let y = lp_node_rad.sin() * planet_incl_from_table.to_radians().cos();
123 let x = lp_node_rad.cos();
124 let ld_deg = pa_m::degrees(y.atan2(x)) + planet_node_from_table;
125 let rd_au = r_au * psi_rad.cos();
126 let le_ld_rad = (le_deg2 - ld_deg).to_radians();
127 let atan2_type_1 = (rd_au * le_ld_rad.sin()).atan2(r_au2 - rd_au * le_ld_rad.cos());
128 let atan2_type_2 = (r_au2 * (-le_ld_rad).sin()).atan2(rd_au - r_au2 * le_ld_rad.cos());
129 let a_rad = if rd_au < 1.0 {
130 atan2_type_1
131 } else {
132 atan2_type_2
133 };
134 let lamda_deg1 = if rd_au < 1.0 {
135 180.0 + le_deg2 + pa_m::degrees(a_rad)
136 } else {
137 pa_m::degrees(a_rad) + ld_deg
138 };
139 let lamda_deg2 = lamda_deg1 - 360.0 * (lamda_deg1 / 360.0).floor();
140 let beta_deg = pa_m::degrees(
141 (rd_au * psi_rad.tan() * ((lamda_deg2 - ld_deg).to_radians()).sin()
142 / (r_au2 * (-le_ld_rad).sin()))
143 .atan(),
144 );
145 let ra_hours = pa_m::dd_dh(pa_m::ec_ra(
146 lamda_deg2,
147 0.0,
148 0.0,
149 beta_deg,
150 0.0,
151 0.0,
152 gdate_day,
153 gdate_month,
154 gdate_year,
155 ));
156 let dec_deg = pa_m::ec_dec(
157 lamda_deg2,
158 0.0,
159 0.0,
160 beta_deg,
161 0.0,
162 0.0,
163 gdate_day,
164 gdate_month,
165 gdate_year,
166 );
167
168 let planet_ra_hour = pa_m::dh_hour(ra_hours);
169 let planet_ra_min = pa_m::dh_min(ra_hours);
170 let planet_ra_sec = pa_m::dh_sec(ra_hours);
171 let planet_dec_deg = pa_m::dd_deg(dec_deg);
172 let planet_dec_min = pa_m::dd_min(dec_deg);
173 let planet_dec_sec = pa_m::dd_sec(dec_deg);
174
175 return (
176 planet_ra_hour as f64,
177 planet_ra_min as f64,
178 planet_ra_sec,
179 planet_dec_deg,
180 planet_dec_min,
181 planet_dec_sec,
182 );
183}
184
185pub fn precise_position_of_planet(
206 lct_hour: f64,
207 lct_min: f64,
208 lct_sec: f64,
209 is_daylight_saving: bool,
210 zone_correction_hours: i32,
211 local_date_day: f64,
212 local_date_month: u32,
213 local_date_year: u32,
214 planet_name: String,
215) -> (f64, f64, f64, f64, f64, f64) {
216 let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
217
218 let _gdate_day = pa_m::lct_gday(
219 lct_hour,
220 lct_min,
221 lct_sec,
222 daylight_saving,
223 zone_correction_hours,
224 local_date_day,
225 local_date_month,
226 local_date_year,
227 );
228 let _gdate_month = pa_m::lct_gmonth(
229 lct_hour,
230 lct_min,
231 lct_sec,
232 daylight_saving,
233 zone_correction_hours,
234 local_date_day,
235 local_date_month,
236 local_date_year,
237 );
238 let _gdate_year = pa_m::lct_gyear(
239 lct_hour,
240 lct_min,
241 lct_sec,
242 daylight_saving,
243 zone_correction_hours,
244 local_date_day,
245 local_date_month,
246 local_date_year,
247 );
248
249 let (
250 planet_ecl_long_deg,
251 planet_ecl_lat_deg,
252 _planet_distance_au,
253 _planet_h_long1,
254 _planet_h_long2,
255 _planet_h_lat,
256 _planet_r_vect,
257 ) = pa_m::planet_coordinates(
258 lct_hour,
259 lct_min,
260 lct_sec,
261 daylight_saving,
262 zone_correction_hours,
263 local_date_day,
264 local_date_month,
265 local_date_year,
266 planet_name,
267 );
268
269 let planet_ra_hours = pa_m::dd_dh(pa_m::ec_ra(
270 planet_ecl_long_deg,
271 0.0,
272 0.0,
273 planet_ecl_lat_deg,
274 0.0,
275 0.0,
276 local_date_day,
277 local_date_month,
278 local_date_year,
279 ));
280 let planet_dec_deg1 = pa_m::ec_dec(
281 planet_ecl_long_deg,
282 0.0,
283 0.0,
284 planet_ecl_lat_deg,
285 0.0,
286 0.0,
287 local_date_day,
288 local_date_month,
289 local_date_year,
290 );
291
292 let planet_ra_hour = pa_m::dh_hour(planet_ra_hours);
293 let planet_ra_min = pa_m::dh_min(planet_ra_hours);
294 let planet_ra_sec = pa_m::dh_sec(planet_ra_hours);
295 let planet_dec_deg = pa_m::dd_deg(planet_dec_deg1);
296 let planet_dec_min = pa_m::dd_min(planet_dec_deg1);
297 let planet_dec_sec = pa_m::dd_sec(planet_dec_deg1);
298
299 return (
300 planet_ra_hour as f64,
301 planet_ra_min as f64,
302 planet_ra_sec,
303 planet_dec_deg,
304 planet_dec_min,
305 planet_dec_sec,
306 );
307}
308
309pub fn visual_aspects_of_a_planet(
332 lct_hour: f64,
333 lct_min: f64,
334 lct_sec: f64,
335 is_daylight_saving: bool,
336 zone_correction_hours: i32,
337 local_date_day: f64,
338 local_date_month: u32,
339 local_date_year: u32,
340 planet_name: String,
341) -> (f64, f64, f64, f64, f64, f64, f64, f64) {
342 let daylight_saving = if is_daylight_saving == true { 1 } else { 0 };
343
344 let greenwich_date_day = pa_m::lct_gday(
345 lct_hour,
346 lct_min,
347 lct_sec,
348 daylight_saving,
349 zone_correction_hours,
350 local_date_day,
351 local_date_month,
352 local_date_year,
353 );
354 let greenwich_date_month = pa_m::lct_gmonth(
355 lct_hour,
356 lct_min,
357 lct_sec,
358 daylight_saving,
359 zone_correction_hours,
360 local_date_day,
361 local_date_month,
362 local_date_year,
363 );
364 let greenwich_date_year = pa_m::lct_gyear(
365 lct_hour,
366 lct_min,
367 lct_sec,
368 daylight_saving,
369 zone_correction_hours,
370 local_date_day,
371 local_date_month,
372 local_date_year,
373 );
374
375 let (
376 planet_ecl_long_deg,
377 planet_ecl_lat_deg,
378 planet_dist_au,
379 planet_h_long1,
380 _temp3,
381 _temp4,
382 planet_r_vect,
383 ) = pa_m::planet_coordinates(
384 lct_hour,
385 lct_min,
386 lct_sec,
387 daylight_saving,
388 zone_correction_hours,
389 local_date_day,
390 local_date_month,
391 local_date_year,
392 planet_name.to_string(),
393 );
394
395 let planet_ra_rad = (pa_m::ec_ra(
396 planet_ecl_long_deg,
397 0.0,
398 0.0,
399 planet_ecl_lat_deg,
400 0.0,
401 0.0,
402 local_date_day,
403 local_date_month,
404 local_date_year,
405 ))
406 .to_radians();
407 let planet_dec_rad = (pa_m::ec_dec(
408 planet_ecl_long_deg,
409 0.0,
410 0.0,
411 planet_ecl_lat_deg,
412 0.0,
413 0.0,
414 local_date_day,
415 local_date_month,
416 local_date_year,
417 ))
418 .to_radians();
419
420 let light_travel_time_hours = planet_dist_au * 0.1386;
421 let (planet_info, _planet_info_status) = pa_pd::get_planet_info_vector(planet_name.to_string());
422 let angular_diameter_arcsec = planet_info.theta0 / planet_dist_au;
423 let phase1 = 0.5 * (1.0 + ((planet_ecl_long_deg - planet_h_long1).to_radians()).cos());
424
425 let sun_ecl_long_deg = pa_m::sun_long(
426 lct_hour,
427 lct_min,
428 lct_sec,
429 daylight_saving,
430 zone_correction_hours,
431 local_date_day,
432 local_date_month,
433 local_date_year,
434 );
435 let sun_ra_rad = (pa_m::ec_ra(
436 sun_ecl_long_deg,
437 0.0,
438 0.0,
439 0.0,
440 0.0,
441 0.0,
442 greenwich_date_day,
443 greenwich_date_month,
444 greenwich_date_year,
445 ))
446 .to_radians();
447 let sun_dec_rad = (pa_m::ec_dec(
448 sun_ecl_long_deg,
449 0.0,
450 0.0,
451 0.0,
452 0.0,
453 0.0,
454 greenwich_date_day,
455 greenwich_date_month,
456 greenwich_date_year,
457 ))
458 .to_radians();
459
460 let y = (sun_dec_rad).cos() * (sun_ra_rad - planet_ra_rad).sin();
461 let x = (planet_dec_rad).cos() * (sun_dec_rad).sin()
462 - (planet_dec_rad).sin() * (sun_dec_rad).cos() * (sun_ra_rad - planet_ra_rad).cos();
463
464 let chi_deg = pa_m::degrees(y.atan2(x));
465 let radius_vector_au = planet_r_vect;
466 let approximate_magnitude1 =
467 5.0 * (radius_vector_au * planet_dist_au / (phase1).sqrt()).log10() + planet_info.v0;
468
469 let distance_au = pa_u::round_f64(planet_dist_au, 5);
470 let ang_dia_arcsec = pa_u::round_f64(angular_diameter_arcsec, 1);
471 let phase = pa_u::round_f64(phase1, 2);
472 let light_time_hour = pa_m::dh_hour(light_travel_time_hours);
473 let light_time_minutes = pa_m::dh_min(light_travel_time_hours);
474 let light_time_seconds = pa_m::dh_sec(light_travel_time_hours);
475 let pos_angle_bright_limb_deg = pa_u::round_f64(chi_deg, 1);
476 let approximate_magnitude = pa_u::round_f64(approximate_magnitude1, 1);
477
478 return (
479 distance_au,
480 ang_dia_arcsec,
481 phase,
482 light_time_hour as f64,
483 light_time_minutes as f64,
484 light_time_seconds,
485 pos_angle_bright_limb_deg,
486 approximate_magnitude,
487 );
488}