home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Astrolog (Version 4.00) File: options.c
- **
- ** IMPORTANT NOTICE: the graphics database and chart display routines
- ** used in this program are Copyright (C) 1991-1993 by Walter D. Pullen
- ** (cruiser1@stein.u.washington.edu). Permission is granted to freely
- ** use and distribute these routines provided one doesn't sell,
- ** restrict, or profit from them in any way. Modification is allowed
- ** provided these notices remain with any altered or edited versions of
- ** the program.
- **
- ** The main planetary calculation routines used in this program have
- ** been Copyrighted and the core of this program is basically a
- ** conversion to C of the routines created by James Neely as listed in
- ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
- ** available from Matrix Software. The copyright gives us permission to
- ** use the routines for personal use but not to sell them or profit from
- ** them in any way.
- **
- ** The PostScript code within the core graphics routines are programmed
- ** and Copyright (C) 1992-1993 by Brian D. Willoughby
- ** (brianw@sounds.wa.com). Conditions are identical to those above.
- **
- ** The extended accurate ephemeris databases and formulas are from the
- ** calculation routines in the program "Placalc" and are programmed and
- ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
- ** (alois@azur.ch). The use of that source code is subject to
- ** regulations made by Astrodienst Zurich, and the code is not in the
- ** public domain. This copyright notice must not be changed or removed
- ** by any user of this program.
- **
- ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
- ** X Window graphics initially programmed 10/23-29/1991.
- ** PostScript graphics initially programmed 11/29-30/1992.
- ** Last code change made 12/31/1993.
- */
-
- #include "astrolog.h"
-
-
- /*
- ******************************************************************************
- ** Display Subroutines.
- ******************************************************************************
- */
-
- /* This is a subprocedure of CreateGrid() and CreateGridRelation(). Given */
- /* two planets, determine what aspect, if any, is present between them, */
- /* and save the aspect name and orb in the specified grid cell. */
-
- void GetAspect(planet1, planet2, ret1, ret2, i, j)
- real *planet1, *planet2, *ret1, *ret2;
- int i, j;
- {
- int k;
- real l, m;
-
- grid->v[i][j] = grid->n[i][j] = 0;
- l = MinDistance(planet2[i], planet1[j]);
- for (k = aspects; k >= 1; k--) {
- m = l-aspectangle[k];
- if (dabs(m) < Orb(i, j, k)) {
- grid->n[i][j] = k;
-
- /* If -ga switch in effect, then change the sign of the orb to */
- /* correspond to whether the aspect is applying or separating. */
- /* To do this, we check the velocity vectors to see if the */
- /* planets are moving toward, away, or are overtaking each other. */
-
- if (exdisplay & DASHga)
- m = SGN2(ret1[j]-ret2[i])*
- SGN2(MinDifference(planet2[i], planet1[j]))*SGN2(m)*dabs(m);
- grid->v[i][j] = (int) (m*60.0);
- }
- }
- }
-
-
- /* Set up the aspect/midpoint grid. Allocate memory for this array, if not */
- /* already done. Allocation is only done once, first time this is called. */
-
- bool EnsureGrid()
- {
- char string[STRING];
-
- if (grid != NULL)
- return TRUE;
- Allocate(grid, sizeof(gridstruct), gridstruct PTR);
- if (grid == NULL
- #ifdef PC
- /* For PC's the grid better not cross a segment boundary. */
- || HIWORD(LOWORD(grid) + sizeof(gridstruct)) > 0
- #endif
- ) {
- sprintf(string, "Not enough memory for grid (%d bytes).",
- sizeof(gridstruct));
- PrintError(string);
- return FALSE;
- }
- return TRUE;
- }
-
-
- /* Fill in the aspect grid based on the aspects taking place among the */
- /* planets in the present chart. Also fill in the midpoint grid. */
-
- void CreateGrid(acc)
- int acc;
- {
- int i, j, k;
- real l;
-
- if (!EnsureGrid())
- return;
- for (j = 1; j <= total; j++) if (!ignore[j])
- for (i = 1; i <= total; i++) if (!ignore[i])
-
- /* The parameter 'acc' determine what half of the grid is filled in */
- /* with the aspects and what half is filled in with the midpoints. */
-
- if (acc ? i > j : i < j)
- GetAspect(planet, planet, ret, ret, i, j);
- else if (acc ? i < j : i > j) {
- l = Mod(Midpoint(planet[i], planet[j])); k = (int)l; /* Calculate */
- grid->n[i][j] = k/30+1; /* midpoint. */
- grid->v[i][j] = (int)((l-(real)(k/30)*30.0)*60.0);
- } else {
- grid->n[i][j] = ZTOS(planet[j]);
- grid->v[i][j] = (int)(planet[j]-(real)(grid->n[i][j]-1)*30.0);
- }
- }
-
-
- /* This is similar to the previous function; however, this time fill in the */
- /* grid based on the aspects (or midpoints if 'acc' set) taking place among */
- /* the planets in two different charts, as in the -g -r0 combination. */
-
- void CreateGridRelation(acc)
- int acc;
- {
- int i, j, k;
- real l;
-
- if (!EnsureGrid())
- return;
- for (j = 1; j <= total; j++) if (!ignore[j])
- for (i = 1; i <= total; i++) if (!ignore[i])
- if (!acc)
- GetAspect(planet1, planet2, ret1, ret2, i, j);
- else {
- l = Mod(Midpoint(planet2[i], planet1[j])); k = (int)l; /* Calculate */
- grid->n[i][j] = k/30+1; /* midpoint. */
- grid->v[i][j] = (int)((l-(real)(k/30)*30.0)*60.0);
- }
- }
-
-
- /*
- ******************************************************************************
- ** Multiple Chart Display Subprograms.
- ******************************************************************************
- */
-
- /* Print out an aspect (or midpoint if -g0 switch in effect) grid of a */
- /* relationship chart. This is similar to the ChartGrid() routine; however, */
- /* here we have both axes labeled with the planets for the two charts in */
- /* question, instead of just a diagonal down the center for only one chart. */
-
- void DisplayGridRelation()
- {
- int i, j, k, tot = total, temp;
-
- #ifdef INTERPRET
- if (interpret && !(exdisplay & DASHg0)) {
- InterpretGridRelation();
- return;
- }
- #endif
- fprintf(S, " 2>");
- for (temp = 0, i = 1; i <= total; i++) if (!ignore[i]) {
- printc(BOXV);
- AnsiColor(objectansi[i]);
- fprintf(S, "%c%c%c", OBJNAM(i));
- AnsiColor(DEFAULT);
- temp++;
- if (column80 && temp >= 19) {
- tot = i;
- i = total;
- }
- }
- fprintf(S, "\n1 ");
- for (i = 1; i <= tot; i++) if (!ignore[i]) {
- printc(BOXV);
- AnsiColor(signansi(ZTOS(planet2[i])));
- fprintf(S, "%2d%c", (int)planet2[i] % 30, DEGR2);
- AnsiColor(DEFAULT);
- }
- fprintf(S, "\nV ");
- for (i = 1; i <= tot; i++) if (!ignore[i]) {
- printc(BOXV);
- temp = ZTOS(planet2[i]);
- AnsiColor(signansi(temp));
- fprintf(S, "%c%c%c", SIGNAM(temp));
- AnsiColor(DEFAULT);
- }
- printl();
- for (j = 1; j <= total; j++) if (!ignore[j])
- for (k = 1; k <= 4; k++) {
- if (k < 2)
- PrintTab(BOXH, 3);
- else if (k == 2) {
- AnsiColor(objectansi[j]);
- fprintf(S, "%c%c%c", OBJNAM(j));
- } else {
- temp = ZTOS(planet1[j]);
- AnsiColor(signansi(temp));
- if (k == 3)
- fprintf(S, "%2d%c", (int)planet1[j] - (temp-1)*30, DEGR2);
- else
- fprintf(S, "%c%c%c", SIGNAM(temp));
- }
- if (k > 1)
- AnsiColor(DEFAULT);
- for (i = 1; i <= tot; i++) if (!ignore[i]) {
- printc(k < 2 ? BOXC : BOXV);
- temp = grid->n[i][j];
- if (k > 1) {
- if (i == j)
- AnsiColor(REVERSE);
- AnsiColor(exdisplay & DASHg0 ? signansi(temp) :
- aspectansi[temp]);
- }
- if (k < 2)
- PrintTab(BOXH, 3);
- else if (k == 2) {
- if (exdisplay & DASHg0)
- fprintf(S, "%c%c%c", SIGNAM(temp));
- else
- fprintf(S, "%s", temp ? aspectabbrev[temp] : " ");
- } else if (k == 3) {
- if (exdisplay & DASHg0)
- fprintf(S, "%2d%c", grid->v[i][j]/60, DEGR2);
- else
- if (grid->n[i][j]) {
- if (grid->v[i][j] < 600)
- fprintf(S, "%c%2d", exdisplay & DASHga ?
- (grid->v[i][j] < 0 ? 'a' : 's') :
- (grid->v[i][j] < 0 ? '-' : '+'), abs(grid->v[i][j])/60);
- else
- fprintf(S, "%3d", abs(temp)/60);
- } else
- fprintf(S, " ");
- } else {
- if (grid->n[i][j])
- fprintf(S, "%02d'", abs(grid->v[i][j])%60);
- else
- fprintf(S, " ");
- }
- AnsiColor(DEFAULT);
- }
- printl();
- }
- }
-
-
- /* Display all aspects between objects in the relationship comparison chart, */
- /* one per line, in sorted order based on the total "power" of the aspects, */
- /* as specified with the -r0 -m0 switch combination. */
-
- void DisplayAspectRelation()
- {
- int pcut = 30000, icut, jcut, phi, ihi, jhi, ahi, p, i, j, k, count = 0;
- real ip, jp;
-
- loop {
- phi = -1;
-
- /* Search for the next most powerful aspect in the aspect grid. */
-
- for (i = 1; i <= total; i++) if (!ignore[i])
- for (j = 1; j <= total; j++) if (!ignore[j])
- if (k = grid->n[i][j]) {
- ip = i <= OBJECTS ? objectinf[i] : 2.5;
- jp = j <= OBJECTS ? objectinf[j] : 2.5;
- p = (int) (aspectinf[k]*(ip+jp)/2.0*
- (1.0-dabs((real)(grid->v[i][j]))/60.0/aspectorb[k])*1000.0);
- if ((p < pcut || (p == pcut && (i > icut ||
- (i == icut && j > jcut)))) && p > phi) {
- ihi = i; jhi = j; phi = p; ahi = k;
- }
- }
- if (phi < 0) /* Exit when no less powerful aspect found. */
- break;
- pcut = phi; icut = ihi; jcut = jhi;
- count++; /* Display the current aspect. */
- #ifdef INTERPRET
- if (interpret) { /* Interpret it if -I in effect. */
- InterpretAspectRelation(jhi, ihi);
- continue;
- }
- #endif
- fprintf(S, "%3d: ", count);
- PrintAspect(jhi, ZTOS(planet1[jhi]), (int)Sgn(ret1[jhi]), ahi,
- ihi, ZTOS(planet2[ihi]), (int)Sgn(ret2[ihi]), 'A');
- k = grid->v[ihi][jhi];
- AnsiColor(k < 0 ? WHITE : LTGRAY);
- fprintf(S, "- orb: %c%d,%02d'",
- exdisplay & DASHga ? (k < 0 ? 'a' : 's') : (k < 0 ? '-' : '+'),
- abs(k)/60, abs(k)%60);
- AnsiColor(DKGREEN);
- fprintf(S, " - power:%6.2f\n", (real) phi/1000.0);
- AnsiColor(DEFAULT);
- }
- }
-
-
- /* Display locations of all midpoints between objects in the relationship */
- /* comparison chart, one per line, in sorted zodiac order from zero Aries */
- /* onward, as specified with the -r0 -m switch combination. */
-
- void DisplayMidpointRelation()
- {
- int mcut = -1, icut, jcut, mlo, ilo, jlo, m, i, j, count = 0;
-
- loop {
- mlo = 21600;
-
- /* Search for the next closest midpoint farther down in the zodiac. */
-
- for (i = 1; i <= total; i++) if (!ignore[i])
- for (j = 1; j <= total; j++) if (!ignore[j]) {
- m = (grid->n[j][i]-1)*30*60 + grid->v[j][i];
- if ((m > mcut || (m == mcut && (i > icut ||
- (i == icut && j > jcut)))) && m < mlo) {
- ilo = i; jlo = j; mlo = m;
- }
- }
- if (mlo >= 21600) /* Exit when no midpoint farther in zodiac found. */
- break;
- mcut = mlo; icut = ilo; jcut = jlo;
- count++; /* Display the current midpoint. */
- #ifdef INTERPRET
- if (interpret) { /* Interpret it if -I in effect. */
- InterpretMidpointRelation(ilo, jlo);
- continue;
- }
- #endif
- fprintf(S, "%4d: ", count);
- PrintZodiac((real) mlo/60.0);
- printc(' ');
- PrintAspect(ilo, ZTOS(planet1[ilo]), (int)Sgn(ret1[ilo]), 0,
- jlo, ZTOS(planet2[jlo]), (int)Sgn(ret2[jlo]), 'M');
- AnsiColor(DEFAULT);
- fprintf(S, "-%4d degree span.\n",
- (int)MinDistance(planet1[ilo], planet2[jlo]));
- }
- }
-
-
- /* Calculate any of the various kinds of relationship charts. This involves */
- /* reading in and storing the planet and house positions for both charts, */
- /* and then combining them in the main single chart in the proper manner. */
- /* If the parameter 'var' is set, then we read the info for the two charts */
- /* from files, otherwise use the info in preset "core" and "second" charts. */
-
- void CastRelation(var)
- int var;
- {
- int mon, day, yea, i;
- real tim, zon, lon, lat, t1, t2, t;
-
- /* Read in and cast the first chart. */
-
- if (var)
- InputData(filename);
- mon = MM; day = DD; yea = YY; tim = TT; zon = ZZ; lon = OO; lat = AA;
- if (var) {
- SetTwin(MM, DD, YY, TT, ZZ, OO, AA);
- } else {
- SetCore(Mon2, Day2, Yea2, Tim2, Zon2, Lon2, Lat2);
- }
- t1 = CastChart(TRUE);
- for (i = 1; i <= SIGNS; i++) {
- house1[i] = house[i];
- inhouse1[i] = inhouse[i];
- }
- for (i = 1; i <= total; i++) {
- planet1[i] = planet[i];
- planetalt1[i] = planetalt[i];
- ret1[i] = ret[i];
- }
-
- /* Read in the second chart. */
-
- if (var) {
- InputData(filename2);
- if (relation == DASHrp) {
- progress = TRUE;
- Jdp = (real)MdyToJulian(MM, DD, YY) + TT / 24.0;
- SetCore(mon, day, yea, tim, zon, lon, lat);
- }
- } else {
- SetCore(mon, day, yea, tim, zon, lon, lat);
- }
- SetMain(MM, DD, YY, TT, ZZ, OO, AA);
- t2 = CastChart(TRUE);
- for (i = 1; i <= SIGNS; i++) {
- house2[i] = house[i];
- inhouse2[i] = inhouse[i];
- }
- for (i = 1; i <= total; i++) {
- planet2[i] = planet[i];
- planetalt2[i] = planetalt[i];
- ret2[i] = ret[i];
- }
-
- /* Now combine the two charts based on what relation we are doing. */
- /* For the standard -r synastry chart, use the house cusps of chart1 */
- /* and the planets positions of chart2. */
-
- if (relation <= DASHr)
- for (i = 1; i <= SIGNS; i++)
- house[i] = house1[i];
-
- /* For the -rc composite chart, take the midpoints of the planets/houses. */
-
- else if (relation == DASHrc) {
- for (i = 1; i <= total; i++) {
- planet[i] = Midpoint(planet1[i], planet2[i]);
- planetalt[i] = (planetalt1[i]+planetalt2[i])/2.0;
- ret[i] = (ret1[i]+ret2[i])/2.0;
- }
- for (i = 1; i <= SIGNS; i++)
- house[i] = Midpoint(house1[i], house2[i]);
-
- /* Make sure we don't have any 180 degree errors in house cusp */
- /* complement pairs, which may happen if the cusps are far apart. */
-
- for (i = 1; i <= SIGNS; i++)
- if (MinDistance(house[_CAP], Mod(house[i]-STOZ(i+3))) > DEGQUAD)
- house[i] = Mod(house[i]+DEGHALF);
-
- /* For the -rm time space midpoint chart, calculate the midpoint time and */
- /* place between the two charts and then recast for the new chart info. */
-
- } else if (relation == DASHrm) {
- T = (t1+t2)/2.0;
- t = (T*36525.0)+ROUND; JD = floor(t)+2415020.0; TT = FRACT(t)*24.0;
- ZZ = (DecToDeg(zon)+DecToDeg(Zon))/2.0; ZZ = DegToDec(ZZ);
- TT = DecToDeg(TT)-DecToDeg(ZZ); TT = DegToDec(TT);
- if (TT < 0.0) {
- TT = DecToDeg(TT)+24.0; TT = DegToDec(TT); JD -= 1.0;
- }
- JulianToMdy(JD, &MM, &DD, &YY);
- OO = (DecToDeg(lon)+DecToDeg(Lon))/2.0;
- if (dabs(Lon-lon) > DEGHALF)
- OO = Mod(OO+DEGHALF);
- OO = DegToDec(OO);
- AA = (DecToDeg(lat)+DecToDeg(Lat))/2.0; AA = DegToDec(AA);
- SetMain(MM, DD, YY, TT, ZZ, OO, AA);
- CastChart(FALSE);
-
- /* There are a couple of non-astrological charts, which only require the */
- /* number of days that have passed between the two charts to be done. */
-
- } else
- JD = dabs(t2-t1)*36525.0;
- HousePlace();
- }
-
-
- /* Given two objects and an aspect between them, or an object and a sign */
- /* that it's entering, print if this is a "major" event, such as a season */
- /* change or major lunar phase. This is called from the DisplayInDay */
- /* searching and influence routines. Go an interpretation if need be too. */
-
- void PrintInDay(source, aspect, dest)
- int source, aspect, dest;
- {
- if (aspect == _SIG) {
- if (source == _SUN) {
- AnsiColor(WHITE);
- if (dest == 1)
- fprintf(S, " (Vernal Equinox)"); /* If the Sun changes sign, */
- else if (dest == 4) /* then print out if this */
- fprintf(S, " (Summer Solstice)"); /* is a season change. */
- else if (dest == 7)
- fprintf(S, " (Autumnal Equinox)");
- else if (dest == 10)
- fprintf(S, " (Winter Solstice)");
- }
- } else if (aspect > 0) {
- if (source == _SUN && dest == _MOO) {
- if (aspect <= _SQU)
- AnsiColor(WHITE);
- if (aspect == _CON)
- fprintf(S, " (New Moon)"); /* Print out if the present */
- else if (aspect == _OPP) /* aspect is a New, Full, */
- fprintf(S, " (Full Moon)"); /* or Half Moon. */
- else if (aspect == _SQU)
- fprintf(S, " (Half Moon)");
- }
- }
- printl();
-
- #ifdef INTERPRET
- if (interpret)
- InterpretInDay(source, aspect, dest);
- #endif
- AnsiColor(DEFAULT);
- }
-
-
- /* Given two objects and an aspect (or one object, and an event such as a */
- /* sign or direction change) display the configuration in question. This */
- /* is called by the many charts which list aspects among items, such as */
- /* the -m0 aspect lists, -m midpoint lists, -d aspect in day search and */
- /* influence charts, and -t transit search and influence charts. */
-
- void PrintAspect(obj1, sign1, ret1, asp, obj2, sign2, ret2, chart)
- int obj1, sign1, ret1, asp, obj2, sign2, ret2;
- char chart;
- {
- int smart, a, s2;
-
- smart = smartcusp && IsCusp(obj2) && asp == _OPP;
- a = smart ? _CON : asp;
- s2 = smart ? sign1 : sign2;
-
- AnsiColor(objectansi[obj1]);
- if (chart == 't' || chart == 'T')
- fprintf(S, "trans ");
- else if (chart == 'e' || chart == 'u' || chart == 'U')
- fprintf(S, "progr ");
- fprintf(S, "%7.7s", objectname[obj1]);
- AnsiColor(signansi(sign1));
- fprintf(S, " %c%c%c%c%c",
- ret1 > 0 ? '(' : (ret1 < 0 ? '[' : '<'), SIGNAM(sign1),
- ret1 > 0 ? ')' : (ret1 < 0 ? ']' : '>'));
- AnsiColor(a > 0 ? aspectansi[a] : WHITE);
- printc(' ');
- if (a == _SIG)
- fprintf(S, "-->"); /* Print a sign change. */
- else if (a == _DIR)
- fprintf(S, "S/%c", obj2 ? 'R' : 'D'); /* Print a direction change. */
- else if (a == 0)
- printf(chart == 'm' ? "&" : "with");
- else
- fprintf(S, "%s", aspectabbrev[a]); /* Print an aspect. */
- printc(' ');
- if (chart == 'A')
- fprintf(S, "with ");
- if (a == _SIG) {
- AnsiColor(signansi(obj2));
- fprintf(S, "%s", signname[obj2]);
- } else if (a >= 0) {
- AnsiColor(signansi(s2));
- if (chart == 't' || chart == 'u' || chart == 'T' || chart == 'U')
- fprintf(S, "natal ");
- fprintf(S, "%c%c%c%c%c ",
- ret2 > 0 ? '(' : (ret2 < 0 ? '[' : '<'), SIGNAM(s2),
- ret2 > 0 ? ')' : (ret2 < 0 ? ']' : '>'));
- AnsiColor(smart ? signansi((obj2-15) - (obj2 < 23)) : objectansi[obj2]);
- if (smart) {
- fprintf(S, "%dth cusp", (obj2-15) - (obj2 < 23));
- if (obj2 < 23)
- printc(' ');
- } else
- fprintf(S, "%.10s", objectname[obj2]);
- }
- if (chart == 'D' || chart == 'T' || chart == 'U' ||
- chart == 'a' || chart == 'A' || chart == 'm' || chart == 'M')
- PrintTab(' ', 10-StringLen(objectname[obj2]));
- }
-
-
- /* Search through a day, and print out the times of exact aspects among the */
- /* planets during that day, as specified with the -d switch, as well as the */
- /* times when a planet changes sign or direction. To do this, we cast charts */
- /* for the beginning and end of the day, or a part of a day, and do a linear */
- /* equation check to see if anything exciting happens during the interval. */
- /* (This is probably the single most complicated procedure in the program.) */
-
- void DisplayInDaySearch(prog)
- int prog;
- {
- int time[MAXINDAY], source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY],
- sign1[MAXINDAY], sign2[MAXINDAY], D1, D2, occurcount, division, div,
- i, j, k, l, s1, s2;
- real divsiz, d1, d2, e1, e2, f1, f2, g;
-
- /* If parameter 'prog' is set, look for changes in a progressed chart. */
-
- division = prog ? 1 : divisions;
- divsiz = 24.0/ (real) division*60.0;
-
- /* If -dm in effect, then search through the whole month, day by day. */
-
- if (exdisplay & DASHdm) {
- D1 = 1;
- if (prog && Mon2 == 0) {
- Mon2 = 1; D2 = DayInYear(Yea2);
- } else
- D2 = DayInMonth(prog ? Mon2 : Mon, prog ? Yea2 : Yea);
- } else
- D1 = D2 = Day;
-
- /* Start searching the day or days in question for exciting stuff. */
-
- for (Day2 = D1; Day2 <= D2; Day2++) {
- occurcount = 0;
-
- /* Cast chart for beginning of day and store it for future use. */
-
- SetCore(Mon, Day2, Yea, 0.0, Zon, Lon, Lat);
- if (progress = prog) {
- Jdp = (real)MdyToJulian(Mon2, DD, Yea2);
- SetCore(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- }
- CastChart(TRUE);
- for (i = 1; i <= SIGNS; i++) {
- house2[i] = house[i];
- inhouse2[i] = inhouse[i];
- }
- for (i = 1; i <= total; i++) {
- planet2[i] = planet[i];
- ret2[i] = ret[i];
- }
-
- /* Now divide the day into segments and search each segment in turn. */
- /* More segments is slower, but has slightly better time accuracy. */
-
- for (div = 1; div <= division; div++) {
-
- /* Cast the chart for the ending time of the present segment. The */
- /* beginning time chart is copied from the previous end time chart. */
-
- SetCore(Mon, Day2, Yea,
- DegToDec(24.0*(real)div/(real)division), Zon, Lon, Lat);
- if (prog) {
- Jdp = (real)MdyToJulian(Mon2, DD+1, Yea2);
- SetCore(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- }
- CastChart(TRUE);
- for (i = 1; i <= SIGNS; i++) {
- house1[i] = house2[i]; inhouse1[i] = inhouse2[i];
- house2[i] = house[i]; inhouse2[i] = inhouse[i];
- }
- for (i = 1; i <= total; i++) {
- planet1[i] = planet2[i]; ret1[i] = ret2[i];
- planet2[i] = planet[i]; ret2[i] = ret[i];
- }
-
- /* Now search through the present segment for anything exciting. */
-
- for (i = 1; i <= total; i++) if (!ignore[i] && (prog || IsThing(i))) {
- s1 = ZTOS(planet1[i])-1;
- s2 = ZTOS(planet2[i])-1;
-
- /* Does the current planet change into the next or previous sign? */
-
- if (!ignore[i] && s1 != s2 && !ignore[0]) {
- source[occurcount] = i;
- aspect[occurcount] = _SIG;
- dest[occurcount] = s2+1;
- time[occurcount] = (int) (MinDistance(planet1[i],
- (real) (ret1[i] >= 0.0 ? s2 : s1) * 30.0) /
- MinDistance(planet1[i], planet2[i])*divsiz) +
- (int) ((real) (div-1)*divsiz);
- sign1[occurcount] = sign2[occurcount] = s1+1;
- occurcount++;
- }
-
- /* Does the current planet go retrograde or direct? */
-
- if (!ignore[i] && (ret1[i] < 0.0) != (ret2[i] < 0.0) && !ignore2[0]) {
- source[occurcount] = i;
- aspect[occurcount] = _DIR;
- dest[occurcount] = ret2[i] < 0.0;
- time[occurcount] = (int) (dabs(ret1[i])/(dabs(ret1[i])+dabs(ret2[i]))
- *divsiz) + (int) ((real) (div-1)*divsiz);
- sign1[occurcount] = sign2[occurcount] = s1+1;
- occurcount++;
- }
-
- /* Now search for anything making an aspect to the current planet. */
-
- for (j = i+1; j <= total; j++) if (!ignore[j] && (prog || IsThing(j)))
- for (k = 1; k <= aspects; k++) {
- d1 = planet1[i]; d2 = planet2[i];
- e1 = planet1[j]; e2 = planet2[j];
- if (MinDistance(d1, d2) < MinDistance(e1, e2)) {
- SwapReal(&d1, &e1);
- SwapReal(&d2, &e2);
- }
-
- /* We are searching each aspect in turn. Let's subtract the */
- /* size of the aspect from the angular difference, so we can */
- /* then treat it like a conjunction. */
-
- if (MinDistance(e1, Mod(d1-aspectangle[k])) <
- MinDistance(e2, Mod(d2+aspectangle[k]))) {
- e1 = Mod(e1+aspectangle[k]);
- e2 = Mod(e2+aspectangle[k]);
- } else {
- e1 = Mod(e1-aspectangle[k]);
- e2 = Mod(e2-aspectangle[k]);
- }
-
- /* Check to see if the aspect actually occurs during our */
- /* segment, making sure we take into account if one or both */
- /* planets are retrograde or if they cross the Aries point. */
-
- f1 = e1-d1;
- if (dabs(f1) > DEGHALF)
- f1 -= Sgn(f1)*DEGREES;
- f2 = e2-d2;
- if (dabs(f2) > DEGHALF)
- f2 -= Sgn(f2)*DEGREES;
- if (MinDistance(Midpoint(d1, d2), Midpoint(e1, e2)) < DEGQUAD &&
- Sgn(f1) != Sgn(f2)) {
- source[occurcount] = i;
- aspect[occurcount] = k;
- dest[occurcount] = j;
-
- /* Horray! The aspect occurs sometime during the interval. */
- /* Now we just have to solve an equation in two variables to */
- /* find out where the "lines" cross, i.e. the aspect's time. */
-
- f1 = d2-d1;
- if (dabs(f1) > DEGHALF)
- f1 -= Sgn(f1)*DEGREES;
- f2 = e2-e1;
- if (dabs(f2) > DEGHALF)
- f2 -= Sgn(f2)*DEGREES;
- g = (dabs(d1-e1) > DEGHALF ?
- (d1-e1)-Sgn(d1-e1)*DEGREES : d1-e1)/(f2-f1);
- time[occurcount] = (int) (g*divsiz) +
- (int) ((real) (div-1)*divsiz);
- sign1[occurcount] = (int) (Mod(planet1[i]+
- Sgn(planet2[i]-planet1[i])*
- (dabs(planet2[i]-planet1[i]) > DEGHALF ? -1 : 1)*
- dabs(g)*MinDistance(planet1[i], planet2[i]))/30.0)+1;
- sign2[occurcount] = (int) (Mod(planet1[j]+
- Sgn(planet2[j]-planet1[j])*
- (dabs(planet2[j]-planet1[j]) > DEGHALF ? -1 : 1)*
- dabs(g)*MinDistance(planet1[j], planet2[j]))/30.0)+1;
- occurcount++;
- }
- }
- }
- }
-
- /* After all the aspects, etc, in the day have been located, sort */
- /* them by time at which they occur, so we can print them in order. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && time[j] > time[j+1]) {
- SWAP(source[j], source[j+1]);
- SWAP(aspect[j], aspect[j+1]);
- SWAP(dest[j], dest[j+1]);
- SWAP(time[j], time[j+1]);
- SWAP(sign1[j], sign1[j+1]); SWAP(sign2[j], sign2[j+1]);
- j--;
- }
- }
-
- /* Finally, loop through and display each aspect and when it occurs. */
-
- for (i = 0; i < occurcount; i++) {
- s1 = time[i]/60;
- s2 = time[i]-s1*60;
- j = Day2;
- if (prog) {
- l = Mon2;
- while (j > (k = DayInMonth(l, Yea2))) {
- j -= k;
- l++;
- }
- }
- SetSave(prog ? l : Mon, j, prog ? Yea2 : Yea,
- DegToDec((real)time[i] / 60.0), Zon, Lon, Lat);
- k = DayOfWeek(prog ? l : Mon, j, prog ? Yea2 : Yea);
- AnsiColor(rainbowansi[k + 1]);
- fprintf(S, "(%c%c%c) ", DAYNAM(k));
- AnsiColor(DEFAULT);
- fprintf(S, "%s %s ",
- CharDate(prog ? l : Mon, j, prog ? Yea2 : Yea, FALSE),
- CharTime(s1, s2));
- PrintAspect(source[i], sign1[i],
- (int)Sgn(ret1[source[i]])+(int)Sgn(ret2[source[i]]),
- aspect[i], dest[i], sign2[i],
- (int)Sgn(ret1[dest[i]])+(int)Sgn(ret2[dest[i]]), prog ? 'e' : 'd');
- PrintInDay(source[i], aspect[i], dest[i]);
- }
- }
- }
-
-
- /* Based on the given chart information, display all the aspects taking */
- /* place in the chart, as specified with the -D switch. The aspects are */
- /* printed in order of influence determined by treating them as happening */
- /* outside among transiting planets, such that rare outer planet aspects */
- /* are given more power than common ones among inner planets. (This is */
- /* almost identical to the -m0 list, except the influences are different.) */
-
- void DisplayInDayInfluence()
- {
- int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY];
- real power[MAXINDAY];
- int occurcount = 0, i, j, k, l, m;
-
- /* Go compute the aspects in the chart. */
-
- i = exdisplay;
- exdisplay |= DASHga; /* We always want applying vs. separating orbs. */
- CreateGrid(FALSE);
- exdisplay = i;
-
- /* Search through the grid and build up the list of aspects. */
-
- for (j = 2; j <= total; j++) {
- if (ignore[j])
- continue;
- for (i = 1; i < j; i++) {
- if (ignore[i] || (k = grid->n[i][j]) == 0 || occurcount >= MAXINDAY)
- continue;
- if (smartcusp && k > _OPP && IsCusp(j))
- continue;
- source[occurcount] = i; aspect[occurcount] = k; dest[occurcount] = j;
- l = grid->v[i][j];
- power[occurcount] =
- ((i <= BASE ? transitinf[i] : 2.0)/4.0)*
- ((j <= BASE ? transitinf[j] : 2.0)/4.0)*
- aspectinf[k]*(1.0-(real)abs(l)/60.0/Orb(i, j, k));
- occurcount++;
- }
- }
-
- /* Sort aspects by order of influence. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && power[j] < power[j+1]) {
- SWAP(source[j], source[j+1]);
- SWAP(aspect[j], aspect[j+1]);
- SWAP(dest[j], dest[j+1]);
- SwapReal(&power[j], &power[j+1]);
- j--;
- }
- }
-
- /* Now display each aspect line. */
-
- for (i = 0; i < occurcount; i++) {
- fprintf(S, "%3d: ", i+1);
- j = source[i]; k = aspect[i]; l = dest[i];
- PrintAspect(
- j, ZTOS(planet[j]), (int)Sgn(ret[j]), k,
- l, ZTOS(planet[l]), (int)Sgn(ret[l]), 'D');
- m = grid->v[j][l];
- AnsiColor(m < 0 ? WHITE : LTGRAY);
- fprintf(S, "- %s%2d%c%02d'", m < 0 ? "app" : "sep",
- abs(m)/60, DEGR1, abs(m)%60);
- AnsiColor(DKGREEN);
- fprintf(S, " - power:%6.2f", power[i]);
- PrintInDay(j, k, l);
- }
- }
-
-
- /* Search through a month, and print out the times of exact transits where */
- /* planets in the time frame make aspect to the planets in some other chart, */
- /* as specified with the -t switch. To do this, we cast charts for the start */
- /* and end of the month, or part of the month, and do an equation check for */
- /* aspects to the other base chart during the interval. */
-
- void DisplayTransitSearch(prog)
- int prog;
- {
- real planet3[TOTAL+1], house3[SIGNS+1], ret3[TOTAL+1];
- uint time[MAXINDAY];
- int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY], sign[MAXINDAY],
- isret[MAXINDAY], M1, M2, occurcount, div, i, j, k, s1, s2, s3;
- real divsiz, daysiz, d, e1, e2, f1, f2;
-
- for (i = 1; i <= SIGNS; i++)
- house3[i] = house[i];
- for (i = 1; i <= total; i++) {
- planet3[i] = planet[i];
- ret3[i] = ret[i];
- }
- if (Mon2 == 0) { /* Searching month number zero means to search */
- M1 = 1; M2 = 12; /* the whole year instead, month by month. */
- } else
- M1 = M2 = Mon2;
-
- /* Start searching the month or months in question for any transits. */
-
- for (Mon2 = M1; Mon2 <= M2; Mon2++) {
- daysiz = (real) DayInMonth(Mon2, Yea2)*24.0*60.0;
- divsiz = daysiz/ (real) divisions;
-
- /* Cast chart for beginning of month and store it for future use. */
-
- SetCore(Mon2, 1, Yea2, 0.0, Zon2, Lon2, Lat2);
- if (progress = prog) {
- Jdp = (real)MdyToJulian(MM, DD, YY);
- SetCore(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- }
- CastChart(TRUE);
- for (i = 1; i <= SIGNS; i++)
- house2[i] = house[i];
- for (i = 1; i <= OBJECTS; i++) {
- planet2[i] = planet[i];
- ret2[i] = ret[i];
- }
-
- /* Divide our month into segments and then search each segment in turn. */
-
- for (div = 1; div <= divisions; div++) {
- occurcount = 0;
-
- /* Cast the chart for the ending time of the present segment, and */
- /* copy the start time chart from the previous end time chart. */
-
- d = 1.0 + (daysiz/24.0/60.0)*(real)div/(real)divisions;
- SetCore(Mon2, (int)d, Yea2,
- DegToDec(FRACT(d)*24.0), Zon2, Lon2, Lat2);
- if (prog) {
- Jdp = (real)MdyToJulian(MM, DD, YY);
- SetCore(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- }
- CastChart(TRUE);
- for (i = 1; i <= SIGNS; i++) {
- house1[i] = house2[i]; house2[i] = house[i];
- }
- for (i = 1; i <= OBJECTS; i++) {
- planet1[i] = planet2[i]; ret1[i] = ret2[i];
- planet2[i] = planet[i]; ret2[i] = ret[i];
- }
-
- /* Now search through the present segment for any transits. Note that */
- /* stars can be transited, but they can't make transits themselves. */
-
- for (i = 1; i <= total; i++) if (!ignore[i])
- for (j = 1; j <= BASE; j++) if (!ignore2[j] && (prog || IsThing(j)))
-
- /* Between each pair of planets, check if they make any aspects. */
-
- for (k = 1; k <= aspects; k++) {
- d = planet3[i]; e1 = planet1[j]; e2 = planet2[j];
- if (MinDistance(e1, Mod(d-aspectangle[k])) <
- MinDistance(e2, Mod(d+aspectangle[k]))) {
- e1 = Mod(e1+aspectangle[k]);
- e2 = Mod(e2+aspectangle[k]);
- } else {
- e1 = Mod(e1-aspectangle[k]);
- e2 = Mod(e2-aspectangle[k]);
- }
-
- /* Check to see if the present aspect actually occurs during the */
- /* segment, making sure we check any Aries point crossings. */
-
- f1 = e1-d;
- if (dabs(f1) > DEGHALF)
- f1 -= Sgn(f1)*DEGREES;
- f2 = e2-d;
- if (dabs(f2) > DEGHALF)
- f2 -= Sgn(f2)*DEGREES;
- if (MinDistance(d, Midpoint(e1, e2)) < DEGQUAD &&
- Sgn(f1) != Sgn(f2) && occurcount < MAXINDAY) {
-
- /* Ok, we have found a transit. Now determine the time */
- /* and save this transit in our list to be printed. */
-
- source[occurcount] = j;
- aspect[occurcount] = k;
- dest[occurcount] = i;
- time[occurcount] = (int) (dabs(f1)/(dabs(f1)+dabs(f2))*divsiz) +
- (int) ((real) (div-1)*divsiz);
- sign[occurcount] = (int) (Mod(
- MinDistance(planet1[j], Mod(d-aspectangle[k])) <
- MinDistance(planet2[j], Mod(d+aspectangle[k])) ?
- d-aspectangle[k] : d+aspectangle[k])/30.0)+1;
- isret[occurcount] = (int)Sgn(ret1[j]) + (int)Sgn(ret2[j]);
- occurcount++;
- }
- }
-
- /* After all transits located, sort them by time at which they occur. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && time[j] > time[j+1]) {
- SWAP(source[j], source[j+1]);
- SWAP(aspect[j], aspect[j+1]);
- SWAP(dest[j], dest[j+1]);
- SWAP(time[j], time[j+1]);
- SWAP(sign[j], sign[j+1]);
- SWAP(isret[j], isret[j+1]);
- j--;
- }
- }
-
- /* Now loop through list and display all the transits. */
-
- for (i = 0; i < occurcount; i++) {
- k = smartcusp && IsCusp(dest[i]);
- if (k && aspect[i] > _OPP)
- continue;
- else
- k = k && aspect[i] == _OPP;
- s1 = time[i]/24/60;
- s3 = time[i]-s1*24*60;
- s2 = s3/60;
- s3 = s3-s2*60;
- SetSave(Mon2, s1+1, Yea2,
- DegToDec((real)(time[i]-s1*24*60) / 60.0), Zon2, Lon2, Lat2);
- fprintf(S, "%s %s ",
- CharDate(Mon2, s1+1, Yea2, FALSE), CharTime(s2, s3));
- PrintAspect(source[i], sign[i], isret[i], aspect[i],
- dest[i], ZTOS(planet3[dest[i]]), (int)Sgn(ret3[dest[i]]),
- prog ? 'u' : 't');
-
- /* Check for a Solar, Lunar, or any other return. */
-
- if (aspect[i] == _CON && source[i] == dest[i]) {
- AnsiColor(WHITE);
- fprintf(S, " (%s Return)", source[i] == _SUN ? "Solar" :
- (source[i] == _MOO ? "Lunar" : objectname[source[i]]));
- }
- printl();
- #ifdef INTERPRET
- if (interpret)
- InterpretTransit(source[i], aspect[i], dest[i]);
- #endif
- AnsiColor(DEFAULT);
- }
- }
- }
- }
-
-
- /* Given an arbitrary day, determine what aspects are made between this */
- /* transiting chart and the given natal chart, as specified with the -T */
- /* switch, and display the transits in order sorted by influence. */
-
- void DisplayTransitInfluence(prog)
- int prog;
- {
- int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY];
- real power[MAXINDAY];
- byte ignore3[TOTAL+1];
- int occurcount = 0, i, j, k, l, m;
-
- /* Cast the natal and transiting charts as with a relationship chart. */
-
- for (i = 1; i <= SIGNS; i++)
- house1[i] = house[i];
- for (i = 1; i <= total; i++) {
- planet1[i] = planet[i];
- ret1[i] = ret[i];
- }
- SetCore(Mon2, Day2, Yea2, Tim2, Zon2, Lon2, Lat2);
- if (progress = prog) {
- Jdp = (real)MdyToJulian(MM, DD, YY);
- MM = Mon; DD = Day; YY = Yea;
- }
- CastChart(TRUE);
- for (i = 1; i <= SIGNS; i++)
- house2[i] = house[i];
- for (i = 1; i <= total; i++) {
- planet2[i] = planet[i];
- ret2[i] = ret[i];
- }
-
- /* Do a relationship aspect grid to get the transits. We have to make and */
- /* restore three changes to get it right for this chart. (1) We make the */
- /* natal planets have zero velocity so applying vs. separating is only a */
- /* function of the transiter. (2) We force applying vs. separating orbs */
- /* regardless if -ga or -ma is in effect or not. (3) Finally we tweak the */
- /* main restrictions to allow for transiting objects not restricted. */
-
- for (i = 1; i <= total; i++) {
- ret[i] = ret1[i];
- ret1[i] = 0.0;
- ignore3[i] = ignore[i];
- ignore[i] = ignore[i] && ignore2[i];
- }
- i = exdisplay;
- exdisplay |= DASHga;
- CreateGridRelation(FALSE);
- exdisplay = i;
- for (i = 1; i <= total; i++) {
- ret1[i] = ret[i];
- ignore[i] = ignore3[i];
- }
-
- /* Loop through the grid, and build up a list of the valid transits. */
-
- for (i = 1; i <= BASE; i++) {
- if (ignore2[i] || !IsThing(i))
- continue;
- for (j = 1; j <= total; j++) {
- if (ignore[j] || (k = grid->n[i][j]) == 0 || occurcount >= MAXINDAY)
- continue;
- if (smartcusp && k > _OPP && IsCusp(j))
- continue;
- source[occurcount] = i; aspect[occurcount] = k; dest[occurcount] = j;
- l = grid->v[i][j];
- power[occurcount] = transitinf[i]*
- ((j <= BASE ? objectinf[j] : 2.0)/4.0)*aspectinf[k]*
- (1.0-(real)abs(l)/60.0/Orb(i, j, k));
- occurcount++;
- }
- }
-
- /* After all transits located, sort them by their total power. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && power[j] < power[j+1]) {
- SWAP(source[j], source[j+1]);
- SWAP(aspect[j], aspect[j+1]);
- SWAP(dest[j], dest[j+1]);
- SwapReal(&power[j], &power[j+1]);
- j--;
- }
- }
-
- /* Now loop through list and display each transit in effect at the time. */
-
- for (i = 0; i < occurcount; i++) {
- k = aspect[i];
- l = source[i];
- fprintf(S, "%3d: ", i+1);
- j = ZTOS(planet2[l]);
- PrintAspect(l, j, (int)Sgn(ret2[l]), k,
- dest[i], ZTOS(planet1[dest[i]]), (int)Sgn(ret1[dest[i]]),
- prog ? 'U' : 'T');
- m = grid->v[l][dest[i]];
- AnsiColor(m < 0 ? WHITE : LTGRAY);
- fprintf(S, "- %s%2d%c%02d'", m < 0 ? "app" : "sep",
- abs(m)/60, DEGR1, abs(m)%60);
- AnsiColor(DKGREEN);
- fprintf(S, " - power:%6.2f", power[i]);
- if (k == _CON && l == dest[i]) { /* Print a small "R" for returns. */
- AnsiColor(WHITE);
- fprintf(S, " R");
- }
- printl();
- #ifdef INTERPRET
- if (interpret)
- InterpretTransit(l, k, dest[i]);
- #endif
- AnsiColor(DEFAULT);
- }
- }
-
-
- /* Given the zodiac location of a planet in the sky and its declination, */
- /* and a location on the Earth, compute the azimuth and altitude of where */
- /* on the local horizon sky the planet would appear to one at the given */
- /* location. A reference MC position at Greenwich is also needed for this. */
-
- void EclToHorizon(azi, alt, planet, planetalt, lon, lat, mc)
- real *azi, *alt, planet, planetalt, lon, lat, mc;
- {
- real lonz, latz;
-
- lonz = DTOR(planet); latz = DTOR(planetalt);
- EclToEqu(&lonz, &latz);
- lonz = DTOR(Mod(RTOD(mc-lonz+lon)));
- lonz = DTOR(Mod(RTOD(lonz-lon+PI/2.0)));
- EquToLocal(&lonz, &latz, PI/2.0-lat);
- *azi = DEGREES-RTOD(lonz); *alt = RTOD(latz);
- }
-
-
- /* Display a list of planetary rising times relative to the local horizon */
- /* for the day indicated in the chart information, as specified with the */
- /* -Zd switch. For the day, the time each planet rises (transits horizon */
- /* in East half of sky), sets (transits horizon in West), reaches its */
- /* zenith point (transits meridian in South half of sky), and nadirs */
- /* transits meridian in North), is displayed. */
-
- void DisplayInDayHorizon()
- {
- int source[MAXINDAY], type[MAXINDAY], time[MAXINDAY], sign[MAXINDAY],
- isret[MAXINDAY], occurcount, division, div, s1, s2, i, j;
- real planetalt1[TOTAL+1], planetalt2[TOTAL+1], azialt[MAXINDAY],
- divsiz, lon, lat, mc1, mc2, azi1, alt1, azi2, alt2, d, k;
-
- lon = DTOR(Mod(Lon)); lat = DTOR(Lat);
- division = divisions * 4;
- divsiz = 24.0/ (real) division*60.0;
- occurcount = 0;
-
- SetCore(Mon, Day, Yea, 0.0, Zon, Lon, Lat);
- CastChart(TRUE);
- mc2 = DTOR(planet[_MC]); k = DTOR(planetalt[_MC]);
- EclToEqu(&mc2, &k);
- for (i = 1; i <= SIGNS; i++) {
- house2[i] = house[i];
- inhouse2[i] = inhouse[i];
- }
- for (i = 1; i <= total; i++) {
- planet2[i] = planet[i];
- planetalt2[i] = planetalt[i];
- ret2[i] = ret[i];
- }
-
- /* Loop thorough the day, dividing it into a certain number of segments. */
- /* For each segment we get the planet positions at its endpoints. */
-
- for (div = 1; div <= division; div++) {
- SetCore(Mon, Day, Yea,
- DegToDec(24.0*(real)div/(real)division), Zon, Lon, Lat);
- CastChart(TRUE);
- mc1 = mc2;
- mc2 = DTOR(planet[_MC]); k = DTOR(planetalt[_MC]);
- EclToEqu(&mc2, &k);
- for (i = 1; i <= SIGNS; i++) {
- house1[i] = house2[i]; inhouse1[i] = inhouse2[i];
- house2[i] = house[i]; inhouse2[i] = inhouse[i];
- }
- for (i = 1; i <= total; i++) {
- planet1[i] = planet2[i]; planet2[i] = planet[i];
- planetalt1[i] = planetalt2[i]; planetalt2[i] = planetalt[i];
- ret1[i] = ret2[i]; ret2[i] = ret[i];
- }
-
- /* For our segment, check to see if each planet during it rises, sets, */
- /* reaches its zenith, or reaches its nadir. */
-
- for (i = 1; i <= total; i++) if (!ignore[i] && IsThing(i)) {
- EclToHorizon(&azi1, &alt1, planet1[i], planetalt1[i], lon, lat, mc1);
- EclToHorizon(&azi2, &alt2, planet2[i], planetalt2[i], lon, lat, mc2);
- j = 0;
- /* Check for transits to the horizon. */
- if ((alt1 > 0.0) != (alt2 > 0.0)) {
- d = dabs(alt1)/(dabs(alt1)+dabs(alt2));
- k = Mod(azi1 + d*MinDifference(azi1, azi2));
- j = 1 + 2*(MinDistance(k, DEGHALF) < DEGQUAD);
- /* Check for transits to the meridian. */
- } else if (Sgn(MinDifference(azi1, DEGQUAD)) !=
- Sgn(MinDifference(azi2, DEGQUAD))) {
- j = 2 + 2*(MinDistance(azi1, DEGQUAD) < DEGQUAD);
- d = dabs(azi1 - (j > 2 ? DEGQUAD : 270.0))/MinDistance(azi1, azi2);
- k = alt1 + d*(alt2-alt1);
- }
- if (j && occurcount < MAXINDAY) {
- source[occurcount] = i;
- type[occurcount] = j;
- time[occurcount] = (int)(24.0*((real)(div-1)+d)/(real)division*60.0);
- sign[occurcount] = (int)Mod(planet1[i] +
- d*MinDifference(planet1[i], planet2[i]))/30 + 1;
- isret[occurcount] = (int)Sgn(ret1[i]) + (int)Sgn(ret2[i]);
- azialt[occurcount] = k;
- SetSave(Mon, Day, Yea, DegToDec((real)time[occurcount] / 60.0),
- Zon, Lon, Lat);
- occurcount++;
- }
- }
- }
-
- /* Sort each event in order of time when it happens during the day. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && time[j] > time[j+1]) {
- SWAP(source[j], source[j+1]);
- SWAP(type[j], type[j+1]);
- SWAP(time[j], time[j+1]);
- SWAP(sign[j], sign[j+1]);
- SWAP(isret[j], isret[j+1]);
- SwapReal(&azialt[j], &azialt[j+1]);
- j--;
- }
- }
-
- /* Finally display the list showing each event and when it occurs. */
-
- for (i = 0; i < occurcount; i++) {
- SetSave(Mon, Day, Yea,
- DegToDec((real)time[i] / 60.0), Zon, Lon, Lat);
- j = DayOfWeek(Mon, Day, Yea);
- AnsiColor(rainbowansi[j + 1]);
- fprintf(S, "(%c%c%c) ", DAYNAM(j));
- AnsiColor(DEFAULT);
- s1 = time[i]/60;
- s2 = time[i]-s1*60;
- fprintf(S, "%s %s ", CharDate(Mon, Day, Yea, FALSE), CharTime(s1, s2));
- AnsiColor(objectansi[source[i]]);
- fprintf(S, "%7.7s ", objectname[source[i]]);
- AnsiColor(signansi(sign[i]));
- fprintf(S, "%c%c%c%c%c ",
- isret[i] > 0 ? '(' : (isret[i] < 0 ? '[' : '<'), SIGNAM(sign[i]),
- isret[i] > 0 ? ')' : (isret[i] < 0 ? ']' : '>'));
- AnsiColor(elemansi[type[i]-1]);
- if (type[i] == 1)
- fprintf(S, "rises ");
- else if (type[i] == 2)
- fprintf(S, "zeniths");
- else if (type[i] == 3)
- fprintf(S, "sets ");
- else
- fprintf(S, "nadirs ");
- AnsiColor(DEFAULT);
- fprintf(S, " at ");
- if (type[i] & 1) {
- j = (int) (FRACT(azialt[i])*60.0);
- fprintf(S, "%3d%c%02d'", (int) azialt[i], DEGR1, j);
-
- /* For rising and setting events, we'll also display a direction */
- /* vector to make the 360 degree azimuth value thought of easier. */
-
- azi1 = cos(DTOR(azialt[i])); alt1 = sin(DTOR(azialt[i]));
- if (dabs(azi1) < dabs(alt1)) {
- azi2 = dabs(azi1 / alt1); alt2 = 1.0;
- } else {
- alt2 = dabs(alt1 / azi1); azi2 = 1.0;
- }
- fprintf(S, " (%.2f%c %.2f%c)",
- alt2, alt1 < 0.0 ? 's' : 'n', azi2, azi1 > 0.0 ? 'e' : 'w');
- } else
- PrintAltitude(azialt[i]);
- printl();
- }
- }
-
-
- /* Print out an ephemeris - the positions of the planets (at the time in the */
- /* current chart) each day during a specified month, as done with the -E */
- /* switch. Display the ephemeris for the whole year if -Ey is in effect. */
-
- void DisplayEphemeris()
- {
- int M0, M1, M2, daysiz, i, j, k, s, d, m;
-
- /* If -Ey is in effect, then loop through all months in the whole year. */
-
- if (exdisplay & DASHEy) {
- M1 = 1; M2 = 12;
- } else
- M1 = M2 = Mon;
-
- /* Loop through the month or months in question, printing each ephemeris. */
-
- for (M0 = M1; M0 <= M2; M0++) {
- daysiz = DayInMonth(M0, Yea);
- printf(eurodate ? "Dy/Mo/Yr" : "Mo/Dy/Yr");
- for (k = 0, j = 1; j <= total; j++) {
- if (!ignore[j] && IsThing(j)) {
- fprintf(S, " %c%c%c%c ", OBJNAM(j), objectname[j][3] != 0 ?
- objectname[j][3] : ' ');
- k++;
- if (column80 && k >= 10)
- j = total;
- }
- }
- printl();
- for (i = 1; i <= daysiz; i++) {
-
- /* Loop through each day in the month, casting a chart for that day. */
-
- SetCore(M0, i, Yea, Tim, Zon, Lon, Lat);
- CastChart(TRUE);
- fprintf(S, "%s ", CharDate(M0, i, Yea, -1));
- for (k = 0, j = 1; j <= total; j++)
- if (!ignore[j] && IsThing(j)) {
- AnsiColor(objectansi[j]);
- s = ZTOS(planet[j]);
- d = (int) planet[j] - (s-1)*30;
- m = (int) (FRACT(planet[j])*60.0);
- fprintf(S, "%2d%s%02d%c", d, signabbrev[s], m,
- ret[j] >= 0.0 ? ' ' : '.');
- k++;
- if (column80 && k >= 10)
- j = total;
- }
- printl();
- AnsiColor(DEFAULT);
- }
- if (M0 < M2)
- printl();
- }
- }
-
-
- /* Display a calendar for the given month in the chart, as specified with */
- /* with the -K switch. When color is on, the title is white, weekends are */
- /* highlighted in red, and the specific day in the chart is colored green. */
-
- void DisplayCalendarMonth()
- {
- int i, j, k;
-
- AnsiColor(WHITE);
- PrintTab(' ', 16-StringLen(monthname[Mon]) >> 1);
- fprintf(S, "%s%5d\n", monthname[Mon], Yea);
- for (i = 0; i < 7; i++)
- fprintf(S, "%c%c%c", dayname[i][0], dayname[i][1], i < 6 ? ' ' : '\n');
- j = DayOfWeek(Mon, 1, Yea);
- AnsiColor(DEFAULT);
- for (i = 0; i < j; i++) {
- if (i == 0)
- AnsiColor(RED);
- fprintf(S, "-- ");
- if (i == 0)
- AnsiColor(DEFAULT);
- }
- k = DayInMonth(Mon, Yea);
- for (i = 1; i <= k; i++) {
- if (i == (int)Day)
- AnsiColor(GREEN);
- else if (j == 0 || j == 6)
- AnsiColor(RED);
- fprintf(S, "%2d", i);
- if (j == 0 || j == 6 || i == Day)
- AnsiColor(DEFAULT);
- if (j < 6) {
- j++;
- printc(' ');
- } else {
- j = 0;
- printl();
- }
- }
- while (j > 0 && j < 7) {
- if (j == 6)
- AnsiColor(RED);
- j++;
- fprintf(S, "--%c", j < 7 ? ' ' : '\n');
- }
- AnsiColor(DEFAULT);
- }
-
-
- /* Display a calendar for the entire year given in the chart, as specified */
- /* with the -Ky switch. This is just like twelve of the individual month */
- /* calendars above displayed together, with same color highlights and all. */
-
- void DisplayCalendarYear()
- {
- int r, w, c, m, d, dy, p[3], l[3], n[3];
-
- dy = DayOfWeek(1, 1, Yea);
- for (r = 0; r < 4; r++) { /* Loop over one set of three months */
- AnsiColor(WHITE);
- for (c = 0; c < 3; c++) {
- m = r*3+c+1;
- PrintTab(' ', 16-StringLen(monthname[m]) >> 1);
- fprintf(S, "%s%5d", monthname[m], Yea);
- if (c < 2)
- PrintTab(' ', 20 + MONTHSPACE -
- (16-StringLen(monthname[m]) >> 1) - StringLen(monthname[m]) - 5);
- }
- printl();
- for (c = 0; c < 3; c++) {
- for (d = 0; d < 7; d++)
- fprintf(S, "%c%c%c", dayname[d][0], dayname[d][1],
- d < 6 || c < 2 ? ' ' : '\n');
- if (c < 2)
- PrintTab(' ', MONTHSPACE-1);
- m = r*3+c+1;
- p[c] = dy % 7;
- l[c] = DayInMonth(m, Yea);
- n[c] = 0;
- dy += l[c];
- }
- for (w = 0; w < 6; w++) { /* Loop over one set of week rows */
- for (c = 0; c < 3; c++) { /* Loop over one week in a month */
- m = r*3+c+1;
- d = 0;
- if (w == 0)
- while (d < p[c]) {
- if (d == 0)
- AnsiColor(RED);
- fprintf(S, "-- ");
- if (d == 0)
- AnsiColor(DEFAULT);
- d++;
- }
- AnsiColor(DEFAULT);
- while (d < 7 && n[c] < l[c]) {
- n[c]++;
- if (n[c] == Day && m == Mon)
- AnsiColor(GREEN);
- else if (d == 0 || d == 6)
- AnsiColor(RED);
- fprintf(S, "%2d%c", n[c], d < 6 || c < 2 ? ' ' : '\n');
- if (d == 0 || d == 6 || (n[c] == Day && m == Mon))
- AnsiColor(DEFAULT);
- d++;
- }
- while (d < 7) {
- if (d == 0 || d == 6)
- AnsiColor(RED);
- fprintf(S, "--%c", d < 6 || c < 2 ? ' ' : '\n');
- if (d == 0)
- AnsiColor(DEFAULT);
- d++;
- }
- if (c < 2)
- PrintTab(' ', MONTHSPACE-1);
- }
- }
- if (r < 3)
- printl();
- }
- AnsiColor(DEFAULT);
- }
-
-
- /* Display either a biorhythm chart or the time difference in various units */
- /* between two charts, i.e. two types of relationship "charts" that aren't */
- /* related in any way to planetary positions, as specified by either the */
- /* -rb or -rd switches, respectively. */
-
- void DisplayRelation()
- {
- #ifdef BIORHYTHM
- int i, j;
- real k, l;
- #endif
-
- /* If we are calculating the difference between two dates, then display */
- /* the value and return, as with the -rd switch. */
-
- if (relation == DASHrd) {
- fprintf(S, "Differences between the dates in the two charts:\n");
- AnsiColor(rainbowansi[1]); fprintf(S, "Years : %.0f\n", JD/365.25);
- AnsiColor(rainbowansi[2]); fprintf(S, "Months : %.0f\n", JD/(365.25/12));
- AnsiColor(rainbowansi[3]); fprintf(S, "Weeks : %.0f\n", JD/7.0);
- AnsiColor(rainbowansi[4]); fprintf(S, "Days : %.0f\n", JD);
- AnsiColor(rainbowansi[5]); fprintf(S, "Hours : %.0f\n", JD*24.0);
- AnsiColor(rainbowansi[6]); fprintf(S, "Minutes: %.0f\n", JD*24.0*60.0);
- AnsiColor(rainbowansi[7]); fprintf(S, "Seconds: %.0f\n", JD*24.0*3600.0);
- AnsiColor(DEFAULT);
- return;
- }
-
- #ifdef BIORHYTHM
- /* If we are doing a biorhythm (-rb switch), then we'll calculate it for */
- /* someone born on the older date, at the time of the younger date. Loop */
- /* through the week preceeding and following the date in question. */
-
- JD = floor(JD + ROUND);
- for (JD -= 7.0, i = -7; i <= 7; i++, JD += 1.0) {
- if (i == 0)
- AnsiColor(WHITE);
- else if (i == 1)
- AnsiColor(DEFAULT);
- fprintf(S, "T%c%d Day%c:",
- i < 0 ? '-' : '+', abs(i), abs(i) != 1 ? 's' : ' ');
- for (j = 1; j <= 3; j++) {
- printc(' ');
- switch (j) {
- case 1: k = _PHY; AnsiColor(RED); fprintf(S, "Physical"); break;
- case 2: k = _EMO; AnsiColor(BLUE); fprintf(S, "Emotional"); break;
- case 3: k = _INT; AnsiColor(GREEN); fprintf(S, "Intellectual"); break;
- }
- AnsiColor(i ? DEFAULT : WHITE);
-
- /* The biorhythm calculation is below. */
-
- l = Biorhythm(JD, k);
- fprintf(S, " at %c%3.0f%%", l < 0.0 ? '-' : '+', dabs(l));
-
- /* Print smiley face, medium face, or sad face based on current cycle. */
-
- AnsiColor(PURPLE);
- fprintf(S, " :%c", l > 50.0 ? ')' : (l < -50.0 ? '(' : '|'));
- AnsiColor(i ? DEFAULT : WHITE);
- if (j < 3)
- printc(',');
- }
- printl();
- }
- #endif /* BIORHYTHM */
- }
-
-
- /* Another important procedure: Display any of the types of (text) charts */
- /* that the user specified they wanted, by calling the appropriate routines. */
-
- void PrintChart(prog)
- {
- if (todisplay == 0) /* Assume the -v chart if user */
- todisplay |= DASHv; /* didn't indicate anything. */
- if (todisplay & DASHv) {
- if (relation < DASHrd)
- ChartLocation();
- else
-
- /* If the -rb or -rd relationship charts are in effect, then instead */
- /* of doing the standard -v chart, print either of these chart types. */
-
- DisplayRelation();
- if (todisplay - (todisplay & DASHv*2-1))
- printl2();
- }
- if (todisplay & DASHw) {
- ChartWheel();
- if (todisplay - (todisplay & DASHw*2-1))
- printl2();
- }
- if (todisplay & DASHg) {
- if (relation > DASHr0) {
- CreateGrid(FALSE);
- ChartGrid();
- if (exdisplay & DASHg0) { /* If -g0 switch in effect, then */
- printl(); /* display aspect configurations. */
- DisplayGrands();
- }
- } else {
-
- /* Do a relationship aspect grid between two charts if -r0 in effect. */
-
- CreateGridRelation((exdisplay & DASHg0) > 0);
- DisplayGridRelation();
- }
- if (todisplay - (todisplay & DASHg*2-1))
- printl2();
- }
- if (todisplay & DASHm) {
- if (!(todisplay & DASHg) || relation <= DASHr0)
- CreateGrid(FALSE);
- if (relation > DASHr0) {
- if (exdisplay & DASHm0)
- ChartAspect();
- else
- ChartMidpoint();
- if (todisplay - (todisplay & DASHm*2-1))
- printl2();
- } else {
- CreateGridRelation((exdisplay & DASHm0) == 0);
- if (exdisplay & DASHm0)
- DisplayAspectRelation();
- else
- DisplayMidpointRelation();
- }
- }
- if (todisplay & DASHZ) {
- if (exdisplay & DASHZd)
- DisplayInDayHorizon();
- else
- ChartHorizon();
- if (todisplay - (todisplay & DASHZ*2-1))
- printl2();
- }
- if (todisplay & DASHS) {
- ChartSpace();
- if (todisplay - (todisplay & DASHS*2-1))
- printl2();
- }
- if (todisplay & DASHj) {
- ChartInfluence();
- if (todisplay - (todisplay & DASHj*2-1))
- printl2();
- }
- if (todisplay & DASHL) {
- ChartAstroGraph();
- if (todisplay - (todisplay & DASHL*2-1))
- printl2();
- }
- if (todisplay & DASHK) {
- if (exdisplay & DASHKy)
- DisplayCalendarYear();
- else
- DisplayCalendarMonth();
- if (todisplay - (todisplay & DASHK*2-1))
- printl2();
- }
- if (todisplay & DASHd) {
- DisplayInDaySearch(prog);
- if (todisplay - (todisplay & DASHd*2-1))
- printl2();
- }
- if (todisplay & DASHD) {
- DisplayInDayInfluence();
- if (todisplay - (todisplay & DASHD*2-1))
- printl2();
- }
- if (todisplay & DASHE) {
- DisplayEphemeris();
- if (todisplay - (todisplay & DASHE*2-1))
- printl2();
- }
- if (todisplay & DASHt) {
- DisplayTransitSearch(prog);
- if (todisplay - (todisplay & DASHt*2-1))
- printl2();
- }
- if (todisplay & DASHT)
- DisplayTransitInfluence(prog);
- }
-
- /* options.c */
-