home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Astrolog (Version 4.00) File: charts.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"
-
-
- /*
- ******************************************************************************
- ** Single Chart Display Subprograms.
- ******************************************************************************
- */
-
- /* Fill out tables based on the number of unrestricted planets in signs by */
- /* element, signs by mode, as well as other values such as the number of */
- /* objects in yang vs. yin signs, in various house hemispheres (north/south */
- /* and east/west), and the number in first six signs vs. second six signs. */
- /* This is used by the -v chart listing and the sidebar in graphics charts. */
-
- void CreateElemTable(elemode, elem, mo, tot, pos, abo, lef, lea)
- int elemode[4][3], *elem, *mo, *tot, *pos, *abo, *lef, *lea;
- {
- int i, j;
-
- *tot = *pos = *abo = *lef = *lea = 0; /* Initialize arrays */
- for (i = 0; i < 4; i++) /* and variables to zero */
- elem[i] = 0;
- for (j = 0; j < 3; j++)
- mo[j] = 0;
- for (i = 0; i < 4; i++)
- for (j = 0; j < 3; j++)
- elemode[i][j] = 0;
-
- /* Calculate number of objects in each element, mode, hemisphere, etc. */
-
- for (i = 1; i <= total; i++) if (!ignore[i]) {
- (*tot)++;
- j = ZTOS(planet[i]);
- elemode[(j-1)&3][(j-1)%3]++;
- elem[(j-1)&3]++; mo[(j-1)%3]++;
- *pos += (j & 1);
- *lea += (j < _LIB);
- j = inhouse[i];
- *abo += (j >= _LIB);
- *lef += (j < _CAN || j >= _CAP);
- }
- }
-
-
- /* Print the straight listing of planet and house positions and specified */
- /* by the -v switch, along with the element table, etc. */
-
- void ChartLocation()
- {
- int elemode[4][3], elem[4], mo[3], pos, abo, lef, lea;
- int count, i, j, k;
-
- CreateElemTable(elemode, elem, mo, &count, &pos, &abo, &lef, &lea);
-
- /* Print header showing time and date of the chart being displayed. */
-
- AnsiColor(WHITE);
- fprintf(S, "%s %s chart ", appname, VERSION);
- if (Mon == -1)
- fprintf(S, "(no time or space)\n");
- else if (relation == DASHrc)
- fprintf(S, "(composite)\n");
- else {
- i = (int) (FRACT(dabs(Tim))*100.0+ROUND);
- j = (int) (FRACT(dabs(Zon))*100.0+ROUND);
- fprintf(S, "for %s %s",
- CharDate(Mon, Day, Yea, TRUE), CharTime((int)Tim, i));
- fprintf(S, " (%c%.0f:%02d GMT) ",
- Zon > 0.0 ? '-' : '+', dabs(Zon), j);
- fprintf(S, "%s\n", CharLocation(Lon, Lat, 100.0));
- }
-
- #ifdef INTERPRET
- if (interpret) { /* Print an interpretation if -I in effect. */
- if (relation == DASHr)
- InterpretSynastry(); /* Print synastry interpretaion for -r -I. */
- else
- InterpretLocation(); /* Do normal interpretation for just -v -I. */
- return;
- }
- #endif
- AnsiColor(DEFAULT);
- fprintf(S, "Body Locat. Ret. Decl. Rul. House Rul. Veloc. ");
- fprintf(S, "%s Houses.\n\n", systemname[housesystem]);
-
- /* Ok, now print out each location of each object. */
-
- for (i = 1, j = 1; i <= BASE; i++, j++) {
- if (i > OBJECTS && (i <= C_HI || ignore[i]))
- continue;
- while (i <= OBJECTS && j <= OBJECTS && ignore[j])
- j++;
- if (i <= OBJECTS && j > OBJECTS)
- PrintTab(' ', 51);
- else {
- if (i > OBJECTS)
- j = i;
- AnsiColor(objectansi[j]);
- fprintf(S, "%-4.4s: ", objectname[j]);
- PrintZodiac(planet[j]);
- fprintf(S, " %c ", ret[j] >= 0.0 ? ' ' : 'R');
- if (j <= THINGS || j > OBJECTS)
- PrintAltitude(planetalt[i]);
- else
- fprintf(S, "_______");
- fprintf(S, " (%c)", Dignify(j, ZTOS(planet[i])));
- k = inhouse[j];
- AnsiColor(signansi(k));
- fprintf(S, " [%2d%c%c house]", k, post[k][0], post[k][1]);
- AnsiColor(DEFAULT);
- fprintf(S, " [%c] ", Dignify(j, k));
- if ((j != _MOO || placalc) && (IsObject(j) || (j == _NOD && placalc)))
- fprintf(S, RTOD(dabs(ret[j])) < 10.0 ? "%c%5.3f" : "%c%5.2f",
- ret[i] < 0.0 ? '-' : '+', RTOD(dabs(ret[j])));
- else
- fprintf(S, "______");
- }
-
- /* For some lines, we have to append the house cusp positions. */
-
- if (i <= SIGNS) {
- fprintf(S, " - ");
- AnsiColor(signansi(i));
- fprintf(S, "House cusp %2d: ", i);
- PrintZodiac(house[i]);
- }
-
- /* For some lines, we have to append the element table information. */
-
- if (i == SIGNS+2)
- fprintf(S, " Car Fix Mut TOT");
- else if (i > SIGNS+2 && i < SIGNS+7) {
- k = i-(SIGNS+2)-1;
- AnsiColor(elemansi[k]);
- fprintf(S, " %c%c%c%3d %3d %3d %3d",
- element[k][0], element[k][1], element[k][2],
- elemode[k][0], elemode[k][1], elemode[k][2], elem[k]);
- AnsiColor(DEFAULT);
- } else if (i == SIGNS+7)
- fprintf(S, " TOT %2d %3d %3d %3d", mo[0], mo[1], mo[2], count);
- else if (i == OBJECTS)
- PrintTab(' ', 23);
- else if (i >= U_LO)
- fprintf(S, " Uranian #%d", i-U_LO+1);
- switch (i-SIGNS-1) {
- case 1: fprintf(S, " +:%2d", pos); break;
- case 2: fprintf(S, " -:%2d", count-pos); break;
- case 3: fprintf(S, " M:%2d", abo); break;
- case 4: fprintf(S, " N:%2d", count-abo); break;
- case 5: fprintf(S, " A:%2d", lef); break;
- case 6: fprintf(S, " D:%2d", count-lef); break;
- case 7: fprintf(S, "<:%2d", lea); break;
- }
- printl();
- }
-
- /* Do another loop to print out the stars in their specified order. */
-
- if (universe) for (i = S_LO; i <= S_HI; i++) if (!ignore[i]) {
- j = BASE+starname[i-BASE];
- AnsiColor(objectansi[j]);
- fprintf(S, "%.4s: ", objectname[j]);
- PrintZodiac(planet[j]);
- fprintf(S, " ");
- PrintAltitude(planetalt[j]);
- k = inhouse[j];
- AnsiColor(signansi(k));
- fprintf(S, " [%2d%c%c house]", k, post[k][0], post[k][1]);
- AnsiColor(DEFAULT);
- fprintf(S, " ______ Star #%2d: %5.2f\n", i-BASE, starbright[j-BASE]);
- }
- }
-
-
- /* Print out the aspect and midpoint grid for a chart, as specified with the */
- /* -g switch. (Each grid row takes up 4 lines of text.) */
-
- void ChartGrid()
- {
- int x, y, r, x1, y1, temp;
-
- #ifdef INTERPRET
- if (interpret) { /* Print interpretation instead if -I in effect. */
- InterpretGrid();
- return;
- }
- #endif
-
- for (y1 = 0, y = 1; y <= total; y++) if (!ignore[y])
- for (r = 1; r <= 4; r++) {
- for (x1 = 0, x = 1; x <= total; x++) if (!ignore[x]) {
- if (y1 > 0 && x1 > 0 && y+r > 2)
- printc(r > 1 ? BOXV : BOXC);
- if (r > 1) {
- temp = grid->n[x][y];
-
- /* Print aspect rows. */
-
- if (x < y) {
- if (temp);
- AnsiColor(aspectansi[temp]);
- if (r == 2)
- fprintf(S, "%s", temp ? aspectabbrev[temp] : " ");
- else if (!temp)
- fprintf(S, " ");
- else {
- if (r == 3) {
- if (grid->v[x][y] < 600)
- fprintf(S, "%c%2d", exdisplay & DASHga ?
- (grid->v[x][y] < 0 ? 'a' : 's') :
- (grid->v[x][y] < 0 ? '-' : '+'), abs(grid->v[x][y])/60);
- else
- fprintf(S, "%3d", abs(grid->v[x][y])/60);
- } else
- fprintf(S, "%02d'", abs(grid->v[x][y])%60);
- }
-
- /* Print midpoint rows. */
-
- } else if (x > y) {
- AnsiColor(signansi(temp));
- if (r == 2) {
- temp = grid->n[x][y];
- fprintf(S, "%c%c%c", SIGNAM(temp));
- } else if (r == 3) {
- fprintf(S, "%2d%c", grid->v[x][y]/60, DEGR2);
- } else
- fprintf(S, "%02d'", grid->v[x][y]%60);
-
- /* Print the diagonal of object names. */
-
- } else {
- AnsiColor(REVERSE);
- if (r == 2) {
- AnsiColor(objectansi[y]);
- fprintf(S, "%c%c%c", OBJNAM(y));
- } else {
- temp = ZTOS(planet[y]);
- AnsiColor(signansi(temp));
- if (r == 3)
- fprintf(S, "%2d%c", (int)planet[y] - (temp-1)*30, DEGR2);
- else
- fprintf(S, "%c%c%c", SIGNAM(temp));
- }
- }
- AnsiColor(DEFAULT);
- } else
- if (y1 > 0)
- PrintTab(BOXH, 3);
- x1++;
- if (column80 && x1 >= 20)
- x = total;
- }
- if (y+r > 2)
- printl();
- y1++;
- }
- }
-
-
- /* This is a subprocedure of DisplayGrands(). Here we print out one aspect */
- /* configuration found by the parent procedure. */
-
- void PrintGrand(nam, i1, i2, i3, i4)
- char nam;
- int i1, i2, i3, i4;
- {
- switch (nam) {
- case '.': AnsiColor(aspectansi[_CON]); fprintf(S, "Stellium "); break;
- case 't': AnsiColor(aspectansi[_TRI]); fprintf(S, "Grand Trine"); break;
- case 's': AnsiColor(aspectansi[_OPP]); fprintf(S, "T-Square "); break;
- case 'y': AnsiColor(aspectansi[_INC]); fprintf(S, "Yod "); break;
- case 'g': AnsiColor(aspectansi[_SQU]); fprintf(S, "Grand Cross"); break;
- case 'c': AnsiColor(aspectansi[_SEX]); fprintf(S, "Cradle "); break;
- default: ;
- }
- AnsiColor(DEFAULT);
- fprintf(S, " %s ", nam == '.' || nam == 't' || nam == 'g' ? "with" : "from");
- AnsiColor(objectansi[i1]);
- fprintf(S, "%c%c%c: ", OBJNAM(i1));
- PrintZodiac(planet[i1]);
- fprintf(S, " %s ", nam == '.' || nam == 't' ? "and" : "to ");
- AnsiColor(objectansi[i2]);
- fprintf(S, "%c%c%c: ", OBJNAM(i2));
- PrintZodiac(planet[i2]);
- fprintf(S, " %s ", nam == 'g' || nam == 'c' ? "to " : "and");
- AnsiColor(objectansi[i3]);
- fprintf(S, "%c%c%c: ", OBJNAM(i3));
- PrintZodiac(planet[i3]);
- if (nam == 'g' || nam == 'c') {
- fprintf(S, " to ");
- AnsiColor(objectansi[i4]);
- fprintf(S, "%c%c%c: ", OBJNAM(i4));
- PrintZodiac(planet[i4]);
- }
- printl();
- }
-
-
- /* Scan the aspect grid of a chart and print out any major configurations, */
- /* as specified with the -g0 switch. */
-
- void DisplayGrands()
- {
- int count = 0, i, j, k, l;
-
- for (i = 1; i <= total; i++) if (!ignore[i])
- for (j = 1; j <= total; j++) if (j != i && !ignore[j])
- for (k = 1; k <= total; k++) if (k != i && k != j && !ignore[k]) {
-
- /* Is there a Stellium among the current three planets? */
-
- if (i < j && j < k && grid->n[i][j] == _CON &&
- grid->n[i][k] == _CON && grid->n[j][k] == _CON) {
- count++;
- PrintGrand('.', i, j, k, l);
-
- /* Is there a Grand Trine? */
-
- } else if (i < j && j < k && grid->n[i][j] == _TRI &&
- grid->n[i][k] == _TRI && grid->n[j][k] == _TRI) {
- count++;
- PrintGrand('t', i, j, k, l);
-
- /* Is there a T-Square? */
-
- } else if (j < k && grid->n[j][k] == _OPP &&
- grid->n[MIN(i, j)][MAX(i, j)] == _SQU &&
- grid->n[MIN(i, k)][MAX(i, k)] == _SQU) {
- count++;
- PrintGrand('s', i, j, k, l);
-
- /* Is there a Yod? */
-
- } else if (j < k && grid->n[j][k] == _SEX &&
- grid->n[MIN(i, j)][MAX(i, j)] == _INC &&
- grid->n[MIN(i, k)][MAX(i, k)] == _INC) {
- count++;
- PrintGrand('y', i, j, k, l);
- }
- for (l = 1; l <= total; l++) if (!ignore[l]) {
-
- /* Is there a Grand Cross among the current four planets? */
-
- if (i < j && i < k && i < l && j < l && grid->n[i][j] == _SQU &&
- grid->n[MIN(j, k)][MAX(j, k)] == _SQU &&
- grid->n[MIN(k, l)][MAX(k, l)] == _SQU &&
- grid->n[i][l] == _SQU &&
- MinDistance(planet[i], planet[k]) > 150.0 &&
- MinDistance(planet[j], planet[l]) > 150.0) {
- count++;
- PrintGrand('g', i, j, k, l);
-
- /* Is there a Cradle? */
-
- } else if (i < l && grid->n[MIN(i, j)][MAX(i, j)] == _SEX &&
- grid->n[MIN(j, k)][MAX(j, k)] == _SEX &&
- grid->n[MIN(k, l)][MAX(k, l)] == _SEX &&
- MinDistance(planet[i], planet[l]) > 150.0) {
- count++;
- PrintGrand('c', i, j, k, l);
- }
- }
- }
- if (!count)
- fprintf(S, "No major configurations in aspect grid.\n");
- }
-
-
- /* This is subprocedure of ChartWheel(). Here we print out the location */
- /* of a particular house cusp as well as what house cusp number it is. */
-
- void PrintHouse(i, left)
- int i, left;
- {
- if (!left)
- PrintZodiac(house[i]);
- AnsiColor(signansi(i));
- fprintf(S, "<%d>", i);
- if (left)
- PrintZodiac(house[i]);
- else
- AnsiColor(DEFAULT);
- }
-
-
- /* Another subprocedure of ChartWheel(). Here we print out one line in a */
- /* particular house cell (which may be blank). */
-
- void PrintWheelSlot(obj, wheelcols)
- int obj, wheelcols;
- {
- if (obj) {
- AnsiColor(objectansi[obj]);
- fprintf(S, " %c%c%c ", OBJNAM(obj)); /* Print planet and its position. */
- PrintZodiac(planet[obj]);
- fprintf(S, "%c ", ret[obj] < 0.0 ? 'r' : ' ');
- PrintTab(' ', WHEELCOLS-14-1);
- } else
- PrintTab(' ', wheelcols-1); /* This particular line is blank. */
- }
-
-
- /* Display all the objects in a wheel format on the screen, as specified */
- /* with the -w switch. The wheel is divided into the 12 houses and the */
- /* planets are placed accordingly. */
-
- void ChartWheel()
- {
- byte wheel[SIGNS][WHEELROWS];
- int wheelcols, count = 0, i, j, k, l;
-
- /* If the seconds (-b0) flag is set, we'll print all planet and house */
- /* locations to the nearest zodiac second instead of just to the minute. */
-
- seconds = -seconds;
- wheelcols = WHEELCOLS + (seconds < 0)*4;
-
- for (i = 0; i < SIGNS; i++)
- for (j = 0; j < wheelrows; j++) /* Clear out array from the */
- wheel[i][j] = 0; /* last time we used it. */
-
- /* This section of code places each object in the wheel house array. */
-
- for (i = 1; i <= total && count < wheelrows*12; i++) {
- if (ignore[i] || !(i < _MC || i == OBJECTS || i > C_HI))
- continue;
-
- /* Try to put object in its proper house. If no room, */
- /* then overflow over to the succeeding house. */
-
- for (j = inhouse[i]-1; j < SIGNS; j = j < SIGNS ? (j+1)%SIGNS : j) {
-
- /* Now try to find the proper place in the house to put the object. */
- /* This is in sorted order, although a check is made for 0 Aries. */
-
- if (wheel[j][wheelrows-1] > 0)
- continue;
- l = house[j+1] > house[Mod12(j+2)];
- for (k = 0; wheel[j][k] > 0 &&
- (planet[i] >= planet[wheel[j][k]] ||
- (l && planet[i] < DEGHALF && planet[wheel[j][k]] > DEGHALF)) &&
- !(l && planet[i] > DEGHALF && planet[wheel[j][k]] < DEGHALF); k++)
- ;
-
- /* Actually insert object in proper place. */
-
- if (wheel[j][k] <= 0)
- wheel[j][k] = i;
- else {
- for (l = wheelrows-1; l > k; l--)
- wheel[j][l] = wheel[j][l-1];
- wheel[j][k] = i;
- }
- count++;
- j = SIGNS;
- }
- }
-
- /* Now, if this is really the -w switch and not -w0, then reverse the */
- /* order of objects in western houses for more intuitive reading. */
-
- if (!(exdisplay & DASHw0))
- for (i = 3; i < 9; i++)
- for (j = 0; j < wheelrows/2; j++) {
- k = wheelrows-1-j;
- l = wheel[i][j]; wheel[i][j] = wheel[i][k]; wheel[i][k] = l;
- }
-
- /* Here we actually print the wheel and the objects in it. */
-
- printc(BOXNW); PrintTab(BOXH, WHEELCOLS-8); PrintHouse(11, TRUE);
- PrintTab(BOXH, WHEELCOLS-11); PrintHouse(10, TRUE);
- PrintTab(BOXH, WHEELCOLS-10); PrintHouse(9, TRUE);
- PrintTab(BOXH, wheelcols-4); fprintf(S, "%c\n", BOXNE);
- for (i = 0; i < wheelrows; i++) {
- for (j = 10; j >= 7; j--) {
- printc(BOXV); PrintWheelSlot(wheel[j][i], wheelcols);
- }
- fprintf(S, "%c\n", BOXV);
- }
- PrintHouse(12, TRUE); PrintTab(BOXH, WHEELCOLS-11);
- printc(BOXC); PrintTab(BOXH, wheelcols-1); printc(BOXJN);
- PrintTab(BOXH, wheelcols-1); printc(BOXC); PrintTab(BOXH, WHEELCOLS-10);
- PrintHouse(8, FALSE); printl();
- for (i = 0; i < wheelrows; i++) {
- printc(BOXV); PrintWheelSlot(wheel[11][i], wheelcols); printc(BOXV);
-
- /* For some rows, we have to insert the chart header information. */
-
- if (i) {
- PrintTab(' ', wheelcols-11-(i == 2 && !eurotime));
- if (i == 1)
- fprintf(S, "%s (%s) chart", appname, VERSION);
- else if (i == 2) {
- j = DayOfWeek(Mon, Day, Yea);
- k = (int) (FRACT(dabs(Tim))*100.0+ROUND);
- fprintf(S, "%c%c%c %s %s", DAYNAM(j), CharDate(Mon, Day, Yea, 2),
- CharTime((int)floor(Tim), k));
- } else if (i == 3) {
- fprintf(S, "%c%02d:", Zon > 0.0 ? '-' : '+', (int)dabs(Zon));
- j = (int) (FRACT(dabs(Zon))*100.0+ROUND);
- fprintf(S, "%02d %s", j, CharLocation(Lon, Lat, 100.0));
- } else
- PrintTab(' ', 21);
- PrintTab(' ', wheelcols-11-(i == 2 && !eurotime));
-
- } else
- PrintTab(' ', wheelcols*2-1);
- printc(BOXV); PrintWheelSlot(wheel[6][i], wheelcols);
- fprintf(S, "%c\n", BOXV);
- }
- PrintHouse(1, TRUE); PrintTab(BOXH, WHEELCOLS-10);
- printc(BOXJW); PrintTab(' ', wheelcols-11);
- fprintf(S, "%s", systemname[housesystem]);
- PrintTab(' ', 14-StringLen(systemname[housesystem]));
- fprintf(S, "Houses."); PrintTab(' ', wheelcols-11); printc(BOXJE);
- PrintTab(BOXH, WHEELCOLS-10); PrintHouse(7, FALSE); printl();
- for (i = 0; i < wheelrows; i++) {
- printc(BOXV); PrintWheelSlot(wheel[0][i], wheelcols); printc(BOXV);
- if (i == 0) {
- PrintTab(' ', wheelcols-12);
- fprintf(S, "Julian Day = %9.2f", JulianDayFromTime(T));
- PrintTab(' ', wheelcols-12);
- } else
- PrintTab(' ', wheelcols*2-1);
- printc(BOXV); PrintWheelSlot(wheel[5][i], wheelcols);
- fprintf(S, "%c\n", BOXV);
- }
- PrintHouse(2, TRUE); PrintTab(BOXH, WHEELCOLS-10);
- printc(BOXC); PrintTab(BOXH, wheelcols-1); printc(BOXJS);
- PrintTab(BOXH, wheelcols-1); printc(BOXC);
- PrintTab(BOXH, WHEELCOLS-10); PrintHouse(6, FALSE); printl();
- for (i = 0; i < wheelrows; i++) {
- for (j = 1; j <= 4; j++) {
- printc(BOXV); PrintWheelSlot(wheel[j][i], wheelcols);
- }
- fprintf(S, "%c\n", BOXV);
- }
- printc(BOXSW); PrintTab(BOXH, wheelcols-4); PrintHouse(3, FALSE);
- PrintTab(BOXH, WHEELCOLS-10); PrintHouse(4, FALSE);
- PrintTab(BOXH, WHEELCOLS-10); PrintHouse(5, FALSE);
- PrintTab(BOXH, WHEELCOLS-7); fprintf(S, "%c\n", BOXSE);
- seconds = -seconds;
- }
-
-
- /* Display all aspects between objects in the chart, one per line, in */
- /* sorted order based on the total "power" of the aspect, as specified with */
- /* the -m0 switch. The same influences used for -I charts are used here. */
-
- void ChartAspect()
- {
- 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 = 2; i <= total; i++) if (!ignore[i])
- for (j = 1; j < i; j++) if (!ignore[j])
- if (k = grid->n[j][i]) {
- 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[j][i]))/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. */
- InterpretAspect(jhi, ihi);
- continue;
- }
- #endif
- fprintf(S, "%3d: ", count);
- PrintAspect(jhi, ZTOS(planet[jhi]), (int)Sgn(ret[jhi]), ahi,
- ihi, ZTOS(planet[ihi]), (int)Sgn(ret[ihi]), 'a');
- k = grid->v[jhi][ihi];
- AnsiColor(k < 0 ? WHITE : LTGRAY);
- fprintf(S, " - orb: %c%d%c%02d'",
- exdisplay & DASHga ? (k < 0 ? 'a' : 's') : (k < 0 ? '-' : '+'),
- abs(k)/60, DEGR1, 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 chart, */
- /* one per line, in sorted zodiac order from zero Aries onward, as */
- /* specified with the -m switch. */
-
- void ChartMidpoint()
- {
- 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 = i+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. */
- InterpretMidpoint(ilo, jlo);
- continue;
- }
- #endif
- fprintf(S, "%4d: ", count);
- PrintZodiac((real) mlo/60.0);
- printc(' ');
- PrintAspect(ilo, ZTOS(planet[ilo]), (int)Sgn(ret[ilo]), 0,
- jlo, ZTOS(planet[jlo]), (int)Sgn(ret[jlo]), 'm');
- AnsiColor(DEFAULT);
- fprintf(S, "-%4d degree span.\n",
- (int) MinDistance(planet[ilo], planet[jlo]));
- }
- }
-
-
- /* Display locations of the objects on the screen with respect to the local */
- /* horizon, as specified with the -Z switch. */
-
- void ChartHorizon()
- {
- real lon, lat, sx, sy, vx, vy,
- lonz[TOTAL+1], latz[TOTAL+1], azi[TOTAL+1], alt[TOTAL+1];
- int i, j, k, tot;
-
- lon = DTOR(Mod(Lon)); lat = DTOR(Lat);
- tot = universe ? total : BASE;
-
- /* First find zenith location on Earth of each object. */
-
- for (i = 1; i <= tot; i++) {
- lonz[i] = DTOR(planet[i]); latz[i] = DTOR(planetalt[i]);
- EclToEqu(&lonz[i], &latz[i]);
- }
-
- /* Then, convert this to local horizon altitude and azimuth. */
-
- for (i = 1; i <= tot; i++) if (i != _MC) {
- lonz[i] = DTOR(Mod(RTOD(lonz[_MC]-lonz[i]+lon)));
- lonz[i] = DTOR(Mod(RTOD(lonz[i]-lon+PI/2.0)));
- EquToLocal(&lonz[i], &latz[i], PI/2.0-lat);
- azi[i] = DEGREES-RTOD(lonz[i]); alt[i] = RTOD(latz[i]);
- }
-
- /* Now, actually print the location of each object. */
-
- fprintf(S,
- "Body Altitude Azimuth Azi. Vector %s Vector Moon Vector\n\n",
- centerplanet ? " Sun" : " Earth");
- for (k = 1; k <= tot; k++) {
- i = k <= BASE ? k : BASE+starname[k-BASE];
- if (ignore[i] || !IsThing(i))
- continue;
- AnsiColor(objectansi[i]);
- fprintf(S, "%-4.4s: ", objectname[i]);
- PrintAltitude(alt[i]);
-
- /* Determine directional vector based on azimuth. */
-
- j = (int) (FRACT(azi[i])*60.0);
- fprintf(S, " %3d%c%02d'", (int) azi[i], DEGR1, j);
- sx = cos(DTOR(azi[i])); sy = sin(DTOR(azi[i]));
- if (dabs(sx) < dabs(sy)) {
- vx = dabs(sx / sy); vy = 1.0;
- } else {
- vy = dabs(sy / sx); vx = 1.0;
- }
- fprintf(S, " (%.2f%c %.2f%c)",
- vy, sy < 0.0 ? 's' : 'n', vx, sx > 0.0 ? 'e' : 'w');
-
- /* Determine distance vector of current object from Sun and Moon. */
-
- vx = azi[1]-azi[i]; vy = azi[2]-azi[i];
- fprintf(S, " [%6.1f%6.1f] [%6.1f%6.1f]",
- dabs(vx) < DEGHALF ? vx : Sgn(vx)*(DEGREES-dabs(vx)), alt[1]-alt[i],
- dabs(vy) < DEGHALF ? vy : Sgn(vy)*(DEGREES-dabs(vy)), alt[2]-alt[i]);
- if (i >= U_LO) {
- if (i <= U_HI)
- fprintf(S, " Uranian #%d", i-U_LO+1);
- else
- fprintf(S, " Star #%2d", i-S_LO+1);
- }
- printl();
- }
- AnsiColor(DEFAULT);
- }
-
-
- /* Display x,y,z locations of each body (in AU) with respect to the Sun */
- /* (or whatever the specified center planet is), as in the -S switch. */
- /* These values were already determined when calculating the planet */
- /* positions themselves, so this procedure is basically just a loop. */
-
- void ChartSpace()
- {
- real x, y, z;
- int i;
-
- fprintf(S, "Body Angle X axis Y axis Z axis Length\n");
- for (i = 0; i <= BASE; i++) {
- if (ignore[i] || i == 2 || !IsObject(i))
- continue;
- AnsiColor(objectansi[i]);
- fprintf(S, "%c%c%c%c: ", OBJNAM(i),
- objectname[i][3] ? objectname[i][3] : ' ');
- x = spacex[i]; y = spacey[i]; z = spacez[i];
- fprintf(S, "[%7.2f] [%7.2f] [%7.3f] [%7.3f] [%7.3f]",
- planet[i], x, y, z, sqrt(x*x+y*y+z*z));
- if (i >= U_LO) {
- if (i <= U_HI)
- fprintf(S, " Uranian #%d", i-U_LO+1);
- else
- fprintf(S, " Star #%2d", i-S_LO+1);
- }
- printl();
- }
- AnsiColor(DEFAULT);
- }
-
-
- /* Print the locations of the astro-graph lines on the Earth as specified */
- /* with the -L switch. This includes Midheaven and Nadir lines, zenith */
- /* positions, and locations of Ascendant and Descendant lines. */
-
- void ChartAstroGraph()
- {
- crosstruct PTR c;
- real planet1[TOTAL+1], planet2[TOTAL+1], mc[TOTAL+1], ic[TOTAL+1],
- as[TOTAL+1], ds[TOTAL+1], as1[TOTAL+1], ds1[TOTAL+1],
- lo = Lon, longm, w, x, y, z, ad, oa, am, od, dm;
- int occurcount = 0, tot = total, i, j, k, l, m, n;
-
- if (exdisplay & DASHL0)
- {
- Allocate(c, sizeof(crosstruct), crosstruct PTR);
- if (c == NULL
- #ifdef PC
- /* For PC's the array better not cross a segment boundary. */
- || HIWORD(LOWORD(c) + sizeof(crosstruct)) > 0
- #endif
- ) {
- PrintError("Not enough memory for crossing table.");
- return;
- }
- }
-
- #ifdef MATRIX
- for (i = 1; i <= total; i++) {
- planet1[i] = DTOR(planet[i]);
- planet2[i] = DTOR(planetalt[i]); /* Calculate zenith location on */
- EclToEqu(&planet1[i], &planet2[i]); /* Earth of each object. */
- }
-
- /* Print header. */
-
- fprintf(S, "Object :");
- for (j = 0, i = 1; i <= total; i++)
- if (!ignore[i] && IsThing(i)) {
- AnsiColor(objectansi[i]);
- fprintf(S, " %c%c%c", OBJNAM(i));
- j++;
- if (column80 && j >= 17) {
- tot = i;
- i = total;
- }
- }
- AnsiColor(DEFAULT);
- fprintf(S, "\n------ :");
- for (i = 1; i <= tot; i++)
- if (!ignore[i] && IsThing(i))
- fprintf(S, " ###");
-
- /* Print the longitude locations of the Midheaven lines. */
-
- fprintf(S, "\nMidheav: ");
- if (lo < 0.0)
- lo += DEGREES;
- for (i = 1; i <= tot; i++)
- if (!ignore[i] && IsThing(i)) {
- AnsiColor(objectansi[i]);
- x = DTOR(MC)-planet1[i];
- if (x < 0.0)
- x += 2.0*PI;
- if (x > PI)
- x -= 2.0*PI;
- z = lo+RTOD(x);
- if (z > DEGHALF)
- z -= DEGREES;
- mc[i] = z;
- fprintf(S, "%3.0f%c", dabs(z), z < 0.0 ? 'e' : 'w');
- }
- AnsiColor(DEFAULT);
-
- /* The Nadir lines are just always 180 degrees away from the Midheaven. */
-
- fprintf(S, "\nNadir : ");
- for (i = 1; i <= tot; i++)
- if (!ignore[i] && IsThing(i)) {
- AnsiColor(objectansi[i]);
- z = mc[i] + DEGHALF;
- if (z > DEGHALF)
- z -= DEGREES;
- ic[i] = z;
- fprintf(S, "%3.0f%c", dabs(z), z < 0.0 ? 'e' : 'w');
- }
- AnsiColor(DEFAULT);
-
- /* Print the Zenith latitude locations. */
-
- fprintf(S, "\nZenith : ");
- for (i = 1; i <= tot; i++)
- if (!ignore[i] && IsThing(i)) {
- AnsiColor(objectansi[i]);
- y = RTOD(planet2[i]);
- fprintf(S, "%3.0f%c", dabs(y), y < 0.0 ? 's' : 'n');
- as[i] = ds[i] = as1[i] = ds1[i] = LARGE;
- }
- printl2();
-
- /* Now print the locations of Ascendant and Descendant lines. Since these */
- /* are curvy, we loop through the latitudes, and for each object at each */
- /* latitude, print the longitude location of the line in question. */
-
- longm = DTOR(Mod(MC+lo));
- for (j = 80; j >= -80; j -= graphstep) {
- AnsiColor(DEFAULT);
- fprintf(S, "Asc@%2d%c: ", j >= 0 ? j : -j, j < 0 ? 's' : 'n');
- for (i = 1; i <= tot; i++)
- if (!ignore[i] && IsThing(i)) {
- AnsiColor(objectansi[i]);
- ad = tan(planet2[i])*tan(DTOR(j));
- if (ad*ad > 1.0) {
- fprintf(S, " -- ");
- as1[i] = ds1[i] = ret2[i] = LARGE;
- } else {
- ad = ASIN(ad);
- oa = planet1[i]-ad;
- if (oa < 0.0)
- oa += 2.0*PI;
- am = oa-PI/2.0;
- if (am < 0.0)
- am += 2.0*PI;
- z = longm-am;
- if (z < 0.0)
- z += 2.0*PI;
- if (z > PI)
- z -= 2.0*PI;
- as1[i] = as[i];
- as[i] = z = RTOD(z);
- ret2[i] = ad;
- fprintf(S, "%3.0f%c", dabs(z), z < 0.0 ? 'e' : 'w');
- }
- }
-
- /* Again, the Descendant position is related to the Ascendant's, */
- /* being a mirror image, so it can be calculated somewhat easier. */
-
- AnsiColor(DEFAULT);
- fprintf(S, "\nDsc@%2d%c: ", j >= 0 ? j : -j, j < 0 ? 's' : 'n');
- for (i = 1; i <= tot; i++)
- if (!ignore[i] && IsThing(i)) {
- AnsiColor(objectansi[i]);
- ad = ret2[i];
- if (ad == LARGE)
- fprintf(S, " -- ");
- else {
- od = planet1[i]+ad;
- dm = od+PI/2.0;
- z = longm-dm;
- if (z < 0.0)
- z += 2.0*PI;
- if (z > PI)
- z -= 2.0*PI;
- ds1[i] = ds[i];
- ds[i] = z = RTOD(z);
- fprintf(S, "%3.0f%c", dabs(z), z < 0.0 ? 'e' : 'w');
- }
- }
- printl();
- #endif /* MATRIX */
-
- /* Now, if the -L0 switch is in effect, then take these line positions, */
- /* which we saved in an array above as we were printing them, and */
- /* calculate and print the latitude crossings. */
-
- if (exdisplay & DASHL0)
- for (l = 1; l <= total; l++) if (!ignore[l] && IsThing(l))
- for (k = 1; k <= total; k++) {
- if (ignore[k] || !IsThing(k))
- continue;
- for (n = 0; n <= 1; n++) {
- x = n ? ds1[l] : as1[l];
- y = n ? ds[l] : as[l];
- for (m = 0; m <= 1; m++) {
-
- /* Check if Ascendant/Descendant cross Midheaven/Nadir. */
-
- z = m ? ic[k] : mc[k];
- if (occurcount < MAXCROSS &&
- dabs(x-y) < DEGHALF && Sgn(z-x) != Sgn(z-y)) {
- c->obj1[occurcount] = n ? -l : l;
- c->obj2[occurcount] = m ? -k : k;
- c->lat[occurcount] = (real)j+5.0*dabs(z-y)/dabs(x-y);
- c->lon[occurcount] = z;
- occurcount++;
- }
-
- /* Check if Ascendant/Descendant cross another Asc/Des. */
-
- w = m ? ds1[k] : as1[k];
- z = m ? ds[k] : as[k];
- if (occurcount < MAXCROSS && k > l &&
- dabs(x-y)+dabs(w-z) < DEGHALF && Sgn(w-x) != Sgn(z-y)) {
- c->obj1[occurcount] = n ? -l : l;
- c->obj2[occurcount] = 100+(m ? -k : k);
- c->lat[occurcount] = (real)j+5.0*
- dabs(y-z)/(dabs(x-w)+dabs(y-z));
- c->lon[occurcount] = MIN(x, y)+dabs(x-y)*
- dabs(y-z)/(dabs(x-w)+dabs(y-z));
- occurcount++;
- }
- }
- }
- }
- }
- if ((exdisplay & DASHL0) == 0)
- return;
- printl();
-
- /* Now, print out all the latitude crossings we found. */
- /* First, we sort them in order of decreasing latitude. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && c->lat[j] < c->lat[j+1]) {
- SWAP(c->obj1[j], c->obj1[j+1]); SWAP(c->obj2[j], c->obj2[j+1]);
- SwapReal(&c->lat[j], &c->lat[j+1]); SwapReal(&c->lon[j], &c->lon[j+1]);
- j--;
- }
- }
- for (i = 1; i < occurcount; i++) {
- j = abs(c->obj1[i]);
- AnsiColor(objectansi[j]);
- fprintf(S, "%c%c%c ", OBJNAM(j));
- AnsiColor(elemansi[c->obj1[i] > 0 ? 0 : 2]);
- fprintf(S, "%s ", c->obj1[i] > 0 ? "Ascendant " : "Descendant");
- AnsiColor(WHITE);
- fprintf(S, "crosses ");
- j = abs(c->obj2[i] - (c->obj2[i] < 50 ? 0 : 100));
- AnsiColor(objectansi[j]);
- fprintf(S, "%c%c%c ", OBJNAM(j));
- AnsiColor(elemansi[c->obj2[i] < 50 ?
- (c->obj2[i] > 0 ? 1 : 3) : (c->obj2[i] > 100 ? 0 : 2)]);
- fprintf(S, "%s ", c->obj2[i] < 50 ? (c->obj2[i] > 0 ? "Midheaven " :
- "Nadir ") : (c->obj2[i] > 100 ? "Ascendant " : "Descendant"));
- j = (int) (FRACT(dabs(c->lon[i]))*60.0);
- AnsiColor(DEFAULT);
- fprintf(S, "at %3d%c%02d'%c, ", (int) dabs(c->lon[i]), DEGR2,
- j, c->lon[i] < 0.0 ? 'E' : 'W');
- j = (int) (FRACT(dabs(c->lat[i]))*60.0);
- fprintf(S, "%2d%c%02d'%c\n", (int) dabs(c->lat[i]), DEGR2,
- j, c->lat[i] < 0.0 ? 'S' : 'N');
- }
- Deallocate(c);
- if (!occurcount) {
- AnsiColor(DEFAULT);
- fprintf(S, "No latitude crossings.\n");
- }
- }
-
- /* charts.c */
-