swisseph 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1919 @@
1
+ /*
2
+ Swisseph :: Swiss Ephemeris for Ruby - A C extension for the Swiss Ephemeris library (http://www.astro.com/swisseph/)
3
+ Copyright (C) 2012 Andrew Kirk (andrew.kirk@windhorsemedia.com)
4
+ Additional work (C) 2024-25 David Lowenfels (dfl@alum.mit.edu)
5
+
6
+ This file is part of Swisseph.
7
+
8
+ Swisseph is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ Swisseph is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with Swisseph. If not, see <http://www.gnu.org/licenses/>.
20
+ */
21
+
22
+ // https://docs.ruby-lang.org/en/3.0/extension_rdoc.html
23
+ #include <ruby.h>
24
+ #include "swephexp.h"
25
+
26
+ // Module Name
27
+ VALUE rb_mSwisseph = Qnil;
28
+
29
+ /*
30
+ * Set directory path of ephemeris files
31
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735481
32
+ * int swe_set_ephe_path(char *path);
33
+ */
34
+ static VALUE t_swe_set_ephe_path(VALUE self, VALUE path)
35
+ {
36
+ swe_set_ephe_path(StringValuePtr(path));
37
+ return Qnil;
38
+ }
39
+
40
+ /*
41
+ * Set directory path of ephemeris files to work with jpl
42
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735481
43
+ * int swe_set_jpl_file(char *fname);
44
+ */
45
+ static VALUE t_swe_set_jpl_file(VALUE self, VALUE path)
46
+ {
47
+ swe_set_jpl_file(StringValuePtr(path));
48
+ return Qnil;
49
+ }
50
+
51
+ /*
52
+ * Close Swiss Ephemeris and release resources
53
+ * void swe_close(void);
54
+ */
55
+ static VALUE t_swe_close(VALUE self)
56
+ {
57
+ swe_close();
58
+ return Qnil;
59
+ }
60
+
61
+ /*
62
+ * Get Swiss Ephemeris version string
63
+ * char *swe_version(char *);
64
+ */
65
+ static VALUE t_swe_version(VALUE self)
66
+ {
67
+ char version[AS_MAXCH];
68
+ swe_version(version);
69
+ return rb_str_new_cstr(version);
70
+ }
71
+
72
+ /*
73
+ * Get planet name by number
74
+ * char *swe_get_planet_name(int ipl, char *spname);
75
+ */
76
+ static VALUE t_swe_get_planet_name(VALUE self, VALUE ipl)
77
+ {
78
+ char name[AS_MAXCH];
79
+ swe_get_planet_name(NUM2INT(ipl), name);
80
+ return rb_str_new_cstr(name);
81
+ }
82
+
83
+ /*
84
+ * Get ayanamsa name by mode number
85
+ * const char *swe_get_ayanamsa_name(int32 isidmode);
86
+ */
87
+ static VALUE t_swe_get_ayanamsa_name(VALUE self, VALUE isidmode)
88
+ {
89
+ const char *name = swe_get_ayanamsa_name(NUM2INT(isidmode));
90
+ if (name == NULL)
91
+ return Qnil;
92
+ return rb_str_new_cstr(name);
93
+ }
94
+
95
+ /*
96
+ * Get the Julian day number from year, month, day, hour
97
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735468
98
+ double swe_julday(
99
+ int year,
100
+ int month,
101
+ int day,
102
+ double hour,
103
+ int gregflag // Gregorian calendar: 1, Julian calendar: 0
104
+ );
105
+ */
106
+ static VALUE t_swe_julday(int argc, VALUE *argv, VALUE self)
107
+ {
108
+ VALUE greg_flag;
109
+
110
+ if (argc > 5 || argc < 4)
111
+ { // there should only be 4 or 5 arguments
112
+ rb_raise(rb_eArgError, "wrong number of arguments");
113
+ }
114
+ greg_flag = (argc == 5) ? NUM2INT(argv[4]) : SE_GREG_CAL;
115
+
116
+ double julday = swe_julday(NUM2INT(argv[0]), NUM2INT(argv[1]), NUM2INT(argv[2]), NUM2DBL(argv[3]), greg_flag);
117
+ return rb_float_new(julday);
118
+ }
119
+ /*
120
+ * Get the year, month, day, hour from Julian day
121
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735468
122
+ void swe_revjul(
123
+ double tjd, // Julian day number
124
+ int gregflag, // Gregorian calendar: 1, Julian calendar: 0
125
+ int *year, // target addresses for year, etc.
126
+ int *month,
127
+ int *day,
128
+ double *hour
129
+ );
130
+ */
131
+ static VALUE t_swe_revjul(int argc, VALUE *argv, VALUE self)
132
+ {
133
+ if (argc > 2 || argc < 1)
134
+ { // there should only be 2 or 3 arguments
135
+ rb_raise(rb_eArgError, "wrong number of arguments");
136
+ }
137
+ VALUE greg_flag = (argc == 2) ? NUM2INT(argv[1]) : SE_GREG_CAL;
138
+
139
+ int year, month, day;
140
+ double hour;
141
+
142
+ swe_revjul(NUM2DBL(argv[0]), greg_flag, &year, &month, &day, &hour);
143
+
144
+ VALUE output = rb_ary_new();
145
+ rb_ary_push(output, rb_uint_new(year));
146
+ rb_ary_push(output, rb_uint_new(month));
147
+ rb_ary_push(output, rb_uint_new(day));
148
+ rb_ary_push(output, rb_float_new(hour));
149
+ return output;
150
+ }
151
+
152
+ /*
153
+ * Convert UTC to Julian day
154
+ * Returns array of [jd_et, jd_ut] or raises error
155
+ * int32 swe_utc_to_jd(int32 iyear, int32 imonth, int32 iday,
156
+ * int32 ihour, int32 imin, double dsec,
157
+ * int32 gregflag, double *dret, char *serr);
158
+ */
159
+ static VALUE t_swe_utc_to_jd(int argc, VALUE *argv, VALUE self)
160
+ {
161
+ if (argc < 6 || argc > 7)
162
+ rb_raise(rb_eArgError, "wrong number of arguments (6 or 7)");
163
+
164
+ int32 gregflag = (argc == 7) ? NUM2INT(argv[6]) : SE_GREG_CAL;
165
+ double dret[2];
166
+ char serr[AS_MAXCH];
167
+
168
+ int32 result = swe_utc_to_jd(
169
+ NUM2INT(argv[0]), NUM2INT(argv[1]), NUM2INT(argv[2]),
170
+ NUM2INT(argv[3]), NUM2INT(argv[4]), NUM2DBL(argv[5]),
171
+ gregflag, dret, serr);
172
+
173
+ if (result < 0)
174
+ rb_raise(rb_eRuntimeError, serr);
175
+
176
+ VALUE output = rb_ary_new();
177
+ rb_ary_push(output, rb_float_new(dret[0])); // JD ET
178
+ rb_ary_push(output, rb_float_new(dret[1])); // JD UT
179
+ return output;
180
+ }
181
+
182
+ /*
183
+ * Convert Julian day UT to UTC
184
+ * void swe_jdut1_to_utc(double tjd_ut, int32 gregflag,
185
+ * int32 *iyear, int32 *imonth, int32 *iday,
186
+ * int32 *ihour, int32 *imin, double *dsec);
187
+ */
188
+ static VALUE t_swe_jdut1_to_utc(int argc, VALUE *argv, VALUE self)
189
+ {
190
+ if (argc < 1 || argc > 2)
191
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
192
+
193
+ int32 gregflag = (argc == 2) ? NUM2INT(argv[1]) : SE_GREG_CAL;
194
+ int32 year, month, day, hour, min;
195
+ double sec;
196
+
197
+ swe_jdut1_to_utc(NUM2DBL(argv[0]), gregflag, &year, &month, &day, &hour, &min, &sec);
198
+
199
+ VALUE output = rb_ary_new();
200
+ rb_ary_push(output, INT2NUM(year));
201
+ rb_ary_push(output, INT2NUM(month));
202
+ rb_ary_push(output, INT2NUM(day));
203
+ rb_ary_push(output, INT2NUM(hour));
204
+ rb_ary_push(output, INT2NUM(min));
205
+ rb_ary_push(output, rb_float_new(sec));
206
+ return output;
207
+ }
208
+
209
+ /*
210
+ * Get day of week from Julian day
211
+ * Returns 0=Monday, 1=Tuesday, ..., 6=Sunday
212
+ * int swe_day_of_week(double jd);
213
+ */
214
+ static VALUE t_swe_day_of_week(VALUE self, VALUE jd)
215
+ {
216
+ return INT2NUM(swe_day_of_week(NUM2DBL(jd)));
217
+ }
218
+
219
+ /*
220
+ * Set the geographic location for topocentric planet computation
221
+ * The longitude and latitude must be in degrees, the altitude in meters.
222
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735476
223
+ void swe_set_topo (
224
+ double geolon, // geographic longitude: eastern longitude is positive, western longitude is negative
225
+ double geolat, // geographic latitude: northern latitude is positive, southern latitude is negative
226
+ double altitude // altitude above sea
227
+ );
228
+ */
229
+ static VALUE t_swe_set_topo(VALUE self, VALUE lon, VALUE lat, VALUE alt)
230
+ {
231
+ swe_set_topo(NUM2DBL(lon), NUM2DBL(lat), NUM2DBL(alt));
232
+ return Qnil;
233
+ }
234
+
235
+ /*
236
+ * Calculation of planets, moon, asteroids, lunar nodes, apogees, fictitious bodies
237
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735419
238
+ long swe_calc_ut(
239
+ double tjd_ut, // Julian day number, Universal Time
240
+ int ipl, // planet number
241
+ long iflag, // flag bits
242
+ double *xx, // target address for 6 position values: longitude, latitude, distance, long.speed, lat.speed, dist.speed
243
+ char *serr // 256 bytes for error string
244
+ );
245
+ */
246
+ static VALUE t_swe_calc_ut(VALUE self, VALUE julian_ut, VALUE body, VALUE iflag)
247
+ {
248
+ double results[6];
249
+ char serr[AS_MAXCH];
250
+
251
+ if (swe_calc_ut(NUM2DBL(julian_ut), NUM2INT(body), NUM2LONG(iflag), results, serr) < 0)
252
+ rb_raise(rb_eRuntimeError, serr);
253
+
254
+ VALUE output = rb_ary_new();
255
+ for (int i = 0; i < 6; i++)
256
+ rb_ary_push(output, rb_float_new(results[i]));
257
+
258
+ return output;
259
+ }
260
+
261
+ /*
262
+ * Calculation of planets, moon, asteroids, etc. (ET/TT version)
263
+ * int32 swe_calc(double tjd_et, int ipl, int32 iflag, double *xx, char *serr);
264
+ */
265
+ static VALUE t_swe_calc(VALUE self, VALUE julian_et, VALUE body, VALUE iflag)
266
+ {
267
+ double results[6];
268
+ char serr[AS_MAXCH];
269
+
270
+ if (swe_calc(NUM2DBL(julian_et), NUM2INT(body), NUM2LONG(iflag), results, serr) < 0)
271
+ rb_raise(rb_eRuntimeError, serr);
272
+
273
+ VALUE output = rb_ary_new();
274
+ for (int i = 0; i < 6; i++)
275
+ rb_ary_push(output, rb_float_new(results[i]));
276
+
277
+ return output;
278
+ }
279
+
280
+ static VALUE t_swe_sidtime(VALUE self, VALUE julian_ut)
281
+ {
282
+ double sidtime = swe_sidtime(NUM2DBL(julian_ut));
283
+ return rb_float_new(sidtime);
284
+ }
285
+
286
+ /*
287
+ * Sidereal time with explicit obliquity and nutation
288
+ * double swe_sidtime0(double tjd_ut, double eps, double nut);
289
+ */
290
+ static VALUE t_swe_sidtime0(VALUE self, VALUE julian_ut, VALUE eps, VALUE nut)
291
+ {
292
+ double sidtime = swe_sidtime0(NUM2DBL(julian_ut), NUM2DBL(eps), NUM2DBL(nut));
293
+ return rb_float_new(sidtime);
294
+ }
295
+
296
+ /*
297
+ * Normalize degrees to range 0-360
298
+ * double swe_degnorm(double x);
299
+ */
300
+ static VALUE t_swe_degnorm(VALUE self, VALUE deg)
301
+ {
302
+ return rb_float_new(swe_degnorm(NUM2DBL(deg)));
303
+ }
304
+
305
+ /*
306
+ * Normalize radians to range 0-2*PI
307
+ * double swe_radnorm(double x);
308
+ */
309
+ static VALUE t_swe_radnorm(VALUE self, VALUE rad)
310
+ {
311
+ return rb_float_new(swe_radnorm(NUM2DBL(rad)));
312
+ }
313
+
314
+ /*
315
+ * Split degrees into degrees, minutes, seconds
316
+ * void swe_split_deg(double ddeg, int32 roundflag, int32 *ideg, int32 *imin, int32 *isec, double *dsecfr, int32 *isgn);
317
+ * roundflag: SE_SPLIT_DEG_ROUND_SEC, SE_SPLIT_DEG_ROUND_MIN, SE_SPLIT_DEG_ROUND_DEG, SE_SPLIT_DEG_ZODIACAL, SE_SPLIT_DEG_KEEP_SIGN, SE_SPLIT_DEG_KEEP_DEG
318
+ * Returns [deg, min, sec, secfr, sign]
319
+ */
320
+ static VALUE t_swe_split_deg(VALUE self, VALUE ddeg, VALUE roundflag)
321
+ {
322
+ int32 ideg, imin, isec, isgn;
323
+ double dsecfr;
324
+
325
+ swe_split_deg(NUM2DBL(ddeg), NUM2INT(roundflag), &ideg, &imin, &isec, &dsecfr, &isgn);
326
+
327
+ VALUE output = rb_ary_new();
328
+ rb_ary_push(output, INT2NUM(ideg));
329
+ rb_ary_push(output, INT2NUM(imin));
330
+ rb_ary_push(output, INT2NUM(isec));
331
+ rb_ary_push(output, rb_float_new(dsecfr));
332
+ rb_ary_push(output, INT2NUM(isgn));
333
+ return output;
334
+ }
335
+
336
+ /*
337
+ * This function can be used to specify the mode for sidereal computations
338
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735478
339
+ void swe_set_sid_mode (
340
+ int32 sid_mode, // Mode
341
+ double t0, // Reference date
342
+ double ayan_t0 // Initial value of the ayanamsha
343
+ );
344
+ */
345
+ static VALUE t_swe_set_sid_mode(VALUE self, VALUE mode, VALUE t0, VALUE ayan_t0)
346
+ {
347
+ swe_set_sid_mode(NUM2INT(mode), NUM2DBL(t0), NUM2DBL(ayan_t0));
348
+ return Qnil;
349
+ }
350
+
351
+ /*
352
+ * This function computes the ayanamsha, the distance of the tropical vernal point from the sidereal zero point of the zodiac.
353
+ * The ayanamsha is used to compute sidereal planetary positions from tropical ones:
354
+ * pos_sid = pos_trop – ayanamsha
355
+ * Before calling swe_get_ayanamsha(), you have to set the sidereal mode with swe_set_sid_mode, unless you want the default sidereal mode, which is the Fagan/Bradley ayanamsha.
356
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735479
357
+ * double swe_get_ayanamsa_ut(double tjd_ut);
358
+ */
359
+ static VALUE t_swe_get_ayanamsa_ut(VALUE self, VALUE julian_ut)
360
+ {
361
+ double ayanamsa = swe_get_ayanamsa_ut(NUM2DBL(julian_ut));
362
+ return rb_float_new(ayanamsa);
363
+ }
364
+
365
+ /*
366
+ * Ayanamsa (ET/TT version)
367
+ * double swe_get_ayanamsa(double tjd_et);
368
+ */
369
+ static VALUE t_swe_get_ayanamsa(VALUE self, VALUE julian_et)
370
+ {
371
+ double ayanamsa = swe_get_ayanamsa(NUM2DBL(julian_et));
372
+ return rb_float_new(ayanamsa);
373
+ }
374
+
375
+ // * This function computes the ayanamsha using a Delta T consistent with the ephe_flag specified.
376
+ // * https://www.astro.com/swisseph/swephprg.htm#_Toc112949018
377
+ // * input variables:
378
+ // * tjd_ut = Julian day number in UT
379
+ // * (tjd_et = Julian day number in ET/TT)
380
+ // * iflag = ephemeris flag (one of SEFLG_SWIEPH, SEFLG_JPLEPH, SEFLG_MOSEPH)
381
+ // * plus some other optional SEFLG_...
382
+ // * output values
383
+ // * daya = ayanamsha value (pointer to double)
384
+ // * serr = error message or warning (pointer to string)
385
+ // * The function returns either the ephemeris flag used or ERR (-1)
386
+
387
+ static VALUE t_swe_get_ayanamsa_ex_ut(VALUE self, VALUE julian_ut, VALUE flag)
388
+ {
389
+ double ayanamsha;
390
+ char serr[AS_MAXCH];
391
+
392
+ if (swe_get_ayanamsa_ex_ut(NUM2DBL(julian_ut), NUM2INT(flag), &ayanamsha, serr) < 0)
393
+ rb_raise(rb_eRuntimeError, serr);
394
+
395
+ return rb_float_new(ayanamsha);
396
+ }
397
+
398
+ /*
399
+ * Ayanamsa with explicit ephemeris (ET/TT version)
400
+ * int32 swe_get_ayanamsa_ex(double tjd_et, int32 iflag, double *daya, char *serr);
401
+ */
402
+ static VALUE t_swe_get_ayanamsa_ex(VALUE self, VALUE julian_et, VALUE flag)
403
+ {
404
+ double ayanamsha;
405
+ char serr[AS_MAXCH];
406
+
407
+ if (swe_get_ayanamsa_ex(NUM2DBL(julian_et), NUM2INT(flag), &ayanamsha, serr) < 0)
408
+ rb_raise(rb_eRuntimeError, serr);
409
+
410
+ return rb_float_new(ayanamsha);
411
+ }
412
+
413
+ /*
414
+ * This function computes house cusps, ascendant, midheaven, etc
415
+ * http://www.astro.com/swisseph/swephprg.htm#_Toc283735486
416
+ int swe_houses(
417
+ double tjd_ut, // Julian day number, UT
418
+ double geolat, // geographic latitude, in degrees
419
+ double geolon, // geographic longitude, in degrees (eastern longitude is positive, western longitude is negative, northern latitude is positive, southern latitude is negative
420
+ int hsys, // house method, ascii code of one of the letters PKORCAEVXHTBG
421
+ double *cusps, // array for 13 doubles
422
+ double *ascmc // array for 10 doubles
423
+ );
424
+ * House method codes...
425
+ * ‘P’ = Placidus
426
+ * ‘K’ = Koch
427
+ * ‘O’ = Porphyrius
428
+ * ‘R’ = Regiomontanus
429
+ * ‘C’ = Campanus
430
+ * ‘A’ or ‘E’ = Equal (cusp 1 is Ascendant)
431
+ * ‘V’ = Vehlow equal (Asc. in middle of house 1)
432
+ * ‘W’ = Whole sign
433
+ * ‘X’ = axial rotation system
434
+ * ‘H’ = azimuthal or horizontal system
435
+ * ‘T’ = Polich/Page (“topocentric” system)
436
+ * ‘B’ = Alcabitus
437
+ * ‘M’ = Morinus
438
+ * ‘U’ = Krusinski-Pisa
439
+ * ‘G’ = Gauquelin sectors
440
+ */
441
+
442
+ static VALUE t_swe_houses(VALUE self, VALUE julian_day, VALUE latitude, VALUE longitude, VALUE house_system)
443
+ {
444
+ double cusps[37]; // 37 for Gauquelin sectors, 13 for others
445
+ double ascmc[10];
446
+ char serr[AS_MAXCH];
447
+ char hsys = NUM2CHR(house_system);
448
+ int num_cusps = (hsys == 'G') ? 37 : 13;
449
+
450
+ if (swe_houses(NUM2DBL(julian_day), NUM2DBL(latitude), NUM2DBL(longitude), hsys, cusps, ascmc) < 0)
451
+ rb_raise(rb_eRuntimeError, serr);
452
+
453
+ VALUE _cusps = rb_ary_new();
454
+ for (int i = 0; i < num_cusps; i++)
455
+ rb_ary_push(_cusps, rb_float_new(cusps[i]));
456
+
457
+ VALUE _ascmc = rb_ary_new();
458
+ for (int i = 0; i < 10; i++)
459
+ rb_ary_push(_ascmc, rb_float_new(ascmc[i]));
460
+
461
+ VALUE output = rb_ary_new();
462
+ rb_ary_push(output, _cusps);
463
+ rb_ary_push(output, _ascmc);
464
+ return output;
465
+ }
466
+
467
+ /*
468
+ * Houses with flags (sidereal, etc.)
469
+ * int swe_houses_ex(double tjd_ut, int32 iflag, double geolat, double geolon, int hsys, double *cusps, double *ascmc);
470
+ */
471
+ static VALUE t_swe_houses_ex(VALUE self, VALUE julian_day, VALUE iflag, VALUE latitude, VALUE longitude, VALUE house_system)
472
+ {
473
+ double cusps[37]; // 37 for Gauquelin sectors, 13 for others
474
+ double ascmc[10];
475
+ char serr[AS_MAXCH];
476
+ char hsys = NUM2CHR(house_system);
477
+ int num_cusps = (hsys == 'G') ? 37 : 13;
478
+
479
+ if (swe_houses_ex(NUM2DBL(julian_day), NUM2INT(iflag), NUM2DBL(latitude), NUM2DBL(longitude), hsys, cusps, ascmc) < 0)
480
+ rb_raise(rb_eRuntimeError, serr);
481
+
482
+ VALUE _cusps = rb_ary_new();
483
+ for (int i = 0; i < num_cusps; i++)
484
+ rb_ary_push(_cusps, rb_float_new(cusps[i]));
485
+
486
+ VALUE _ascmc = rb_ary_new();
487
+ for (int i = 0; i < 10; i++)
488
+ rb_ary_push(_ascmc, rb_float_new(ascmc[i]));
489
+
490
+ VALUE output = rb_ary_new();
491
+ rb_ary_push(output, _cusps);
492
+ rb_ary_push(output, _ascmc);
493
+ return output;
494
+ }
495
+
496
+ /*
497
+ * Houses from ARMC (sidereal time)
498
+ * int swe_houses_armc(double armc, double geolat, double eps, int hsys, double *cusps, double *ascmc);
499
+ */
500
+ static VALUE t_swe_houses_armc(VALUE self, VALUE armc, VALUE latitude, VALUE eps, VALUE house_system)
501
+ {
502
+ double cusps[37]; // 37 for Gauquelin sectors, 13 for others
503
+ double ascmc[10];
504
+ char serr[AS_MAXCH];
505
+ char hsys = NUM2CHR(house_system);
506
+ int num_cusps = (hsys == 'G') ? 37 : 13;
507
+
508
+ if (swe_houses_armc(NUM2DBL(armc), NUM2DBL(latitude), NUM2DBL(eps), hsys, cusps, ascmc) < 0)
509
+ rb_raise(rb_eRuntimeError, serr);
510
+
511
+ VALUE _cusps = rb_ary_new();
512
+ for (int i = 0; i < num_cusps; i++)
513
+ rb_ary_push(_cusps, rb_float_new(cusps[i]));
514
+
515
+ VALUE _ascmc = rb_ary_new();
516
+ for (int i = 0; i < 10; i++)
517
+ rb_ary_push(_ascmc, rb_float_new(ascmc[i]));
518
+
519
+ VALUE output = rb_ary_new();
520
+ rb_ary_push(output, _cusps);
521
+ rb_ary_push(output, _ascmc);
522
+ return output;
523
+ }
524
+
525
+ // This function is better than swe_houses and returns speeds as well
526
+ // https://www.astro.com/swisseph/swephprg.htm#_Toc112949026
527
+ // int swe_houses_ex2(
528
+ // double tjd_ut, /* Julian day number, UT */
529
+ // int32 iflag, /* 0 or SEFLG_SIDEREAL or SEFLG_RADIANS or SEFLG_NONUT */
530
+ // double geolat, /* geographic latitude, in degrees */
531
+ // double geolon, /* geographic longitude, in degrees
532
+ // * eastern longitude is positive,
533
+ // * western longitude is negative,
534
+ // * northern latitude is positive,
535
+ // * southern latitude is negative */
536
+ // int hsys, /* house method, one-letter case sensitive code (list, see further below) */
537
+ // double *cusps, /* array for 13 (or 37 for hsys G) doubles, explained further below */
538
+ // double *ascmc, /* array for 10 doubles, explained further below */
539
+ // double *cusp_speed, /* like cusps */
540
+ // double *ascmc_speed, /* like ascmc */
541
+ // char *serr);
542
+
543
+ static VALUE t_swe_houses_ex2(VALUE self, VALUE julian_day, VALUE flag, VALUE latitude, VALUE longitude, VALUE house_system)
544
+ {
545
+ double cusps[37]; // 37 for Gauquelin sectors, 13 for others
546
+ double ascmc[10];
547
+ double cusps_speed[37]; // 37 for Gauquelin sectors, 13 for others
548
+ double ascmc_speed[10];
549
+ char serr[AS_MAXCH];
550
+ char hsys = NUM2CHR(house_system);
551
+ int num_cusps = (hsys == 'G') ? 37 : 13;
552
+
553
+ if (swe_houses_ex2(NUM2DBL(julian_day), NUM2INT(flag), NUM2DBL(latitude), NUM2DBL(longitude), hsys, cusps, ascmc, cusps_speed, ascmc_speed, serr) < 0)
554
+ rb_raise(rb_eRuntimeError, serr);
555
+
556
+ VALUE _cusps = rb_ary_new();
557
+ for (int i = 0; i < num_cusps; i++)
558
+ rb_ary_push(_cusps, rb_float_new(cusps[i]));
559
+
560
+ VALUE _ascmc = rb_ary_new();
561
+ for (int i = 0; i < 10; i++)
562
+ rb_ary_push(_ascmc, rb_float_new(ascmc[i]));
563
+
564
+ VALUE _cusps_speed = rb_ary_new();
565
+ for (int i = 0; i < num_cusps; i++)
566
+ rb_ary_push(_cusps_speed, rb_float_new(cusps_speed[i]));
567
+
568
+ VALUE _ascmc_speed = rb_ary_new();
569
+ for (int i = 0; i < 10; i++)
570
+ rb_ary_push(_ascmc_speed, rb_float_new(ascmc_speed[i]));
571
+
572
+ VALUE output = rb_ary_new();
573
+ rb_ary_push(output, _cusps);
574
+ rb_ary_push(output, _ascmc);
575
+ rb_ary_push(output, _cusps_speed);
576
+ rb_ary_push(output, _ascmc_speed);
577
+ return output;
578
+ }
579
+
580
+ // char *swe_house_name(
581
+ // int hsys); /* house method, ascii code of one of the letters PKORCAEVXHTBG */
582
+ static VALUE t_swe_house_name(VALUE self, VALUE hsys)
583
+ {
584
+ return rb_str_new_cstr(swe_house_name(NUM2CHR(hsys)));
585
+ }
586
+
587
+ // int32 swe_rise_trans(
588
+ // double tjd_ut, /* search after this time (UT) */
589
+ // int32 ipl, /* planet number, if planet or moon */
590
+ // char *starname, /* star name, if star; must be NULL or empty, if ipl is used */
591
+ // int32 epheflag, /* ephemeris flag */
592
+ // int32 rsmi, /* integer specifying that rise, set, or one of the two meridian transits is wanted. see definition below */
593
+ // double *geopos, /* array of three doubles containing
594
+ // * geograph. long., lat., height of observer */
595
+ // double atpress /* atmospheric pressure in mbar/hPa */
596
+ // double attemp, /* atmospheric temperature in deg. C */
597
+ // double *tret, /* return address (double) for rise time etc. */
598
+ // char *serr); /* return address for error message */
599
+
600
+ static VALUE t_swe_rise_trans(VALUE self, VALUE julian_day, VALUE body, VALUE flag, VALUE rmsi, VALUE lon, VALUE lat, VALUE height, VALUE pressure, VALUE temp)
601
+ {
602
+ double geopos[3];
603
+ geopos[0] = NUM2DBL(lon);
604
+ geopos[1] = NUM2DBL(lat);
605
+ geopos[2] = NUM2DBL(height);
606
+ int ipl;
607
+ char *starname;
608
+ if (TYPE(body) == T_STRING)
609
+ {
610
+ starname = StringValuePtr(body);
611
+ ipl = 0;
612
+ }
613
+ else
614
+ {
615
+ ipl = NUM2INT(body);
616
+ starname = NULL;
617
+ }
618
+ char serr[AS_MAXCH];
619
+ double retval;
620
+
621
+ if (swe_rise_trans(NUM2DBL(julian_day), ipl, starname, NUM2INT(flag), NUM2INT(rmsi), geopos, NUM2DBL(pressure), NUM2DBL(temp), &retval, serr) < 0)
622
+ rb_raise(rb_eRuntimeError, serr);
623
+ return rb_float_new(retval);
624
+ }
625
+
626
+ // int32 swe_rise_trans_true_hor(
627
+ // double tjd_ut, /* search after this time (UT) */
628
+ // int32 ipl, /* planet number, if planet or moon */
629
+ // char *starname, /* star name, if star; must be NULL or empty, if ipl is used */
630
+ // int32 epheflag, /* ephemeris flag */
631
+ // int32 rsmi, /* integer specifying that rise, set, or one of the two meridian transits is wanted. see definition below */
632
+ // double *geopos, /* array of three doubles containing
633
+ // * geograph. long., lat., height of observer */
634
+ // double atpress, /* atmospheric pressure in mbar/hPa */
635
+ // double attemp, /* atmospheric temperature in deg. C */
636
+ // double horhgt, /* height of local horizon in deg at the point where the body rises or sets */
637
+ // double *tret, /* return address (double) for rise time etc. */
638
+ // char *serr); /* return address for error message */
639
+
640
+ static VALUE t_swe_rise_trans_true_hor(VALUE self, VALUE julian_day, VALUE body, VALUE flag, VALUE rmsi, VALUE lon, VALUE lat, VALUE height, VALUE pressure, VALUE temp, VALUE hor_height)
641
+ {
642
+ double geopos[3];
643
+ geopos[0] = NUM2DBL(lon);
644
+ geopos[1] = NUM2DBL(lat);
645
+ geopos[2] = NUM2DBL(height);
646
+ int ipl;
647
+ char *starname;
648
+ if (TYPE(body) == T_STRING)
649
+ {
650
+ starname = StringValuePtr(body);
651
+ ipl = 0;
652
+ }
653
+ else
654
+ {
655
+ ipl = NUM2INT(body);
656
+ starname = NULL;
657
+ }
658
+ char serr[AS_MAXCH];
659
+ double retval;
660
+
661
+ if (swe_rise_trans_true_hor(NUM2DBL(julian_day), ipl, starname, NUM2INT(flag), NUM2INT(rmsi), geopos, NUM2DBL(pressure), NUM2DBL(temp), NUM2DBL(hor_height), &retval, serr) < 0)
662
+ rb_raise(rb_eRuntimeError, serr);
663
+ return rb_float_new(retval);
664
+ }
665
+
666
+ // https://www.astro.com/swisseph/swephprg.htm#_Toc112948998
667
+ // swe_azalt() computes the horizontal coordinates (azimuth and altitude) of a planet or a star from either ecliptical or equatorial coordinates.
668
+ // void swe_azalt(
669
+ // double tjd_ut, // UT
670
+ // int32 calc_flag, // SE_ECL2HOR or SE_EQU2HOR
671
+ // double *geopos, // array of 3 doubles: geograph. long., lat., height
672
+ // double atpress, // atmospheric pressure in mbar (hPa)
673
+ // double attemp, // atmospheric temperature in degrees Celsius
674
+ // double *xin, // array of 3 doubles: position of body in either ecliptical or equatorial coordinates, depending on calc_flag
675
+ // double *xaz); // return array of 3 doubles, containing azimuth, true altitude, apparent altitude
676
+ // If calc_flag = SE_ECL2HOR, set xin[0] = ecl. long., xin[1] = ecl. lat., (xin[2] = distance (not required));
677
+ // else
678
+ // if calc_flag = SE_EQU2HOR, set xin[0] = right ascension, xin[1] = declination, (xin[2] = distance (not required));
679
+ // #define SE_ECL2HOR 0
680
+ // #define SE_EQU2HOR 1
681
+ // The return values are:
682
+ // · xaz[0] = azimuth, i.e. position degree, measured from the south point to west;
683
+ // · xaz[1] = true altitude above horizon in degrees;
684
+ // · xaz[2] = apparent (refracted) altitude above horizon in degrees.
685
+ // The apparent altitude of a body depends on the atmospheric pressure and temperature. If only the true altitude is required, these parameters can be neglected.
686
+ // If atpress is given the value 0, the function estimates the pressure from the geographical altitude given in geopos[2] and attemp. If geopos[2] is 0, atpress will be estimated for sea level.
687
+ static VALUE t_swe_azalt(VALUE self, VALUE julian_day, VALUE flag, VALUE lon, VALUE lat, VALUE height, VALUE pressure, VALUE temp, VALUE in0, VALUE in1, VALUE in2)
688
+ {
689
+ double geopos[3];
690
+ geopos[0] = NUM2DBL(lon);
691
+ geopos[1] = NUM2DBL(lat);
692
+ geopos[2] = NUM2DBL(height);
693
+
694
+ double xin[3];
695
+ xin[0] = NUM2DBL(in0);
696
+ xin[1] = NUM2DBL(in1);
697
+ xin[2] = NUM2DBL(in2);
698
+ double xaz[3];
699
+
700
+ swe_azalt(NUM2DBL(julian_day), NUM2INT(flag), geopos, NUM2DBL(pressure), NUM2DBL(temp), xin, xaz);
701
+
702
+ VALUE output = rb_ary_new();
703
+ rb_ary_push(output, rb_float_new(xaz[0]));
704
+ rb_ary_push(output, rb_float_new(xaz[1]));
705
+ rb_ary_push(output, rb_float_new(xaz[2]));
706
+ return output;
707
+ }
708
+
709
+ /*
710
+ * Reverse of swe_azalt: horizontal to ecliptic/equatorial
711
+ * void swe_azalt_rev(double tjd_ut, int32 calc_flag, double *geopos, double *xin, double *xout);
712
+ * calc_flag: SE_HOR2ECL or SE_HOR2EQU
713
+ * xin: [azimuth, true_altitude]
714
+ * xout: [longitude, latitude] or [ra, dec]
715
+ */
716
+ static VALUE t_swe_azalt_rev(VALUE self, VALUE julian_day, VALUE flag, VALUE lon, VALUE lat, VALUE height, VALUE azimuth, VALUE altitude)
717
+ {
718
+ double geopos[3];
719
+ geopos[0] = NUM2DBL(lon);
720
+ geopos[1] = NUM2DBL(lat);
721
+ geopos[2] = NUM2DBL(height);
722
+
723
+ double xin[2];
724
+ xin[0] = NUM2DBL(azimuth);
725
+ xin[1] = NUM2DBL(altitude);
726
+ double xout[2];
727
+
728
+ swe_azalt_rev(NUM2DBL(julian_day), NUM2INT(flag), geopos, xin, xout);
729
+
730
+ VALUE output = rb_ary_new();
731
+ rb_ary_push(output, rb_float_new(xout[0]));
732
+ rb_ary_push(output, rb_float_new(xout[1]));
733
+ return output;
734
+ }
735
+
736
+ /*
737
+ * Atmospheric refraction
738
+ * double swe_refrac(double inalt, double atpress, double attemp, int32 calc_flag);
739
+ * calc_flag: SE_TRUE_TO_APP (0) or SE_APP_TO_TRUE (1)
740
+ */
741
+ static VALUE t_swe_refrac(VALUE self, VALUE inalt, VALUE atpress, VALUE attemp, VALUE calc_flag)
742
+ {
743
+ double result = swe_refrac(NUM2DBL(inalt), NUM2DBL(atpress), NUM2DBL(attemp), NUM2INT(calc_flag));
744
+ return rb_float_new(result);
745
+ }
746
+
747
+ /*
748
+ * Planetary phenomena (phase, elongation, magnitude, etc.)
749
+ * int32 swe_pheno_ut(double tjd_ut, int32 ipl, int32 iflag, double *attr, char *serr);
750
+ * Returns array of 7 values:
751
+ * [0] phase angle (earth-planet-sun)
752
+ * [1] phase (illumined fraction of disc)
753
+ * [2] elongation of planet
754
+ * [3] apparent diameter of disc
755
+ * [4] apparent magnitude
756
+ * [5] horizontal parallax (Moon)
757
+ * [6] (reserved)
758
+ */
759
+ static VALUE t_swe_pheno_ut(VALUE self, VALUE julian_ut, VALUE ipl, VALUE iflag)
760
+ {
761
+ double attr[20];
762
+ char serr[AS_MAXCH];
763
+
764
+ if (swe_pheno_ut(NUM2DBL(julian_ut), NUM2INT(ipl), NUM2INT(iflag), attr, serr) < 0)
765
+ rb_raise(rb_eRuntimeError, serr);
766
+
767
+ VALUE output = rb_ary_new();
768
+ for (int i = 0; i < 7; i++)
769
+ rb_ary_push(output, rb_float_new(attr[i]));
770
+ return output;
771
+ }
772
+
773
+ /*
774
+ * Equation of time
775
+ * int32 swe_time_equ(double tjd, double *te, char *serr);
776
+ * Returns the difference between local apparent time and local mean time in days
777
+ */
778
+ static VALUE t_swe_time_equ(VALUE self, VALUE tjd)
779
+ {
780
+ double te;
781
+ char serr[AS_MAXCH];
782
+
783
+ if (swe_time_equ(NUM2DBL(tjd), &te, serr) < 0)
784
+ rb_raise(rb_eRuntimeError, serr);
785
+
786
+ return rb_float_new(te);
787
+ }
788
+
789
+ /*
790
+ * Local mean time to local apparent time
791
+ * int32 swe_lmt_to_lat(double tjd_lmt, double geolon, double *tjd_lat, char *serr);
792
+ */
793
+ static VALUE t_swe_lmt_to_lat(VALUE self, VALUE tjd_lmt, VALUE geolon)
794
+ {
795
+ double tjd_lat;
796
+ char serr[AS_MAXCH];
797
+
798
+ if (swe_lmt_to_lat(NUM2DBL(tjd_lmt), NUM2DBL(geolon), &tjd_lat, serr) < 0)
799
+ rb_raise(rb_eRuntimeError, serr);
800
+
801
+ return rb_float_new(tjd_lat);
802
+ }
803
+
804
+ /*
805
+ * Local apparent time to local mean time
806
+ * int32 swe_lat_to_lmt(double tjd_lat, double geolon, double *tjd_lmt, char *serr);
807
+ */
808
+ static VALUE t_swe_lat_to_lmt(VALUE self, VALUE tjd_lat, VALUE geolon)
809
+ {
810
+ double tjd_lmt;
811
+ char serr[AS_MAXCH];
812
+
813
+ if (swe_lat_to_lmt(NUM2DBL(tjd_lat), NUM2DBL(geolon), &tjd_lmt, serr) < 0)
814
+ rb_raise(rb_eRuntimeError, serr);
815
+
816
+ return rb_float_new(tjd_lmt);
817
+ }
818
+
819
+ // https://www.astro.com/swisseph/swephprg.htm#_Toc112949076
820
+ /* equator -> ecliptic : eps must be positive
821
+ * ecliptic -> equator : eps must be negative
822
+ * eps, longitude and latitude are in positive degrees! */
823
+ // void swe_cotrans(
824
+ // double *xpo, /* 3 doubles: long., lat., dist. to be converted; distance remains unchanged, can be set to 1.00 */
825
+ // double *xpn, /* 3 doubles: long., lat., dist. Result of the conversion */
826
+ // double eps); /* obliquity of ecliptic, in degrees. */
827
+ static VALUE t_swe_cotrans(int argc, VALUE *argv, VALUE self)
828
+ {
829
+ // VALUE self, VALUE VALUE lon, VALUE lat, VALUE distance
830
+ if (argc < 3 || argc > 4)
831
+ { // there should only be 3 or 4 arguments
832
+ rb_raise(rb_eArgError, "wrong number of arguments");
833
+ }
834
+ double eps = NUM2DBL(argv[0]);
835
+ double xpo[3];
836
+ xpo[0] = NUM2DBL(argv[1]); // NUM2DBL(lon);
837
+ xpo[1] = NUM2DBL(argv[2]); // NUM2DBL(lat);
838
+ xpo[2] = NUM2DBL((argc == 4) ? argv[3] : 1.0);
839
+
840
+ double xpn[3];
841
+
842
+ swe_cotrans(xpo, xpn, eps);
843
+
844
+ VALUE output = rb_ary_new();
845
+ rb_ary_push(output, rb_float_new(xpn[0]));
846
+ rb_ary_push(output, rb_float_new(xpn[1]));
847
+ if (argc == 4)
848
+ rb_ary_push(output, rb_float_new(xpn[2]));
849
+ return output;
850
+ }
851
+
852
+ /*
853
+ * Coordinate transformation with speed
854
+ * void swe_cotrans_sp(double *xpo, double *xpn, double eps);
855
+ * xpo: [lon, lat, dist, lon_speed, lat_speed, dist_speed]
856
+ * xpn: output [lon, lat, dist, lon_speed, lat_speed, dist_speed]
857
+ */
858
+ static VALUE t_swe_cotrans_sp(VALUE self, VALUE eps, VALUE lon, VALUE lat, VALUE dist, VALUE lon_speed, VALUE lat_speed, VALUE dist_speed)
859
+ {
860
+ double xpo[6];
861
+ xpo[0] = NUM2DBL(lon);
862
+ xpo[1] = NUM2DBL(lat);
863
+ xpo[2] = NUM2DBL(dist);
864
+ xpo[3] = NUM2DBL(lon_speed);
865
+ xpo[4] = NUM2DBL(lat_speed);
866
+ xpo[5] = NUM2DBL(dist_speed);
867
+
868
+ double xpn[6];
869
+
870
+ swe_cotrans_sp(xpo, xpn, NUM2DBL(eps));
871
+
872
+ VALUE output = rb_ary_new();
873
+ for (int i = 0; i < 6; i++)
874
+ rb_ary_push(output, rb_float_new(xpn[i]));
875
+ return output;
876
+ }
877
+
878
+ static VALUE t_swe_house_pos(VALUE self, VALUE armc, VALUE geolat, VALUE eps, VALUE hsys, VALUE eclon, VALUE eclat)
879
+ {
880
+ // double armc, /* ARMC */
881
+ // double geolat, /* geographic latitude, in degrees */
882
+ // double eps, /* ecliptic obliquity, in degrees */
883
+ // int hsys, /* house method, one of the letters PKRCAV */
884
+ // double *xpin, /* array of 2 doubles: ecl. longitude and latitude of the planet */
885
+ // char *serr); /* return area for error or warning message */
886
+
887
+ double eclpos[2];
888
+ eclpos[0] = NUM2DBL(eclon);
889
+ eclpos[1] = NUM2DBL(eclat);
890
+ char serr[AS_MAXCH];
891
+
892
+ double retval = swe_house_pos(NUM2DBL(armc), NUM2DBL(geolat), NUM2DBL(eps), NUM2INT(hsys), eclpos, serr);
893
+ if (retval < 0)
894
+ rb_raise(rb_eRuntimeError, serr);
895
+
896
+ VALUE output = rb_float_new(retval);
897
+ return output;
898
+ }
899
+
900
+ /*
901
+ * Find the crossing of the Sun over a given ecliptic position
902
+ * double swe_solcross_ut(double x2cross, double tjd_ut, int32 iflag, char *serr);
903
+ */
904
+ static VALUE t_swe_solcross_ut(VALUE self, VALUE x2cross, VALUE tjd_ut, VALUE iflag)
905
+ {
906
+ char serr[AS_MAXCH];
907
+ serr[0] = '\0';
908
+ double tjd = NUM2DBL(tjd_ut);
909
+
910
+ double retval = swe_solcross_ut(NUM2DBL(x2cross), tjd, NUM2INT(iflag), serr);
911
+ if (retval < tjd)
912
+ rb_raise(rb_eRuntimeError, "%s", serr);
913
+ return rb_float_new(retval);
914
+ }
915
+
916
+ /*
917
+ * Find the crossing of the Moon over a given ecliptic position
918
+ * double swe_mooncross_ut(double x2cross, double tjd_ut, int32 iflag, char *serr);
919
+ */
920
+ static VALUE t_swe_mooncross_ut(VALUE self, VALUE x2cross, VALUE tjd_ut, VALUE iflag)
921
+ {
922
+ char serr[AS_MAXCH];
923
+ serr[0] = '\0';
924
+ double tjd = NUM2DBL(tjd_ut);
925
+
926
+ double retval = swe_mooncross_ut(NUM2DBL(x2cross), tjd, NUM2INT(iflag), serr);
927
+ if (retval < tjd)
928
+ rb_raise(rb_eRuntimeError, "%s", serr);
929
+ return rb_float_new(retval);
930
+ }
931
+
932
+ /*
933
+ double swe_mooncross_node_ut(
934
+ double tjd_ut,
935
+ int32 iflag,
936
+ double *xlon,
937
+ double *xlat,
938
+ char *serr);
939
+ */
940
+ static VALUE t_swe_mooncross_node_ut(VALUE self, VALUE tjd_ut, VALUE iflag)
941
+ {
942
+ char serr[AS_MAXCH];
943
+ serr[0] = '\0';
944
+ double tjd = NUM2DBL(tjd_ut);
945
+ double xlon, xlat;
946
+ double retval = swe_mooncross_node_ut(tjd, NUM2INT(iflag), &xlon, &xlat, serr);
947
+ if (retval < tjd)
948
+ rb_raise(rb_eRuntimeError, "%s", serr);
949
+ VALUE output = rb_ary_new();
950
+ rb_ary_push(output, rb_float_new(retval));
951
+ rb_ary_push(output, rb_float_new(xlon));
952
+ rb_ary_push(output, rb_float_new(xlat));
953
+
954
+ return output;
955
+ }
956
+ /*
957
+ * Find heliocentric crossing of a planet over a given ecliptic position
958
+ * int32 swe_helio_cross_ut(int32 ipl, double x2cross, double tjd_ut, int32 iflag, int32 dir, double *jx, char *serr);
959
+ */
960
+ static VALUE t_swe_helio_cross_ut(VALUE self, VALUE body, VALUE x2cross, VALUE tjd_ut, VALUE iflag, VALUE dir)
961
+ {
962
+ char serr[AS_MAXCH];
963
+ serr[0] = '\0';
964
+ double jx;
965
+ int32 retval = swe_helio_cross_ut(NUM2INT(body), NUM2DBL(x2cross), NUM2DBL(tjd_ut), NUM2INT(iflag), NUM2INT(dir), &jx, serr);
966
+ if (retval < 0)
967
+ rb_raise(rb_eRuntimeError, "%s", serr);
968
+ return rb_float_new(jx);
969
+ }
970
+
971
+ /*
972
+ * Find the crossing of the Sun over a given ecliptic position (ET version)
973
+ * double swe_solcross(double x2cross, double jd_et, int32 flag, char *serr);
974
+ */
975
+ static VALUE t_swe_solcross(VALUE self, VALUE x2cross, VALUE tjd_et, VALUE iflag)
976
+ {
977
+ char serr[AS_MAXCH];
978
+ serr[0] = '\0';
979
+ double tjd = NUM2DBL(tjd_et);
980
+
981
+ double retval = swe_solcross(NUM2DBL(x2cross), tjd, NUM2INT(iflag), serr);
982
+ if (retval < tjd)
983
+ rb_raise(rb_eRuntimeError, "%s", serr);
984
+ return rb_float_new(retval);
985
+ }
986
+
987
+ /*
988
+ * Find the crossing of the Moon over a given ecliptic position (ET version)
989
+ * double swe_mooncross(double x2cross, double jd_et, int32 flag, char *serr);
990
+ */
991
+ static VALUE t_swe_mooncross(VALUE self, VALUE x2cross, VALUE tjd_et, VALUE iflag)
992
+ {
993
+ char serr[AS_MAXCH];
994
+ serr[0] = '\0';
995
+ double tjd = NUM2DBL(tjd_et);
996
+
997
+ double retval = swe_mooncross(NUM2DBL(x2cross), tjd, NUM2INT(iflag), serr);
998
+ if (retval < tjd)
999
+ rb_raise(rb_eRuntimeError, "%s", serr);
1000
+ return rb_float_new(retval);
1001
+ }
1002
+
1003
+ /*
1004
+ * Find moon crossing of node (ET version)
1005
+ * double swe_mooncross_node(double jd_et, int32 flag, double *xlon, double *xlat, char *serr);
1006
+ */
1007
+ static VALUE t_swe_mooncross_node(VALUE self, VALUE tjd_et, VALUE iflag)
1008
+ {
1009
+ char serr[AS_MAXCH];
1010
+ serr[0] = '\0';
1011
+ double tjd = NUM2DBL(tjd_et);
1012
+ double xlon, xlat;
1013
+ double retval = swe_mooncross_node(tjd, NUM2INT(iflag), &xlon, &xlat, serr);
1014
+ if (retval < tjd)
1015
+ rb_raise(rb_eRuntimeError, "%s", serr);
1016
+ VALUE output = rb_ary_new();
1017
+ rb_ary_push(output, rb_float_new(retval));
1018
+ rb_ary_push(output, rb_float_new(xlon));
1019
+ rb_ary_push(output, rb_float_new(xlat));
1020
+
1021
+ return output;
1022
+ }
1023
+
1024
+ /*
1025
+ * Find heliocentric crossing of a planet (ET version)
1026
+ * int32 swe_helio_cross(int32 ipl, double x2cross, double jd_et, int32 iflag, int32 dir, double *jd_cross, char *serr);
1027
+ */
1028
+ static VALUE t_swe_helio_cross(VALUE self, VALUE body, VALUE x2cross, VALUE tjd_et, VALUE iflag, VALUE dir)
1029
+ {
1030
+ char serr[AS_MAXCH];
1031
+ serr[0] = '\0';
1032
+ double jx;
1033
+ int32 retval = swe_helio_cross(NUM2INT(body), NUM2DBL(x2cross), NUM2DBL(tjd_et), NUM2INT(iflag), NUM2INT(dir), &jx, serr);
1034
+ if (retval < 0)
1035
+ rb_raise(rb_eRuntimeError, "%s", serr);
1036
+ return rb_float_new(jx);
1037
+ }
1038
+
1039
+ /*
1040
+ * Compute planetary nodes and apsides (perihelia, aphelia) - UT version
1041
+ * Returns [ascending_node, descending_node, perihelion, aphelion] each with 6 values
1042
+ */
1043
+ static VALUE t_swe_nod_aps_ut(VALUE self, VALUE julian_ut, VALUE body, VALUE iflag, VALUE method)
1044
+ {
1045
+ char serr[AS_MAXCH];
1046
+ double xnasc[6];
1047
+ double xndsc[6];
1048
+ double xperi[6];
1049
+ double xaphe[6];
1050
+
1051
+ if (swe_nod_aps_ut(NUM2DBL(julian_ut), NUM2INT(body), NUM2INT(iflag), NUM2INT(method), xnasc, xndsc, xperi, xaphe, serr) < 0)
1052
+ rb_raise(rb_eRuntimeError, serr);
1053
+
1054
+ VALUE output = rb_ary_new();
1055
+
1056
+ VALUE ascending = rb_ary_new();
1057
+ for (int i = 0; i < 6; i++)
1058
+ rb_ary_push(ascending, rb_float_new(xnasc[i]));
1059
+ rb_ary_push(output, ascending);
1060
+
1061
+ VALUE descending = rb_ary_new();
1062
+ for (int i = 0; i < 6; i++)
1063
+ rb_ary_push(descending, rb_float_new(xndsc[i]));
1064
+ rb_ary_push(output, descending);
1065
+
1066
+ VALUE perihelion = rb_ary_new();
1067
+ for (int i = 0; i < 6; i++)
1068
+ rb_ary_push(perihelion, rb_float_new(xperi[i]));
1069
+ rb_ary_push(output, perihelion);
1070
+
1071
+ VALUE aphelion = rb_ary_new();
1072
+ for (int i = 0; i < 6; i++)
1073
+ rb_ary_push(aphelion, rb_float_new(xaphe[i]));
1074
+ rb_ary_push(output, aphelion);
1075
+
1076
+ return output; // return array of arrays
1077
+ }
1078
+
1079
+ /*
1080
+ * Compute planetary nodes and apsides (perihelia, aphelia) - ET version
1081
+ * int32 swe_nod_aps(double tjd_et, int32 ipl, int32 iflag, int32 method, ...);
1082
+ */
1083
+ static VALUE t_swe_nod_aps(VALUE self, VALUE julian_et, VALUE body, VALUE iflag, VALUE method)
1084
+ {
1085
+ char serr[AS_MAXCH];
1086
+ double xnasc[6];
1087
+ double xndsc[6];
1088
+ double xperi[6];
1089
+ double xaphe[6];
1090
+
1091
+ if (swe_nod_aps(NUM2DBL(julian_et), NUM2INT(body), NUM2INT(iflag), NUM2INT(method), xnasc, xndsc, xperi, xaphe, serr) < 0)
1092
+ rb_raise(rb_eRuntimeError, serr);
1093
+
1094
+ VALUE output = rb_ary_new();
1095
+
1096
+ VALUE ascending = rb_ary_new();
1097
+ for (int i = 0; i < 6; i++)
1098
+ rb_ary_push(ascending, rb_float_new(xnasc[i]));
1099
+ rb_ary_push(output, ascending);
1100
+
1101
+ VALUE descending = rb_ary_new();
1102
+ for (int i = 0; i < 6; i++)
1103
+ rb_ary_push(descending, rb_float_new(xndsc[i]));
1104
+ rb_ary_push(output, descending);
1105
+
1106
+ VALUE perihelion = rb_ary_new();
1107
+ for (int i = 0; i < 6; i++)
1108
+ rb_ary_push(perihelion, rb_float_new(xperi[i]));
1109
+ rb_ary_push(output, perihelion);
1110
+
1111
+ VALUE aphelion = rb_ary_new();
1112
+ for (int i = 0; i < 6; i++)
1113
+ rb_ary_push(aphelion, rb_float_new(xaphe[i]));
1114
+ rb_ary_push(output, aphelion);
1115
+
1116
+ return output; // return array of arrays
1117
+ }
1118
+
1119
+ /* swe_calc_pctr() calculates planetocentric positions of planets, i. e. positions as observed from some different planet, e.g. Jupiter-centric ephemerides. The function can actually calculate any object as observed from any other object, e.g. also the position of some asteroid as observed from another asteroid or from a planetary moon. The function declaration is as follows:
1120
+ int32 swe_calc_pctr(
1121
+ double tjd, // input time in TT
1122
+ int32 ipl, // target object
1123
+ int32 iplctr, // center object
1124
+ int32 iflag,
1125
+ double *xxret,
1126
+ char *serr);
1127
+ */
1128
+ // tjd_et = Julian day, Ephemeris time, where tjd_et = tjd_ut + swe_deltat(tjd_ut)
1129
+ static VALUE t_swe_calc_pctr(VALUE self, VALUE julian_et, VALUE body, VALUE center, VALUE iflag)
1130
+ {
1131
+ char serr[AS_MAXCH];
1132
+ double xxret[6];
1133
+
1134
+ if (swe_calc_pctr(NUM2DBL(julian_et), NUM2INT(body), NUM2INT(center), NUM2INT(iflag), xxret, serr) < 0)
1135
+ rb_raise(rb_eRuntimeError, serr);
1136
+
1137
+ VALUE output = rb_ary_new();
1138
+ for (int i = 0; i < 6; i++)
1139
+ rb_ary_push(output, rb_float_new(xxret[i]));
1140
+
1141
+ return output;
1142
+ }
1143
+
1144
+ /*
1145
+ * Calculate orbital elements of a planet or asteroid
1146
+ * https://www.astro.com/swisseph/swephprg.htm#_Toc112949042
1147
+ * int32 swe_get_orbital_elements(
1148
+ * double tjd_et, // Julian day in ET/TT
1149
+ * int32 ipl, // planet number
1150
+ * int32 iflag, // flag bits
1151
+ * double *dret, // return values, see below
1152
+ * char *serr); // error string
1153
+ *
1154
+ * Returns array with the following values:
1155
+ * - 0: semi-major axis (AU)
1156
+ * - 1: eccentricity
1157
+ * - 2: inclination (degrees)
1158
+ * - 3: longitude of ascending node (degrees)
1159
+ * - 4: argument of perihelion (degrees)
1160
+ * - 5: longitude of perihelion (degrees)
1161
+ * - 6: mean anomaly (degrees)
1162
+ * - 7: true anomaly (degrees)
1163
+ * - 8: eccentric anomaly (degrees)
1164
+ * - 9: mean longitude (degrees)
1165
+ * - 10: semi-minor axis (AU)
1166
+ * - 11: focal distance (AU)
1167
+ * - 12: perihelion distance (AU)
1168
+ * - 13: aphelion distance (AU)
1169
+ * - 14: orbital period (years)
1170
+ * - 15: mean daily motion (degrees)
1171
+ * - 16: daily motion at tjd_et (degrees)
1172
+ */
1173
+ static VALUE t_swe_get_orbital_elements(VALUE self, VALUE julian_et, VALUE body, VALUE iflag)
1174
+ {
1175
+ char serr[AS_MAXCH];
1176
+ double dret[17]; // Array to store the return values
1177
+
1178
+ if (swe_get_orbital_elements(NUM2DBL(julian_et), NUM2INT(body), NUM2INT(iflag), dret, serr) < 0)
1179
+ rb_raise(rb_eRuntimeError, serr);
1180
+
1181
+ VALUE output = rb_ary_new();
1182
+ for (int i = 0; i < 17; i++)
1183
+ rb_ary_push(output, rb_float_new(dret[i]));
1184
+
1185
+ return output;
1186
+ }
1187
+
1188
+ /*
1189
+ * Get the Delta T value (difference between ET and UT)
1190
+ * https://www.astro.com/swisseph/swephprg.htm#_Toc112949107
1191
+ * double swe_deltat(double tjd_ut);
1192
+ */
1193
+ static VALUE t_swe_deltat(VALUE self, VALUE julian_ut)
1194
+ {
1195
+ double delta_t = swe_deltat(NUM2DBL(julian_ut));
1196
+ return rb_float_new(delta_t);
1197
+ }
1198
+
1199
+ /*
1200
+ * Get the Delta T value (difference between ET and UT) with explicit ephemeris
1201
+ * https://www.astro.com/swisseph/swephprg.htm#_Toc112949107
1202
+ * double swe_deltat_ex(double tjd_ut, int32 iflag, char *serr);
1203
+ */
1204
+ static VALUE t_swe_deltat_ex(VALUE self, VALUE julian_ut, VALUE iflag)
1205
+ {
1206
+ char serr[AS_MAXCH];
1207
+ double delta_t = swe_deltat_ex(NUM2DBL(julian_ut), NUM2INT(iflag), serr);
1208
+
1209
+ // If there's an error message, return it along with the delta_t value
1210
+ if (serr[0] != '\0')
1211
+ {
1212
+ VALUE result = rb_ary_new();
1213
+ rb_ary_push(result, rb_float_new(delta_t));
1214
+ rb_ary_push(result, rb_str_new_cstr(serr));
1215
+ return result;
1216
+ }
1217
+
1218
+ return rb_float_new(delta_t);
1219
+ }
1220
+
1221
+ static VALUE t_swe_fixstar(VALUE self, VALUE star, VALUE julian_et, VALUE iflag)
1222
+ {
1223
+ char serr[AS_MAXCH];
1224
+ double results[6];
1225
+
1226
+ if (swe_fixstar(StringValuePtr(star), NUM2DBL(julian_et), NUM2INT(iflag), results, serr) < 0)
1227
+ rb_raise(rb_eRuntimeError, serr);
1228
+
1229
+ VALUE output = rb_ary_new();
1230
+ for (int i = 0; i < 6; i++)
1231
+ rb_ary_push(output, rb_float_new(results[i]));
1232
+
1233
+ return output;
1234
+ }
1235
+
1236
+ static VALUE t_swe_fixstar_ut(VALUE self, VALUE star, VALUE julian_ut, VALUE iflag)
1237
+ {
1238
+ char serr[AS_MAXCH];
1239
+ double results[6];
1240
+
1241
+ if (swe_fixstar_ut(StringValuePtr(star), NUM2DBL(julian_ut), NUM2INT(iflag), results, serr) < 0)
1242
+ rb_raise(rb_eRuntimeError, serr);
1243
+
1244
+ VALUE output = rb_ary_new();
1245
+ for (int i = 0; i < 6; i++)
1246
+ rb_ary_push(output, rb_float_new(results[i]));
1247
+
1248
+ return output;
1249
+ }
1250
+
1251
+ static VALUE t_swe_fixstar_mag(VALUE self, VALUE star)
1252
+ {
1253
+ char serr[AS_MAXCH];
1254
+ double mag;
1255
+
1256
+ if (swe_fixstar_mag(StringValuePtr(star), &mag, serr) < 0)
1257
+ rb_raise(rb_eRuntimeError, serr);
1258
+
1259
+ return rb_float_new(mag);
1260
+ }
1261
+
1262
+ static VALUE t_swe_fixstar2(VALUE self, VALUE star, VALUE julian_et, VALUE iflag)
1263
+ {
1264
+ char serr[AS_MAXCH];
1265
+ double results[6];
1266
+
1267
+ if (swe_fixstar2(StringValuePtr(star), NUM2DBL(julian_et), NUM2INT(iflag), results, serr) < 0)
1268
+ rb_raise(rb_eRuntimeError, serr);
1269
+
1270
+ VALUE output = rb_ary_new();
1271
+ for (int i = 0; i < 6; i++)
1272
+ rb_ary_push(output, rb_float_new(results[i]));
1273
+
1274
+ return output;
1275
+ }
1276
+
1277
+ static VALUE t_swe_fixstar2_ut(VALUE self, VALUE star, VALUE julian_ut, VALUE iflag)
1278
+ {
1279
+ char serr[AS_MAXCH];
1280
+ double results[6];
1281
+
1282
+ if (swe_fixstar2_ut(StringValuePtr(star), NUM2DBL(julian_ut), NUM2INT(iflag), results, serr) < 0)
1283
+ rb_raise(rb_eRuntimeError, serr);
1284
+
1285
+ VALUE output = rb_ary_new();
1286
+ for (int i = 0; i < 6; i++)
1287
+ rb_ary_push(output, rb_float_new(results[i]));
1288
+
1289
+ return output;
1290
+ }
1291
+
1292
+ static VALUE t_swe_fixstar2_mag(VALUE self, VALUE star)
1293
+ {
1294
+ char serr[AS_MAXCH];
1295
+ double mag;
1296
+
1297
+ if (swe_fixstar2_mag(StringValuePtr(star), &mag, serr) < 0)
1298
+ rb_raise(rb_eRuntimeError, serr);
1299
+
1300
+ return rb_float_new(mag);
1301
+ }
1302
+
1303
+ /*
1304
+ * Find heliacal rising/setting times
1305
+ * int32 swe_heliacal_ut(double tjdstart_ut, double *geopos, double *datm, double *dobs, char *ObjectName, int32 TypeEvent, int32 iflag, double *dret, char *serr);
1306
+ * geopos: [lon, lat, height]
1307
+ * datm: [pressure, temp, humidity, extinction_coeff] (4 doubles)
1308
+ * dobs: [age, snellen_left, snellen_right, telescope_mag, telescope_diam, binoc_factor] (6 doubles)
1309
+ * TypeEvent: SE_HELIACAL_RISING, SE_HELIACAL_SETTING, SE_EVENING_FIRST, SE_MORNING_LAST
1310
+ * Returns array of 50 values (see Swiss Ephemeris documentation)
1311
+ */
1312
+ static VALUE t_swe_heliacal_ut(int argc, VALUE *argv, VALUE self)
1313
+ {
1314
+ if (argc != 9)
1315
+ rb_raise(rb_eArgError, "wrong number of arguments (9 required: tjd_ut, object_name, type_event, iflag, lon, lat, height, datm_array, dobs_array)");
1316
+
1317
+ char serr[AS_MAXCH];
1318
+ double geopos[3];
1319
+ geopos[0] = NUM2DBL(argv[4]); // lon
1320
+ geopos[1] = NUM2DBL(argv[5]); // lat
1321
+ geopos[2] = NUM2DBL(argv[6]); // height
1322
+
1323
+ // datm: atmospheric data array (4 doubles)
1324
+ VALUE datm_arr = argv[7];
1325
+ if (TYPE(datm_arr) != T_ARRAY || RARRAY_LEN(datm_arr) < 4)
1326
+ rb_raise(rb_eArgError, "datm must be array of 4 values [pressure, temp, humidity, extinction_coeff]");
1327
+ double datm[4];
1328
+ for (int i = 0; i < 4; i++)
1329
+ datm[i] = NUM2DBL(rb_ary_entry(datm_arr, i));
1330
+
1331
+ // dobs: observer data array (6 doubles)
1332
+ VALUE dobs_arr = argv[8];
1333
+ if (TYPE(dobs_arr) != T_ARRAY || RARRAY_LEN(dobs_arr) < 6)
1334
+ rb_raise(rb_eArgError, "dobs must be array of 6 values [age, snellen_left, snellen_right, telescope_mag, telescope_diam, binoc_factor]");
1335
+ double dobs[6];
1336
+ for (int i = 0; i < 6; i++)
1337
+ dobs[i] = NUM2DBL(rb_ary_entry(dobs_arr, i));
1338
+
1339
+ double dret[50];
1340
+ char *object_name = StringValuePtr(argv[1]);
1341
+
1342
+ if (swe_heliacal_ut(NUM2DBL(argv[0]), geopos, datm, dobs, object_name, NUM2INT(argv[2]), NUM2INT(argv[3]), dret, serr) < 0)
1343
+ rb_raise(rb_eRuntimeError, serr);
1344
+
1345
+ VALUE output = rb_ary_new();
1346
+ for (int i = 0; i < 50; i++)
1347
+ rb_ary_push(output, rb_float_new(dret[i]));
1348
+ return output;
1349
+ }
1350
+
1351
+ /*
1352
+ * Compute visibility limit magnitude
1353
+ * int32 swe_vis_limit_mag(double tjdut, double *geopos, double *datm, double *dobs, char *ObjectName, int32 helflag, double *dret, char *serr);
1354
+ * Returns array of 8 values with magnitude information
1355
+ */
1356
+ static VALUE t_swe_vis_limit_mag(int argc, VALUE *argv, VALUE self)
1357
+ {
1358
+ if (argc != 8)
1359
+ rb_raise(rb_eArgError, "wrong number of arguments (8 required: tjd_ut, object_name, helflag, lon, lat, height, datm_array, dobs_array)");
1360
+
1361
+ char serr[AS_MAXCH];
1362
+ double geopos[3];
1363
+ geopos[0] = NUM2DBL(argv[3]); // lon
1364
+ geopos[1] = NUM2DBL(argv[4]); // lat
1365
+ geopos[2] = NUM2DBL(argv[5]); // height
1366
+
1367
+ // datm: atmospheric data array (4 doubles)
1368
+ VALUE datm_arr = argv[6];
1369
+ if (TYPE(datm_arr) != T_ARRAY || RARRAY_LEN(datm_arr) < 4)
1370
+ rb_raise(rb_eArgError, "datm must be array of 4 values [pressure, temp, humidity, extinction_coeff]");
1371
+ double datm[4];
1372
+ for (int i = 0; i < 4; i++)
1373
+ datm[i] = NUM2DBL(rb_ary_entry(datm_arr, i));
1374
+
1375
+ // dobs: observer data array (6 doubles)
1376
+ VALUE dobs_arr = argv[7];
1377
+ if (TYPE(dobs_arr) != T_ARRAY || RARRAY_LEN(dobs_arr) < 6)
1378
+ rb_raise(rb_eArgError, "dobs must be array of 6 values [age, snellen_left, snellen_right, telescope_mag, telescope_diam, binoc_factor]");
1379
+ double dobs[6];
1380
+ for (int i = 0; i < 6; i++)
1381
+ dobs[i] = NUM2DBL(rb_ary_entry(dobs_arr, i));
1382
+
1383
+ double dret[50];
1384
+ char *object_name = StringValuePtr(argv[1]);
1385
+
1386
+ if (swe_vis_limit_mag(NUM2DBL(argv[0]), geopos, datm, dobs, object_name, NUM2INT(argv[2]), dret, serr) < 0)
1387
+ rb_raise(rb_eRuntimeError, serr);
1388
+
1389
+ VALUE output = rb_ary_new();
1390
+ for (int i = 0; i < 8; i++)
1391
+ rb_ary_push(output, rb_float_new(dret[i]));
1392
+ return output;
1393
+ }
1394
+
1395
+ /*
1396
+ * Compute Gauquelin sector position
1397
+ * int32 swe_gauquelin_sector(double t_ut, int32 ipl, char *starname, int32 iflag, int32 imeth, double *geopos, double atpress, double attemp, double *dgsect, char *serr);
1398
+ * imeth: 0=sector from MC/IC, 1=sector from Asc/Desc, 2=sector from 36 houses, 3=sector from 36 houses with MC/IC, 4=sector from MC/IC/Asc/Desc
1399
+ * Returns sector position (1-36)
1400
+ */
1401
+ static VALUE t_swe_gauquelin_sector(VALUE self, VALUE tjd_ut, VALUE body, VALUE iflag, VALUE imeth, VALUE lon, VALUE lat, VALUE height, VALUE atpress, VALUE attemp)
1402
+ {
1403
+ char serr[AS_MAXCH];
1404
+ double geopos[3];
1405
+ geopos[0] = NUM2DBL(lon);
1406
+ geopos[1] = NUM2DBL(lat);
1407
+ geopos[2] = NUM2DBL(height);
1408
+ double dgsect;
1409
+ int ipl;
1410
+ char *starname;
1411
+
1412
+ if (TYPE(body) == T_STRING) {
1413
+ starname = StringValuePtr(body);
1414
+ ipl = 0;
1415
+ } else {
1416
+ ipl = NUM2INT(body);
1417
+ starname = NULL;
1418
+ }
1419
+
1420
+ if (swe_gauquelin_sector(NUM2DBL(tjd_ut), ipl, starname, NUM2INT(iflag), NUM2INT(imeth), geopos, NUM2DBL(atpress), NUM2DBL(attemp), &dgsect, serr) < 0)
1421
+ rb_raise(rb_eRuntimeError, serr);
1422
+
1423
+ return rb_float_new(dgsect);
1424
+ }
1425
+
1426
+ /*
1427
+ * Find time of next solar eclipse globally
1428
+ * int32 swe_sol_eclipse_when_glob(double tjd_start, int32 ifl, int32 ifltype, double *tret, int32 backward, char *serr);
1429
+ * ifltype: SE_ECL_TOTAL, SE_ECL_ANNULAR, SE_ECL_PARTIAL, SE_ECL_ANNULAR_TOTAL, or 0 for any
1430
+ * backward: 1 for backward search, 0 for forward
1431
+ * Returns array of 10 times:
1432
+ * [0] time of maximum eclipse
1433
+ * [1] time when eclipse takes place at local apparent noon (not implemented)
1434
+ * [2] time of eclipse begin
1435
+ * [3] time of eclipse end
1436
+ * [4] time of totality begin
1437
+ * [5] time of totality end
1438
+ * [6] time of center line begin
1439
+ * [7] time of center line end
1440
+ * [8] time when annular-total eclipse becomes total (not implemented)
1441
+ * [9] time when annular-total eclipse becomes annular again (not implemented)
1442
+ */
1443
+ static VALUE t_swe_sol_eclipse_when_glob(VALUE self, VALUE tjd_start, VALUE ifl, VALUE ifltype, VALUE backward)
1444
+ {
1445
+ char serr[AS_MAXCH];
1446
+ double tret[10];
1447
+
1448
+ int32 result = swe_sol_eclipse_when_glob(NUM2DBL(tjd_start), NUM2INT(ifl), NUM2INT(ifltype), tret, NUM2INT(backward), serr);
1449
+ if (result < 0)
1450
+ rb_raise(rb_eRuntimeError, serr);
1451
+
1452
+ VALUE output = rb_ary_new();
1453
+ rb_ary_push(output, INT2NUM(result)); // eclipse type flags
1454
+ for (int i = 0; i < 10; i++)
1455
+ rb_ary_push(output, rb_float_new(tret[i]));
1456
+ return output;
1457
+ }
1458
+
1459
+ /*
1460
+ * Find time of next local solar eclipse
1461
+ * int32 swe_sol_eclipse_when_loc(double tjd_start, int32 ifl, double *geopos, double *tret, double *attr, int32 backward, char *serr);
1462
+ * Returns [type, tret[10], attr[20]]
1463
+ */
1464
+ static VALUE t_swe_sol_eclipse_when_loc(VALUE self, VALUE tjd_start, VALUE ifl, VALUE lon, VALUE lat, VALUE height, VALUE backward)
1465
+ {
1466
+ char serr[AS_MAXCH];
1467
+ double geopos[3];
1468
+ geopos[0] = NUM2DBL(lon);
1469
+ geopos[1] = NUM2DBL(lat);
1470
+ geopos[2] = NUM2DBL(height);
1471
+ double tret[10];
1472
+ double attr[20];
1473
+
1474
+ int32 result = swe_sol_eclipse_when_loc(NUM2DBL(tjd_start), NUM2INT(ifl), geopos, tret, attr, NUM2INT(backward), serr);
1475
+ if (result < 0)
1476
+ rb_raise(rb_eRuntimeError, serr);
1477
+
1478
+ VALUE output = rb_ary_new();
1479
+ rb_ary_push(output, INT2NUM(result)); // eclipse type flags
1480
+
1481
+ VALUE _tret = rb_ary_new();
1482
+ for (int i = 0; i < 10; i++)
1483
+ rb_ary_push(_tret, rb_float_new(tret[i]));
1484
+ rb_ary_push(output, _tret);
1485
+
1486
+ VALUE _attr = rb_ary_new();
1487
+ for (int i = 0; i < 20; i++)
1488
+ rb_ary_push(_attr, rb_float_new(attr[i]));
1489
+ rb_ary_push(output, _attr);
1490
+
1491
+ return output;
1492
+ }
1493
+
1494
+ /*
1495
+ * Compute attributes of solar eclipse for given tjd and location
1496
+ * int32 swe_sol_eclipse_how(double tjd, int32 ifl, double *geopos, double *attr, char *serr);
1497
+ * Returns [type, attr[20]]
1498
+ * attr[0]: fraction of solar diameter covered by moon (= magnitude for partial and annular)
1499
+ * attr[1]: ratio of lunar diameter to solar one
1500
+ * attr[2]: fraction of solar disc covered by moon (obscuration)
1501
+ * attr[3]: diameter of core shadow in km
1502
+ * attr[4]: azimuth of sun at tjd
1503
+ * attr[5]: true altitude of sun above horizon at tjd
1504
+ * attr[6]: apparent altitude of sun above horizon at tjd
1505
+ * attr[7]: elongation of moon in degrees
1506
+ * attr[8]: magnitude acc. to NASA
1507
+ * attr[9]: saros series number (if >= 0)
1508
+ * attr[10]: saros series member number (if >= 0)
1509
+ */
1510
+ static VALUE t_swe_sol_eclipse_how(VALUE self, VALUE tjd, VALUE ifl, VALUE lon, VALUE lat, VALUE height)
1511
+ {
1512
+ char serr[AS_MAXCH];
1513
+ double geopos[3];
1514
+ geopos[0] = NUM2DBL(lon);
1515
+ geopos[1] = NUM2DBL(lat);
1516
+ geopos[2] = NUM2DBL(height);
1517
+ double attr[20];
1518
+
1519
+ int32 result = swe_sol_eclipse_how(NUM2DBL(tjd), NUM2INT(ifl), geopos, attr, serr);
1520
+ if (result < 0)
1521
+ rb_raise(rb_eRuntimeError, serr);
1522
+
1523
+ VALUE output = rb_ary_new();
1524
+ rb_ary_push(output, INT2NUM(result)); // eclipse type flags
1525
+ for (int i = 0; i < 20; i++)
1526
+ rb_ary_push(output, rb_float_new(attr[i]));
1527
+ return output;
1528
+ }
1529
+
1530
+ /*
1531
+ * Find geographic location and attributes of solar eclipse at given tjd
1532
+ * int32 swe_sol_eclipse_where(double tjd, int32 ifl, double *geopos, double *attr, char *serr);
1533
+ * Returns [type, geopos[2], attr[20]]
1534
+ */
1535
+ static VALUE t_swe_sol_eclipse_where(VALUE self, VALUE tjd, VALUE ifl)
1536
+ {
1537
+ char serr[AS_MAXCH];
1538
+ double geopos[10];
1539
+ double attr[20];
1540
+
1541
+ int32 result = swe_sol_eclipse_where(NUM2DBL(tjd), NUM2INT(ifl), geopos, attr, serr);
1542
+ if (result < 0)
1543
+ rb_raise(rb_eRuntimeError, serr);
1544
+
1545
+ VALUE output = rb_ary_new();
1546
+ rb_ary_push(output, INT2NUM(result)); // eclipse type flags
1547
+
1548
+ VALUE _geopos = rb_ary_new();
1549
+ rb_ary_push(_geopos, rb_float_new(geopos[0])); // longitude
1550
+ rb_ary_push(_geopos, rb_float_new(geopos[1])); // latitude
1551
+ rb_ary_push(output, _geopos);
1552
+
1553
+ VALUE _attr = rb_ary_new();
1554
+ for (int i = 0; i < 20; i++)
1555
+ rb_ary_push(_attr, rb_float_new(attr[i]));
1556
+ rb_ary_push(output, _attr);
1557
+
1558
+ return output;
1559
+ }
1560
+
1561
+ /*
1562
+ * Find time of next lunar eclipse
1563
+ * int32 swe_lun_eclipse_when(double tjd_start, int32 ifl, int32 ifltype, double *tret, int32 backward, char *serr);
1564
+ * ifltype: SE_ECL_TOTAL, SE_ECL_PENUMBRAL, SE_ECL_PARTIAL, or 0 for any
1565
+ * Returns [type, tret[10]]
1566
+ * tret[0]: time of maximum eclipse
1567
+ * tret[1]: (not used)
1568
+ * tret[2]: time of partial phase begin
1569
+ * tret[3]: time of partial phase end
1570
+ * tret[4]: time of totality begin
1571
+ * tret[5]: time of totality end
1572
+ * tret[6]: time of penumbral phase begin
1573
+ * tret[7]: time of penumbral phase end
1574
+ */
1575
+ static VALUE t_swe_lun_eclipse_when(VALUE self, VALUE tjd_start, VALUE ifl, VALUE ifltype, VALUE backward)
1576
+ {
1577
+ char serr[AS_MAXCH];
1578
+ double tret[10];
1579
+
1580
+ int32 result = swe_lun_eclipse_when(NUM2DBL(tjd_start), NUM2INT(ifl), NUM2INT(ifltype), tret, NUM2INT(backward), serr);
1581
+ if (result < 0)
1582
+ rb_raise(rb_eRuntimeError, serr);
1583
+
1584
+ VALUE output = rb_ary_new();
1585
+ rb_ary_push(output, INT2NUM(result)); // eclipse type flags
1586
+ for (int i = 0; i < 10; i++)
1587
+ rb_ary_push(output, rb_float_new(tret[i]));
1588
+ return output;
1589
+ }
1590
+
1591
+ /*
1592
+ * Find time of next local lunar eclipse
1593
+ * int32 swe_lun_eclipse_when_loc(double tjd_start, int32 ifl, double *geopos, double *tret, double *attr, int32 backward, char *serr);
1594
+ * Returns [type, tret[10], attr[20]]
1595
+ */
1596
+ static VALUE t_swe_lun_eclipse_when_loc(VALUE self, VALUE tjd_start, VALUE ifl, VALUE lon, VALUE lat, VALUE height, VALUE backward)
1597
+ {
1598
+ char serr[AS_MAXCH];
1599
+ double geopos[3];
1600
+ geopos[0] = NUM2DBL(lon);
1601
+ geopos[1] = NUM2DBL(lat);
1602
+ geopos[2] = NUM2DBL(height);
1603
+ double tret[10];
1604
+ double attr[20];
1605
+
1606
+ int32 result = swe_lun_eclipse_when_loc(NUM2DBL(tjd_start), NUM2INT(ifl), geopos, tret, attr, NUM2INT(backward), serr);
1607
+ if (result < 0)
1608
+ rb_raise(rb_eRuntimeError, serr);
1609
+
1610
+ VALUE output = rb_ary_new();
1611
+ rb_ary_push(output, INT2NUM(result)); // eclipse type flags
1612
+
1613
+ VALUE _tret = rb_ary_new();
1614
+ for (int i = 0; i < 10; i++)
1615
+ rb_ary_push(_tret, rb_float_new(tret[i]));
1616
+ rb_ary_push(output, _tret);
1617
+
1618
+ VALUE _attr = rb_ary_new();
1619
+ for (int i = 0; i < 20; i++)
1620
+ rb_ary_push(_attr, rb_float_new(attr[i]));
1621
+ rb_ary_push(output, _attr);
1622
+
1623
+ return output;
1624
+ }
1625
+
1626
+ /*
1627
+ * Compute attributes of lunar eclipse for given tjd
1628
+ * int32 swe_lun_eclipse_how(double tjd_ut, int32 ifl, double *geopos, double *attr, char *serr);
1629
+ * geopos is optional for some values (can pass 0,0,0)
1630
+ * Returns [type, attr[20]]
1631
+ * attr[0]: umbral magnitude at tjd
1632
+ * attr[1]: penumbral magnitude
1633
+ * attr[2]: (not used)
1634
+ * attr[3]: (not used)
1635
+ * attr[4]: azimuth of moon at tjd
1636
+ * attr[5]: true altitude of moon above horizon at tjd
1637
+ * attr[6]: apparent altitude of moon above horizon at tjd
1638
+ * attr[7]: distance of moon from opposition in degrees
1639
+ * attr[8]: umbral magnitude at tjd (same as attr[0])
1640
+ * attr[9]: saros series number
1641
+ * attr[10]: saros series member number
1642
+ */
1643
+ static VALUE t_swe_lun_eclipse_how(VALUE self, VALUE tjd, VALUE ifl, VALUE lon, VALUE lat, VALUE height)
1644
+ {
1645
+ char serr[AS_MAXCH];
1646
+ double geopos[3];
1647
+ geopos[0] = NUM2DBL(lon);
1648
+ geopos[1] = NUM2DBL(lat);
1649
+ geopos[2] = NUM2DBL(height);
1650
+ double attr[20];
1651
+
1652
+ int32 result = swe_lun_eclipse_how(NUM2DBL(tjd), NUM2INT(ifl), geopos, attr, serr);
1653
+ if (result < 0)
1654
+ rb_raise(rb_eRuntimeError, serr);
1655
+
1656
+ VALUE output = rb_ary_new();
1657
+ rb_ary_push(output, INT2NUM(result)); // eclipse type flags
1658
+ for (int i = 0; i < 20; i++)
1659
+ rb_ary_push(output, rb_float_new(attr[i]));
1660
+ return output;
1661
+ }
1662
+
1663
+ void Init_swisseph()
1664
+ {
1665
+ // Module
1666
+ rb_mSwisseph = rb_define_module("Swisseph");
1667
+
1668
+ // Module Functions
1669
+ rb_define_module_function(rb_mSwisseph, "swe_set_ephe_path", t_swe_set_ephe_path, 1);
1670
+ rb_define_module_function(rb_mSwisseph, "swe_set_jpl_file", t_swe_set_jpl_file, 1);
1671
+ rb_define_module_function(rb_mSwisseph, "swe_close", t_swe_close, 0);
1672
+ rb_define_module_function(rb_mSwisseph, "swe_version", t_swe_version, 0);
1673
+ rb_define_module_function(rb_mSwisseph, "swe_get_planet_name", t_swe_get_planet_name, 1);
1674
+ rb_define_module_function(rb_mSwisseph, "swe_get_ayanamsa_name", t_swe_get_ayanamsa_name, 1);
1675
+ rb_define_module_function(rb_mSwisseph, "swe_julday", t_swe_julday, -1);
1676
+ rb_define_module_function(rb_mSwisseph, "swe_revjul", t_swe_revjul, -1);
1677
+ rb_define_module_function(rb_mSwisseph, "swe_utc_to_jd", t_swe_utc_to_jd, -1);
1678
+ rb_define_module_function(rb_mSwisseph, "swe_jdut1_to_utc", t_swe_jdut1_to_utc, -1);
1679
+ rb_define_module_function(rb_mSwisseph, "swe_day_of_week", t_swe_day_of_week, 1);
1680
+ rb_define_module_function(rb_mSwisseph, "swe_set_topo", t_swe_set_topo, 3);
1681
+ rb_define_module_function(rb_mSwisseph, "swe_calc_ut", t_swe_calc_ut, 3);
1682
+ rb_define_module_function(rb_mSwisseph, "swe_sidtime", t_swe_sidtime, 1);
1683
+ rb_define_module_function(rb_mSwisseph, "swe_sidtime0", t_swe_sidtime0, 3);
1684
+ rb_define_module_function(rb_mSwisseph, "swe_degnorm", t_swe_degnorm, 1);
1685
+ rb_define_module_function(rb_mSwisseph, "swe_radnorm", t_swe_radnorm, 1);
1686
+ rb_define_module_function(rb_mSwisseph, "swe_split_deg", t_swe_split_deg, 2);
1687
+ rb_define_module_function(rb_mSwisseph, "swe_set_sid_mode", t_swe_set_sid_mode, 3);
1688
+ rb_define_module_function(rb_mSwisseph, "swe_get_ayanamsa_ut", t_swe_get_ayanamsa_ut, 1);
1689
+ rb_define_module_function(rb_mSwisseph, "swe_get_ayanamsa_ex_ut", t_swe_get_ayanamsa_ex_ut, 2);
1690
+ rb_define_module_function(rb_mSwisseph, "swe_houses", t_swe_houses, 4);
1691
+ rb_define_module_function(rb_mSwisseph, "swe_houses_ex", t_swe_houses_ex, 5);
1692
+ rb_define_module_function(rb_mSwisseph, "swe_houses_ex2", t_swe_houses_ex2, 5);
1693
+ rb_define_module_function(rb_mSwisseph, "swe_houses_armc", t_swe_houses_armc, 4);
1694
+ rb_define_module_function(rb_mSwisseph, "swe_house_name", t_swe_house_name, 1);
1695
+ rb_define_module_function(rb_mSwisseph, "swe_house_pos", t_swe_house_pos, 6);
1696
+ rb_define_module_function(rb_mSwisseph, "swe_rise_trans", t_swe_rise_trans, 9);
1697
+ rb_define_module_function(rb_mSwisseph, "swe_rise_trans_true_hor", t_swe_rise_trans_true_hor, 10);
1698
+ rb_define_module_function(rb_mSwisseph, "swe_azalt", t_swe_azalt, 10);
1699
+ rb_define_module_function(rb_mSwisseph, "swe_azalt_rev", t_swe_azalt_rev, 7);
1700
+ rb_define_module_function(rb_mSwisseph, "swe_refrac", t_swe_refrac, 4);
1701
+ rb_define_module_function(rb_mSwisseph, "swe_pheno_ut", t_swe_pheno_ut, 3);
1702
+ rb_define_module_function(rb_mSwisseph, "swe_time_equ", t_swe_time_equ, 1);
1703
+ rb_define_module_function(rb_mSwisseph, "swe_lmt_to_lat", t_swe_lmt_to_lat, 2);
1704
+ rb_define_module_function(rb_mSwisseph, "swe_lat_to_lmt", t_swe_lat_to_lmt, 2);
1705
+ rb_define_module_function(rb_mSwisseph, "swe_cotrans", t_swe_cotrans, -1);
1706
+ rb_define_module_function(rb_mSwisseph, "swe_cotrans_sp", t_swe_cotrans_sp, 7);
1707
+ rb_define_module_function(rb_mSwisseph, "swe_solcross_ut", t_swe_solcross_ut, 3);
1708
+ rb_define_module_function(rb_mSwisseph, "swe_mooncross_ut", t_swe_mooncross_ut, 3);
1709
+ rb_define_module_function(rb_mSwisseph, "swe_mooncross_node_ut", t_swe_mooncross_node_ut, 2);
1710
+ rb_define_module_function(rb_mSwisseph, "swe_helio_cross_ut", t_swe_helio_cross_ut, 5);
1711
+ rb_define_module_function(rb_mSwisseph, "swe_nod_aps_ut", t_swe_nod_aps_ut, 4);
1712
+ rb_define_module_function(rb_mSwisseph, "swe_calc_pctr", t_swe_calc_pctr, 4);
1713
+ rb_define_module_function(rb_mSwisseph, "swe_get_orbital_elements", t_swe_get_orbital_elements, 3);
1714
+ rb_define_module_function(rb_mSwisseph, "swe_deltat", t_swe_deltat, 1);
1715
+ rb_define_module_function(rb_mSwisseph, "swe_deltat_ex", t_swe_deltat_ex, 2);
1716
+ rb_define_module_function(rb_mSwisseph, "swe_fixstar", t_swe_fixstar, 3);
1717
+ rb_define_module_function(rb_mSwisseph, "swe_fixstar_ut", t_swe_fixstar_ut, 3);
1718
+ rb_define_module_function(rb_mSwisseph, "swe_fixstar_mag", t_swe_fixstar_mag, 1);
1719
+ rb_define_module_function(rb_mSwisseph, "swe_fixstar2", t_swe_fixstar2, 3);
1720
+ rb_define_module_function(rb_mSwisseph, "swe_fixstar2_ut", t_swe_fixstar2_ut, 3);
1721
+ rb_define_module_function(rb_mSwisseph, "swe_fixstar2_mag", t_swe_fixstar2_mag, 1);
1722
+ rb_define_module_function(rb_mSwisseph, "swe_sol_eclipse_when_glob", t_swe_sol_eclipse_when_glob, 4);
1723
+ rb_define_module_function(rb_mSwisseph, "swe_sol_eclipse_when_loc", t_swe_sol_eclipse_when_loc, 6);
1724
+ rb_define_module_function(rb_mSwisseph, "swe_sol_eclipse_how", t_swe_sol_eclipse_how, 5);
1725
+ rb_define_module_function(rb_mSwisseph, "swe_sol_eclipse_where", t_swe_sol_eclipse_where, 2);
1726
+ rb_define_module_function(rb_mSwisseph, "swe_lun_eclipse_when", t_swe_lun_eclipse_when, 4);
1727
+ rb_define_module_function(rb_mSwisseph, "swe_lun_eclipse_when_loc", t_swe_lun_eclipse_when_loc, 6);
1728
+ rb_define_module_function(rb_mSwisseph, "swe_lun_eclipse_how", t_swe_lun_eclipse_how, 5);
1729
+ rb_define_module_function(rb_mSwisseph, "swe_gauquelin_sector", t_swe_gauquelin_sector, 9);
1730
+ rb_define_module_function(rb_mSwisseph, "swe_heliacal_ut", t_swe_heliacal_ut, -1);
1731
+ rb_define_module_function(rb_mSwisseph, "swe_vis_limit_mag", t_swe_vis_limit_mag, -1);
1732
+
1733
+ // ET (Ephemeris Time) versions
1734
+ rb_define_module_function(rb_mSwisseph, "swe_calc", t_swe_calc, 3);
1735
+ rb_define_module_function(rb_mSwisseph, "swe_get_ayanamsa", t_swe_get_ayanamsa, 1);
1736
+ rb_define_module_function(rb_mSwisseph, "swe_get_ayanamsa_ex", t_swe_get_ayanamsa_ex, 2);
1737
+ rb_define_module_function(rb_mSwisseph, "swe_solcross", t_swe_solcross, 3);
1738
+ rb_define_module_function(rb_mSwisseph, "swe_mooncross", t_swe_mooncross, 3);
1739
+ rb_define_module_function(rb_mSwisseph, "swe_mooncross_node", t_swe_mooncross_node, 2);
1740
+ rb_define_module_function(rb_mSwisseph, "swe_helio_cross", t_swe_helio_cross, 5);
1741
+ rb_define_module_function(rb_mSwisseph, "swe_nod_aps", t_swe_nod_aps, 4);
1742
+
1743
+ // Constants
1744
+
1745
+ rb_define_const(rb_mSwisseph, "SE_SUN", INT2FIX(SE_SUN));
1746
+ rb_define_const(rb_mSwisseph, "SE_MOON", INT2FIX(SE_MOON));
1747
+ rb_define_const(rb_mSwisseph, "SE_MERCURY", INT2FIX(SE_MERCURY));
1748
+ rb_define_const(rb_mSwisseph, "SE_VENUS", INT2FIX(SE_VENUS));
1749
+ rb_define_const(rb_mSwisseph, "SE_MARS", INT2FIX(SE_MARS));
1750
+ rb_define_const(rb_mSwisseph, "SE_JUPITER", INT2FIX(SE_JUPITER));
1751
+ rb_define_const(rb_mSwisseph, "SE_SATURN", INT2FIX(SE_SATURN));
1752
+ rb_define_const(rb_mSwisseph, "SE_URANUS", INT2FIX(SE_URANUS));
1753
+ rb_define_const(rb_mSwisseph, "SE_NEPTUNE", INT2FIX(SE_NEPTUNE));
1754
+ rb_define_const(rb_mSwisseph, "SE_PLUTO", INT2FIX(SE_PLUTO));
1755
+ rb_define_const(rb_mSwisseph, "SE_MEAN_NODE", INT2FIX(SE_MEAN_NODE));
1756
+ rb_define_const(rb_mSwisseph, "SE_TRUE_NODE", INT2FIX(SE_TRUE_NODE));
1757
+ rb_define_const(rb_mSwisseph, "SE_MEAN_APOG", INT2FIX(SE_MEAN_APOG));
1758
+ rb_define_const(rb_mSwisseph, "SE_OSCU_APOG", INT2FIX(SE_OSCU_APOG));
1759
+ rb_define_const(rb_mSwisseph, "SE_EARTH", INT2FIX(SE_EARTH));
1760
+ rb_define_const(rb_mSwisseph, "SE_CHIRON", INT2FIX(SE_CHIRON));
1761
+ rb_define_const(rb_mSwisseph, "SE_PHOLUS", INT2FIX(SE_PHOLUS));
1762
+ rb_define_const(rb_mSwisseph, "SE_CERES", INT2FIX(SE_CERES));
1763
+ rb_define_const(rb_mSwisseph, "SE_PALLAS", INT2FIX(SE_PALLAS));
1764
+ rb_define_const(rb_mSwisseph, "SE_JUNO", INT2FIX(SE_JUNO));
1765
+ rb_define_const(rb_mSwisseph, "SE_VESTA", INT2FIX(SE_VESTA));
1766
+ rb_define_const(rb_mSwisseph, "SE_CUPIDO", INT2FIX(SE_CUPIDO));
1767
+ rb_define_const(rb_mSwisseph, "SE_HADES", INT2FIX(SE_HADES));
1768
+ rb_define_const(rb_mSwisseph, "SE_ZEUS", INT2FIX(SE_ZEUS));
1769
+ rb_define_const(rb_mSwisseph, "SE_KRONOS", INT2FIX(SE_KRONOS));
1770
+ rb_define_const(rb_mSwisseph, "SE_APOLLON", INT2FIX(SE_APOLLON));
1771
+ rb_define_const(rb_mSwisseph, "SE_ADMETOS", INT2FIX(SE_ADMETOS));
1772
+ rb_define_const(rb_mSwisseph, "SE_VULKANUS", INT2FIX(SE_VULKANUS));
1773
+ rb_define_const(rb_mSwisseph, "SE_POSEIDON", INT2FIX(SE_POSEIDON));
1774
+
1775
+ rb_define_const(rb_mSwisseph, "SE_INTP_APOG", INT2FIX(SE_INTP_APOG));
1776
+ rb_define_const(rb_mSwisseph, "SE_INTP_PERG", INT2FIX(SE_INTP_PERG));
1777
+
1778
+ rb_define_const(rb_mSwisseph, "SEFLG_JPLEPH", INT2FIX(SEFLG_JPLEPH));
1779
+ rb_define_const(rb_mSwisseph, "SEFLG_SWIEPH", INT2FIX(SEFLG_SWIEPH));
1780
+ rb_define_const(rb_mSwisseph, "SEFLG_MOSEPH", INT2FIX(SEFLG_MOSEPH));
1781
+ rb_define_const(rb_mSwisseph, "SEFLG_HELCTR", INT2FIX(SEFLG_HELCTR));
1782
+ rb_define_const(rb_mSwisseph, "SEFLG_TRUEPOS", INT2FIX(SEFLG_TRUEPOS));
1783
+ rb_define_const(rb_mSwisseph, "SEFLG_J2000", INT2FIX(SEFLG_J2000));
1784
+ rb_define_const(rb_mSwisseph, "SEFLG_NONUT", INT2FIX(SEFLG_NONUT));
1785
+ rb_define_const(rb_mSwisseph, "SEFLG_SPEED3", INT2FIX(SEFLG_SPEED3));
1786
+ rb_define_const(rb_mSwisseph, "SEFLG_SPEED", INT2FIX(SEFLG_SPEED));
1787
+ rb_define_const(rb_mSwisseph, "SEFLG_NOGDEFL", INT2FIX(SEFLG_NOGDEFL));
1788
+ rb_define_const(rb_mSwisseph, "SEFLG_NOABERR", INT2FIX(SEFLG_NOABERR));
1789
+ rb_define_const(rb_mSwisseph, "SEFLG_EQUATORIAL", INT2FIX(SEFLG_EQUATORIAL));
1790
+ rb_define_const(rb_mSwisseph, "SEFLG_XYZ", INT2FIX(SEFLG_XYZ));
1791
+ rb_define_const(rb_mSwisseph, "SEFLG_RADIANS", INT2FIX(SEFLG_RADIANS));
1792
+ rb_define_const(rb_mSwisseph, "SEFLG_BARYCTR", INT2FIX(SEFLG_BARYCTR));
1793
+ rb_define_const(rb_mSwisseph, "SEFLG_TOPOCTR", INT2FIX(SEFLG_TOPOCTR));
1794
+ rb_define_const(rb_mSwisseph, "SEFLG_SIDEREAL", INT2FIX(SEFLG_SIDEREAL));
1795
+ rb_define_const(rb_mSwisseph, "SEFLG_ICRS", INT2FIX(SEFLG_ICRS));
1796
+
1797
+ /* sidereal modes (ayanamsas) */
1798
+ rb_define_const(rb_mSwisseph, "SE_SIDM_FAGAN_BRADLEY", INT2FIX(SE_SIDM_FAGAN_BRADLEY)); // 0
1799
+ rb_define_const(rb_mSwisseph, "SE_SIDM_LAHIRI", INT2FIX(SE_SIDM_LAHIRI));
1800
+ rb_define_const(rb_mSwisseph, "SE_SIDM_DELUCE", INT2FIX(SE_SIDM_DELUCE));
1801
+ rb_define_const(rb_mSwisseph, "SE_SIDM_RAMAN", INT2FIX(SE_SIDM_RAMAN));
1802
+ rb_define_const(rb_mSwisseph, "SE_SIDM_USHASHASHI", INT2FIX(SE_SIDM_USHASHASHI));
1803
+ rb_define_const(rb_mSwisseph, "SE_SIDM_KRISHNAMURTI", INT2FIX(SE_SIDM_KRISHNAMURTI));
1804
+ rb_define_const(rb_mSwisseph, "SE_SIDM_DJWHAL_KHUL", INT2FIX(SE_SIDM_DJWHAL_KHUL));
1805
+ rb_define_const(rb_mSwisseph, "SE_SIDM_YUKTESHWAR", INT2FIX(SE_SIDM_YUKTESHWAR));
1806
+ rb_define_const(rb_mSwisseph, "SE_SIDM_JN_BHASIN", INT2FIX(SE_SIDM_JN_BHASIN));
1807
+ rb_define_const(rb_mSwisseph, "SE_SIDM_BABYL_KUGLER1", INT2FIX(SE_SIDM_BABYL_KUGLER1));
1808
+ rb_define_const(rb_mSwisseph, "SE_SIDM_BABYL_KUGLER2", INT2FIX(SE_SIDM_BABYL_KUGLER2));
1809
+ rb_define_const(rb_mSwisseph, "SE_SIDM_BABYL_KUGLER3", INT2FIX(SE_SIDM_BABYL_KUGLER3));
1810
+ rb_define_const(rb_mSwisseph, "SE_SIDM_BABYL_HUBER", INT2FIX(SE_SIDM_BABYL_HUBER));
1811
+ rb_define_const(rb_mSwisseph, "SE_SIDM_BABYL_ETPSC", INT2FIX(SE_SIDM_BABYL_ETPSC));
1812
+ rb_define_const(rb_mSwisseph, "SE_SIDM_ALDEBARAN_15TAU", INT2FIX(SE_SIDM_ALDEBARAN_15TAU));
1813
+ rb_define_const(rb_mSwisseph, "SE_SIDM_HIPPARCHOS", INT2FIX(SE_SIDM_HIPPARCHOS));
1814
+ rb_define_const(rb_mSwisseph, "SE_SIDM_SASSANIAN", INT2FIX(SE_SIDM_SASSANIAN));
1815
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALCENT_0SAG", INT2FIX(SE_SIDM_GALCENT_0SAG));
1816
+ rb_define_const(rb_mSwisseph, "SE_SIDM_J2000", INT2FIX(SE_SIDM_J2000));
1817
+ rb_define_const(rb_mSwisseph, "SE_SIDM_J1900", INT2FIX(SE_SIDM_J1900));
1818
+ rb_define_const(rb_mSwisseph, "SE_SIDM_B1950", INT2FIX(SE_SIDM_B1950));
1819
+ rb_define_const(rb_mSwisseph, "SE_SIDM_SURYASIDDHANTA", INT2FIX(SE_SIDM_SURYASIDDHANTA));
1820
+ rb_define_const(rb_mSwisseph, "SE_SIDM_SURYASIDDHANTA_MSUN", INT2FIX(SE_SIDM_SURYASIDDHANTA_MSUN));
1821
+ rb_define_const(rb_mSwisseph, "SE_SIDM_ARYABHATA", INT2FIX(SE_SIDM_ARYABHATA));
1822
+ rb_define_const(rb_mSwisseph, "SE_SIDM_ARYABHATA_MSUN", INT2FIX(SE_SIDM_ARYABHATA_MSUN));
1823
+ rb_define_const(rb_mSwisseph, "SE_SIDM_SS_REVATI", INT2FIX(SE_SIDM_SS_REVATI));
1824
+ rb_define_const(rb_mSwisseph, "SE_SIDM_SS_CITRA", INT2FIX(SE_SIDM_SS_CITRA));
1825
+ rb_define_const(rb_mSwisseph, "SE_SIDM_TRUE_CITRA", INT2FIX(SE_SIDM_TRUE_CITRA));
1826
+ rb_define_const(rb_mSwisseph, "SE_SIDM_TRUE_REVATI", INT2FIX(SE_SIDM_TRUE_REVATI));
1827
+ rb_define_const(rb_mSwisseph, "SE_SIDM_TRUE_PUSHYA", INT2FIX(SE_SIDM_TRUE_PUSHYA));
1828
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALCENT_RGILBRAND", INT2FIX(SE_SIDM_GALCENT_RGILBRAND));
1829
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALEQU_IAU1958", INT2FIX(SE_SIDM_GALEQU_IAU1958));
1830
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALEQU_TRUE", INT2FIX(SE_SIDM_GALEQU_TRUE));
1831
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALEQU_MULA", INT2FIX(SE_SIDM_GALEQU_MULA));
1832
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALALIGN_MARDYKS", INT2FIX(SE_SIDM_GALALIGN_MARDYKS));
1833
+ rb_define_const(rb_mSwisseph, "SE_SIDM_TRUE_MULA", INT2FIX(SE_SIDM_TRUE_MULA));
1834
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALCENT_MULA_WILHELM", INT2FIX(SE_SIDM_GALCENT_MULA_WILHELM));
1835
+ rb_define_const(rb_mSwisseph, "SE_SIDM_ARYABHATA_522", INT2FIX(SE_SIDM_ARYABHATA_522));
1836
+ rb_define_const(rb_mSwisseph, "SE_SIDM_BABYL_BRITTON", INT2FIX(SE_SIDM_BABYL_BRITTON));
1837
+ rb_define_const(rb_mSwisseph, "SE_SIDM_TRUE_SHEORAN", INT2FIX(SE_SIDM_TRUE_SHEORAN));
1838
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALCENT_COCHRANE", INT2FIX(SE_SIDM_GALCENT_COCHRANE));
1839
+ rb_define_const(rb_mSwisseph, "SE_SIDM_GALEQU_FIORENZA", INT2FIX(SE_SIDM_GALEQU_FIORENZA));
1840
+ rb_define_const(rb_mSwisseph, "SE_SIDM_VALENS_MOON", INT2FIX(SE_SIDM_VALENS_MOON));
1841
+ rb_define_const(rb_mSwisseph, "SE_SIDM_LAHIRI_1940", INT2FIX(SE_SIDM_LAHIRI_1940));
1842
+ rb_define_const(rb_mSwisseph, "SE_SIDM_LAHIRI_VP285", INT2FIX(SE_SIDM_LAHIRI_VP285));
1843
+ rb_define_const(rb_mSwisseph, "SE_SIDM_KRISHNAMURTI_VP291", INT2FIX(SE_SIDM_KRISHNAMURTI_VP291));
1844
+ rb_define_const(rb_mSwisseph, "SE_SIDM_LAHIRI_ICRC", INT2FIX(SE_SIDM_LAHIRI_ICRC)); // 46
1845
+ rb_define_const(rb_mSwisseph, "SE_SIDM_USER", INT2FIX(SE_SIDM_USER)); // 255
1846
+
1847
+ rb_define_const(rb_mSwisseph, "SE_GREG_CAL", INT2FIX(SE_GREG_CAL));
1848
+ rb_define_const(rb_mSwisseph, "SE_JUL_CAL", INT2FIX(SE_JUL_CAL));
1849
+
1850
+ rb_define_const(rb_mSwisseph, "SE_ECL2HOR", INT2FIX(SE_ECL2HOR));
1851
+ rb_define_const(rb_mSwisseph, "SE_EQU2HOR", INT2FIX(SE_EQU2HOR));
1852
+
1853
+ rb_define_const(rb_mSwisseph, "SE_NODBIT_MEAN", INT2FIX(SE_NODBIT_MEAN));
1854
+ rb_define_const(rb_mSwisseph, "SE_NODBIT_OSCU", INT2FIX(SE_NODBIT_OSCU));
1855
+ rb_define_const(rb_mSwisseph, "SE_NODBIT_OSCU_BAR", INT2FIX(SE_NODBIT_OSCU_BAR));
1856
+ rb_define_const(rb_mSwisseph, "SE_NODBIT_FOPOINT", INT2FIX(SE_NODBIT_FOPOINT));
1857
+
1858
+ rb_define_const(rb_mSwisseph, "SE_CALC_RISE", INT2FIX(SE_CALC_RISE));
1859
+ rb_define_const(rb_mSwisseph, "SE_CALC_SET", INT2FIX(SE_CALC_SET));
1860
+ rb_define_const(rb_mSwisseph, "SE_CALC_MTRANSIT", INT2FIX(SE_CALC_MTRANSIT));
1861
+ rb_define_const(rb_mSwisseph, "SE_CALC_ITRANSIT", INT2FIX(SE_CALC_ITRANSIT));
1862
+ rb_define_const(rb_mSwisseph, "SE_BIT_DISC_CENTER", INT2FIX(SE_BIT_DISC_CENTER));
1863
+ rb_define_const(rb_mSwisseph, "SE_BIT_DISC_BOTTOM", INT2FIX(SE_BIT_DISC_BOTTOM));
1864
+ rb_define_const(rb_mSwisseph, "SE_BIT_GEOCTR_NO_ECL_LAT", INT2FIX(SE_BIT_GEOCTR_NO_ECL_LAT));
1865
+ rb_define_const(rb_mSwisseph, "SE_BIT_NO_REFRACTION", INT2FIX(SE_BIT_NO_REFRACTION));
1866
+ rb_define_const(rb_mSwisseph, "SE_BIT_CIVIL_TWILIGHT", INT2FIX(SE_BIT_CIVIL_TWILIGHT));
1867
+ rb_define_const(rb_mSwisseph, "SE_BIT_NAUTIC_TWILIGHT", INT2FIX(SE_BIT_NAUTIC_TWILIGHT));
1868
+ rb_define_const(rb_mSwisseph, "SE_BIT_ASTRO_TWILIGHT", INT2FIX(SE_BIT_ASTRO_TWILIGHT));
1869
+ rb_define_const(rb_mSwisseph, "SE_BIT_FIXED_DISC_SIZE", INT2FIX(SE_BIT_FIXED_DISC_SIZE));
1870
+ rb_define_const(rb_mSwisseph, "SE_BIT_HINDU_RISING", INT2FIX(SE_BIT_HINDU_RISING));
1871
+
1872
+ /* for swe_azalt_rev() */
1873
+ rb_define_const(rb_mSwisseph, "SE_HOR2ECL", INT2FIX(SE_HOR2ECL));
1874
+ rb_define_const(rb_mSwisseph, "SE_HOR2EQU", INT2FIX(SE_HOR2EQU));
1875
+
1876
+ /* for swe_refrac() */
1877
+ rb_define_const(rb_mSwisseph, "SE_TRUE_TO_APP", INT2FIX(SE_TRUE_TO_APP));
1878
+ rb_define_const(rb_mSwisseph, "SE_APP_TO_TRUE", INT2FIX(SE_APP_TO_TRUE));
1879
+
1880
+ /* for swe_split_deg() */
1881
+ rb_define_const(rb_mSwisseph, "SE_SPLIT_DEG_ROUND_SEC", INT2FIX(SE_SPLIT_DEG_ROUND_SEC));
1882
+ rb_define_const(rb_mSwisseph, "SE_SPLIT_DEG_ROUND_MIN", INT2FIX(SE_SPLIT_DEG_ROUND_MIN));
1883
+ rb_define_const(rb_mSwisseph, "SE_SPLIT_DEG_ROUND_DEG", INT2FIX(SE_SPLIT_DEG_ROUND_DEG));
1884
+ rb_define_const(rb_mSwisseph, "SE_SPLIT_DEG_ZODIACAL", INT2FIX(SE_SPLIT_DEG_ZODIACAL));
1885
+ rb_define_const(rb_mSwisseph, "SE_SPLIT_DEG_NAKSHATRA", INT2FIX(SE_SPLIT_DEG_NAKSHATRA));
1886
+ rb_define_const(rb_mSwisseph, "SE_SPLIT_DEG_KEEP_SIGN", INT2FIX(SE_SPLIT_DEG_KEEP_SIGN));
1887
+ rb_define_const(rb_mSwisseph, "SE_SPLIT_DEG_KEEP_DEG", INT2FIX(SE_SPLIT_DEG_KEEP_DEG));
1888
+
1889
+ /* for eclipse functions */
1890
+ rb_define_const(rb_mSwisseph, "SE_ECL_CENTRAL", INT2FIX(SE_ECL_CENTRAL));
1891
+ rb_define_const(rb_mSwisseph, "SE_ECL_NONCENTRAL", INT2FIX(SE_ECL_NONCENTRAL));
1892
+ rb_define_const(rb_mSwisseph, "SE_ECL_TOTAL", INT2FIX(SE_ECL_TOTAL));
1893
+ rb_define_const(rb_mSwisseph, "SE_ECL_ANNULAR", INT2FIX(SE_ECL_ANNULAR));
1894
+ rb_define_const(rb_mSwisseph, "SE_ECL_PARTIAL", INT2FIX(SE_ECL_PARTIAL));
1895
+ rb_define_const(rb_mSwisseph, "SE_ECL_ANNULAR_TOTAL", INT2FIX(SE_ECL_ANNULAR_TOTAL));
1896
+ rb_define_const(rb_mSwisseph, "SE_ECL_HYBRID", INT2FIX(SE_ECL_HYBRID));
1897
+ rb_define_const(rb_mSwisseph, "SE_ECL_PENUMBRAL", INT2FIX(SE_ECL_PENUMBRAL));
1898
+ rb_define_const(rb_mSwisseph, "SE_ECL_ALLTYPES_SOLAR", INT2FIX(SE_ECL_ALLTYPES_SOLAR));
1899
+ rb_define_const(rb_mSwisseph, "SE_ECL_ALLTYPES_LUNAR", INT2FIX(SE_ECL_ALLTYPES_LUNAR));
1900
+ rb_define_const(rb_mSwisseph, "SE_ECL_VISIBLE", INT2FIX(SE_ECL_VISIBLE));
1901
+ rb_define_const(rb_mSwisseph, "SE_ECL_MAX_VISIBLE", INT2FIX(SE_ECL_MAX_VISIBLE));
1902
+ rb_define_const(rb_mSwisseph, "SE_ECL_1ST_VISIBLE", INT2FIX(SE_ECL_1ST_VISIBLE));
1903
+ rb_define_const(rb_mSwisseph, "SE_ECL_2ND_VISIBLE", INT2FIX(SE_ECL_2ND_VISIBLE));
1904
+ rb_define_const(rb_mSwisseph, "SE_ECL_3RD_VISIBLE", INT2FIX(SE_ECL_3RD_VISIBLE));
1905
+ rb_define_const(rb_mSwisseph, "SE_ECL_4TH_VISIBLE", INT2FIX(SE_ECL_4TH_VISIBLE));
1906
+ rb_define_const(rb_mSwisseph, "SE_ECL_ONE_TRY", INT2FIX(SE_ECL_ONE_TRY));
1907
+
1908
+ /* for heliacal functions */
1909
+ rb_define_const(rb_mSwisseph, "SE_HELIACAL_RISING", INT2FIX(SE_HELIACAL_RISING));
1910
+ rb_define_const(rb_mSwisseph, "SE_HELIACAL_SETTING", INT2FIX(SE_HELIACAL_SETTING));
1911
+ rb_define_const(rb_mSwisseph, "SE_MORNING_FIRST", INT2FIX(SE_MORNING_FIRST));
1912
+ rb_define_const(rb_mSwisseph, "SE_EVENING_LAST", INT2FIX(SE_EVENING_LAST));
1913
+ rb_define_const(rb_mSwisseph, "SE_EVENING_FIRST", INT2FIX(SE_EVENING_FIRST));
1914
+ rb_define_const(rb_mSwisseph, "SE_MORNING_LAST", INT2FIX(SE_MORNING_LAST));
1915
+ rb_define_const(rb_mSwisseph, "SE_HELFLAG_LONG_SEARCH", INT2FIX(SE_HELFLAG_LONG_SEARCH));
1916
+ rb_define_const(rb_mSwisseph, "SE_HELFLAG_HIGH_PRECISION", INT2FIX(SE_HELFLAG_HIGH_PRECISION));
1917
+ rb_define_const(rb_mSwisseph, "SE_HELFLAG_OPTICAL_PARAMS", INT2FIX(SE_HELFLAG_OPTICAL_PARAMS));
1918
+ rb_define_const(rb_mSwisseph, "SE_HELFLAG_NO_DETAILS", INT2FIX(SE_HELFLAG_NO_DETAILS));
1919
+ }