From: astrolog@byron.u.washington.edu (Astrolog)
Newsgroups: alt.astrology
Subject: * Astrolog birthchart program version 2.30 [Part 06/12] options.c
Summary: (Virgo) Source file - extract and save to "options.c"
Keywords: Astrolog 2.30
Date: 12 Sep 92 02:53:52 GMT
Organization: University of Washington

/*
** Astrolog (Version 2.30) File: options.c
**
** IMPORTANT: the graphics database and chart display routines used in
** this program are Copyright (C) 1991-1992 by Walter D. Pullen. 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.
*/

#include "astrolog.h"

/*
*******************************************************************************
** Calculation subprograms
*******************************************************************************
*/

/* This is a subprocedure of creategrid() and createrelationgrid(). Given */
/* two planets, determine what aspect, if any, is present between them,   */
/* and save the aspect name and orb in the specified grid cell.           */

getaspect(planet1, planet2, i, j)
double *planet1, *planet2;
int i, j;
{
  int k;
  double l, m;
  gridname[i][j] = grid[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)) {
      gridname[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 (todisplay & DASHGA)
	m = sgn(ret[j]-ret[i])*sgn(planet1[j]-planet2[i])*
	  (dabs(planet1[j]-planet2[i])>180.0 ? -1.0 : 1.0)*sgn(m)*dabs(m);
      grid[i][j] = (int) (m*60.0);
    }
  }
}


/* 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;
  double l;
  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, i, j);
      else if (acc ? i < j : i > j) {
	l = mod(midpoint(planet[i], planet[j])); k = (int)l;    /* Calculate */
	gridname[i][j] = k/30+1;                                /* midpoint. */
	grid[i][j] = (int)((l-(double)(k/30)*30.0)*60.0);
      } else {
	gridname[i][j] = (int)planet[j]/30+1;
	grid[i][j] = (int)(planet[j]-(double)(gridname[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 createrelationgrid(acc)
int acc;
{
  int i, j, k;
  double l;
  for (j = 1; j <= total; j++) if (!ignore[j])
    for (i = 1; i <= total; i++) if (!ignore[i])
      if (!acc)
	getaspect(planet1, planet2, i, j);
      else {
	l = mod(midpoint(planet2[i], planet1[j])); k = (int)l;  /* Calculate */
	gridname[i][j] = k/30+1;                                /* midpoint. */
	grid[i][j] = (int)((l-(double)(k/30)*30.0)*60.0);
      }
}


/* 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. */

displayrelationgrid()
{
  int i, j, k, temp;
  printf(" 2>");
  for (i = 1; i < total; i++) if (!ignore[i])
    printf("|%c%c%c", OBJNAM(i));
  printf("\n1  ");
  for (i = 1; i < total; i++) if (!ignore[i])
    printf("|###");
  printf("\nV  ");
  for (i = 1; i < total; i++) if (!ignore[i]) {
    temp = (int)(planet2[i]/30.0)+1;
    printf("|%c%c%c", SIGNAM(temp));
  }
  putchar('\n');
  for (j = 1; j < total; j++) if (!ignore[j])
    for (k = 1; k <= 4; k++) {
      if (k < 2)
	printf("---");
      else if (k == 2)
	printf("%c%c%c", OBJNAM(j));
      else if (k == 4) {
	temp = (int)(planet1[j]/30.0)+1;
	printf("%c%c%c", SIGNAM(temp));
      } else
	printf("###");
      for (i = 1; i < total; i++) if (!ignore[i]) {
	putchar('|');
        if (k < 2)
	  printf("---");
	else if (k == 2) {
	  temp = gridname[i][j];
	  if (todisplay & DASHG0)
	    printf("%c%c%c", SIGNAM(temp));
	  else
	    printf("%s", aspectabbrev[temp]);
	} else if (k == 3) {
	  if (todisplay & DASHG0)
	    printf("%3d", grid[i][j]/60);
	  else
	    if (gridname[i][j]) {
	      if (grid[i][j] < 600)
		printf("%c%2d", todisplay & DASHGA ?
		       (grid[i][j] < 0 ? 'a' : 's') :
		       (grid[i][j] < 0 ? '-' : '+'), abs(grid[i][j])/60);
	      else
		printf("%3d", abs(temp)/60);
	    } else
	      printf("   ");
	} else {
	  if (gridname[i][j]) {
	    temp = abs(grid[i][j])%60;
	    printf("%d%d'", temp/10, temp%10);
	  } else
	    printf("   ");
	}
      }
      putchar('\n');
    }
}


/* 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.   */

#define degtodec(A) sgn(A)*(floor(dabs(A))+(dabs(A)-floor(dabs(A)))*60/100.0)

void castrelation()
{
  double zon, lon, lat, t1, t2, t;
  int i;

  /* Read in the first chart. */

  inputdata(filename);
  zon = X; lon = L5; lat = LA;
  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. */

  inputdata(filename2);
  Mon = M; Day = D; Yea = Y; Tim = F; Zon = X; Lon = L5; Lat = LA;
  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 <= 1)
    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 == 2) {
    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[10], mod(house[i]-(double)(i+2)*30.0)) > 90.0)
	house[i] = mod(house[i]+180.0);

  /* 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 == 3) {
    T = (t1+t2)/2.0;
    t = (T*36525.0)+0.5; JD = floor(t)+2415020.0; F = (t-floor(t))*24.0;
    X = (dectodeg(zon)+dectodeg(Zon))/2.0; X = degtodec(X);
    F = dectodeg(F)-dectodeg(X); F = degtodec(F);
    if (F < 0.0) {
      F = dectodeg(F)+24.0; F = degtodec(F); JD -= 1.0;
    }
    juliantomdy(JD, &M, &D, &Y);
    L5 = (dectodeg(lon)+dectodeg(Lon))/2.0;
    if (dabs(Lon-lon) > 180.0)
      L5 = mod(L5+180.0);
    L5 = degtodec(L5);
    LA = (dectodeg(lat)+dectodeg(Lat))/2.0; LA = degtodec(LA);
    Mon = M; Day = D; Yea = Y; Tim = F; Zon = X; Lon = L5; Lat = LA;
    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 = floor((dabs(t2-t1)*36525.0)+0.5);
  houseplace();
}


/* 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.)  */

displayinday(prog)
int prog;
{
  int time[MAXINDAY], source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY],
    sign1[MAXINDAY], sign2[MAXINDAY], occurcount, divisions, div,
    i, j, k, s1, s2;
  double Day2, D1, D2, divsiz, d1, d2, e1, e2, f1, f2, g;

  /* If parameter 'prog' is set, look for changes in a progressed chart. */

  divisions = prog ? 1 : DIVISIONS;
  divsiz = 24.0/ (double) divisions*60.0;

  /* If -d0 in effect, then search through the whole month, day by day. */

  if (todisplay & DASHD0) {
    D1 = 1.0;
    if (prog && Mon2 == 0.0) {
      Mon2 = 1.0; D2 = 365.0-28.0+(double)dayinmonth(2, (int) Yea2);
    } else D2 = (double)
      dayinmonth((int) (prog ? Mon2 : Mon), (int) (prog ? Yea2 : Yea));
  } else
    D1 = D2 = Day;

  /* Start searching the day or days in question for exciting stuff. */

  for (Day2 = D1; Day2 <= D2; Day2 += 1.0) {
    occurcount = 0;

    /* Cast chart for beginning of day and store it for future use. */

    M = Mon; D = Day2; Y = Yea; F = 0.0; X = Zon; L5 = Lon; LA = Lat;
    if (progress = prog) {
      Jdp = mdytojulian(Mon2, D, Yea2);
      M = Mon; D = Day; Y = Yea; F = Tim; X = Zon; L5 = Lon; LA = 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 == slower, but slightly better time accuracy.       */

    for (div = 1; div <= divisions; div++) {

      /* Cast the chart for the ending time of the present segment. The   */
      /* beginning time chart is copied from the previous end time chart. */

      M = Mon; D = Day2; Y = Yea; X = Zon; L5 = Lon; LA = Lat;
      F = 24.0*div/ (double) divisions;
      if (prog) {
	Jdp = mdytojulian(Mon2, D+1.0, Yea2);
	M = Mon; D = Day; Y = Yea; F = Tim; X = Zon; L5 = Lon; LA = 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 || i <= THINGS || i > C_HI)) {
	s1 = (int) floor(planet1[i] / 30.0);
	s2 = (int) floor(planet2[i] / 30.0);

	/* Does the current planet change into the next or previous sign? */

	if (!ignore[i] && s1 != s2) {
	  source[occurcount] = i;
	  aspect[occurcount] = -1;
	  dest[occurcount] = s2+1;
	  time[occurcount] = (int) (mindistance(planet1[i],
            (double) (ret1[i] >= 0.0 ? s2 : s1) * 30.0) /
            mindistance(planet1[i], planet2[i])*divsiz) +
	    (int) ((double) (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)) {
	  source[occurcount] = i;
	  aspect[occurcount] = -2;
	  dest[occurcount] = ret2[i] < 0.0;
	  time[occurcount] = (int) (dabs(ret1[i])/(dabs(ret1[i])+dabs(ret2[i]))
	    *divsiz) + (int) ((double) (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 || j <= THINGS || j > C_HI))
	  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)) {
	      swapdoub(&d1, &e1);
	      swapdoub(&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) > 180.0)
	      f1 -= sgn(f1)*DEGREES;
	    f2 = e2-d2;
	    if (dabs(f2) > 180.0)
	      f2 -= sgn(f2)*DEGREES;
	    if (mindistance(midpoint(d1, d2), midpoint(e1, e2)) < 90.0 &&
		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) > 180.0)
		f1 -= sgn(f1)*DEGREES;
	      f2 = e2-e1;
	      if (dabs(f2) > 180.0)
		f2 -= sgn(f2)*DEGREES;
	      g = (dabs(d1-e1) > 180.0 ?
		   (d1-e1)-sgn(d1-e1)*DEGREES : d1-e1)/(f2-f1);
	      time[occurcount] = (int) (g*divsiz) +
		(int) ((double) (div-1)*divsiz);
	      sign1[occurcount] = (int) (mod(planet1[i]+
		sgn(planet2[i]-planet1[i])*
		(dabs(planet2[i]-planet1[i]) > 180.0 ? -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]) > 180.0 ? -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]) {
	swapint(&source[j], &source[j+1]);
	swapint(&aspect[j], &aspect[j+1]);
	swapint(&dest[j], &dest[j+1]);
	swapint(&time[j], &time[j+1]);
	swapint(&sign1[j], &sign1[j+1]); swapint(&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;
      s1 = mod12(s1);
      j = (int) Day2;
      if (prog) {
	g = Mon2;
	while (j > (k = dayinmonth((int) g, (int) Yea2))) {
	  j -= k;
	  g += 1.0;
	}
      }
      printf("%2.0f/%d%d/%4.0f ",
	     prog ? g : Mon, j/10, j%10, prog ? Yea2 : Yea);  /* Print date. */
      printf("%2d:%d%d%cm - ",
	     s1, s2/10, s2%10, time[i] < 12*60 ? 'a' : 'p');  /* Print time. */
      if (prog)
	printf("progr ");
      printf("%7.7s", objectname[source[i]]);
      j = (ret1[source[i]] < 0.0)+(ret2[source[i]] < 0.0);
      printf(" %c%c%c%c%c", j < 1 ? '(' : (j > 1 ? '[' : '<'),
	     SIGNAM(sign1[i]), j < 1 ? ')' : (j > 1 ? ']' : '>'));
      if (aspect[i] == -1)
	printf(" --> ");
      else if (aspect[i] == -2)
	printf(" S/%c", dest[i] ? 'R' : 'D');   /* Print a direction change. */
      else
	printf(" %s ", aspectabbrev[aspect[i]]);
      if (aspect[i] == -1) {
	printf("%s", signname[dest[i]]);
	if (source[i] == 1) {
	  if (dest[i] == 1)
	    printf(" (Vernal Equinox)");      /* If the Sun changes sign, */
	  else if (dest[i] == 4)              /* then print out if this   */
	    printf(" (Summer Solstice)");     /* is a season change.      */
	  else if (dest[i] == 7)
	    printf(" (Autumnal Equinox)");
	  else if (dest[i] == 10)
	    printf(" (Winter Solstice)");
	}
      } else if (aspect[i] > 0) {
	j = (ret1[dest[i]] < 0.0)+(ret2[dest[i]] < 0.0);
	printf("%c%c%c%c%c %s",
	       j < 1 ? '(' : (j > 1 ? '[' : '<'), SIGNAM(sign2[i]),
	       j < 1 ? ')' : (j > 1 ? ']' : '>'), objectname[dest[i]]);
	if (source[i] == 1 && dest[i] == 2) {
	  if (aspect[i] == 1)
	    printf(" (New Moon)");     /* Print out if the present */
	  else if (aspect[i] == 2)     /* aspect is a New, Full,   */
	    printf(" (Full Moon)");    /* or Half Moon.            */
	  else if (aspect[i] == 3)
	    printf(" (Half Moon)");
	}
      }
      putchar('\n');
    }
  }
}


/* 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 printtransit(prog)
int prog;
{
  double planet3[TOTAL+1], house3[SIGNS+1], ret3[TOTAL+1];
  int time[MAXINDAY], source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY],
    sign[MAXINDAY], isret[MAXINDAY], occurcount, div, i, j, k, s1, s2, s3;
  double M1, M2, divsiz, daysiz, d, e1, e2, f1, f2;

  /* Compute the chart that we are looking for transits to, and save it. */

  inputdata(filename);
  Mon = M; Day = D; Yea = Y; Tim = F; Zon = X; Lon = L5; Lat = LA;
  castchart(TRUE);
  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.0) {        /* Searching month number zero means to search */
    M1 = 1.0; M2 = 12.0;    /* 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 += 1.0) {
    daysiz = (double) dayinmonth((int) Mon2, (int) Yea2)*24.0*60.0;
    divsiz = daysiz/ (double) DIVISIONS;

    /* Cast chart for beginning of month and store it for future use. */

    M = Mon2; D = 1.0; Y = Yea2; F = 0.0;
    X = defzone; L5 = deflong; LA = deflat;
    if (progress = prog) {
      Jdp = mdytojulian(M, D, Y);
      M = Mon; D = Day; Y = Yea; F = Tim; X = Zon; L5 = Lon; LA = 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.    */

      M = Mon2; Y = Yea2; F = 0.0; X = defzone; L5 = deflong; LA = deflat;
      D = 1.0+(daysiz/24.0/60.0)*div/ (double) DIVISIONS;
      if (prog) {
	Jdp = mdytojulian(M, D, Y);
	M = Mon; D = Day; Y = Yea; F = Tim; X = Zon; L5 = Lon; LA = 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 (!ignore[j] &&
	  (j != 2 || (j == 2 && (todisplay & DASHT0) > 0)) &&
	  (prog || j <= THINGS || j > C_HI))

	  /* 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) > 180.0)
	      f1 -= sgn(f1)*DEGREES;
	    f2 = e2-d;
	    if (dabs(f2) > 180.0)
	      f2 -= sgn(f2)*DEGREES;
	    if (mindistance(d, midpoint(e1, e2)) < 90.0 &&
		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) ((double) (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] = (ret1[j] < 0.0)+(ret2[j] < 0.0);
	      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]) {
	  swapint(&source[j], &source[j+1]);
	  swapint(&aspect[j], &aspect[j+1]);
	  swapint(&dest[j], &dest[j+1]);
	  swapint(&time[j], &time[j+1]);
	  swapint(&sign[j], &sign[j+1]);
	  swapint(&isret[j], &isret[j+1]);
	  j--;
	}
      }

      /* Now loop through list and display all the transits. */

      for (i = 0; i < occurcount; i++) {
	s1 = time[i]/24/60;
	s3 = time[i]-s1*24*60;
	s2 = s3/60;
	s3 = s3-s2*60;
	printf("%2.0f/%d%d/%4.0f %2d:%d%d%cm - %s ",
	       Mon2, (s1+1)/10, (s1+1)%10, Yea2, mod12(s2),
	       s3/10, s3%10, s2 < 12 ? 'a' : 'p', !prog ? "trans" : "progr");
	printf("%7.7s", objectname[source[i]]);
	j = (int) (planet3[dest[i]]/30.0)+1;
	printf(" %c%c%c%c%c ",
	       isret[i] < 1 ? '(' : (isret[i] > 1 ? '[' : '<'),
	       SIGNAM(sign[i]),
	       isret[i] < 1 ? ')' : (isret[i] > 1 ? ']' : '>'));
	printf("%s natal %c%c%c%c%c %s", aspectabbrev[aspect[i]],
	       ret3[dest[i]] >= 0.0 ? '(' : '[', SIGNAM(j),
	       ret3[dest[i]] >= 0.0 ? ')' : ']', objectname[dest[i]]);

	/* Check for a Solar, Lunar, or any other return. */

	if (aspect[i] == 1 && source[i] == dest[i])
	  printf(" (%s Return)", source[i] == 1 ? "Solar" :
		 (source[i] == 2 ? "Lunar" : objectname[source[i]]));
	putchar('\n');
      }
    }
  }
}


/* Print out an ephemeris - the positions of the planets at midnight each */
/* day during a specified month, as done with the -E switch.              */

void printephemeris()
{
  double M1, M2;
  int daysiz, i, j, k, s, d, m;

  /* If -E0 switch in effect, then allow stuff other than Sun..Pluto. */

  k = todisplay & DASHE0 ? BASE : 10;

  /* If the specified month is "0", loop through all months in whole year. */

  if (Mon2 == 0.0) {
    M1 = 1.0; M2 = 12.0;
  } else
    M1 = M2 = Mon2;

  /* Loop through the month or months in question, printing each ephemeris. */

  for (Mon2 = M1; Mon2 <= M2; Mon2 += 1.0) {
    daysiz = dayinmonth((int) Mon2, (int) Yea2);
    printf("Mo/Dy/Yr");
    for (j = 1; j <= k; j++) {
      if (!ignore[j] && (j <= THINGS || j > C_HI))
	printf("  %c%c%c%c ", OBJNAM(j), objectname[j][3] != 0 ?
	       objectname[j][3] : ' ');
    }
    putchar('\n');
    for (i = 1; i <= daysiz; i++) {

      /* Loop through each day in the month, casting a chart for that day. */

      M = Mon2; D = (double) i; Y = Yea2;
      F = 0.0; X = defzone; L5 = deflong; LA = deflat;
      castchart(TRUE);
      printf("%2d/%2d/%2d ", (int) Mon2, i, ((int) Yea2) % 100);
      for (j = 1; j <= k; j++)
	if (!ignore[j] && (j <= THINGS || j > C_HI)) {
	  s = (int) (planet[j]/30.0) + 1;
	  d = (int) planet[j] - (s-1)*30;
	  m = (int) ((planet[j]-floor(planet[j]))*60.0);
	  printf("%2d%s%s%d%c", d, signabbrev[s], m < 10 ? "0" : "", m,
		 ret[j] >= 0.0 ? ' ' : '.');
	}
      putchar('\n');
    }
    if (Mon2 < M2)
      putchar('\n');
  }
}


/* Display either a biorythm chart or the number of days that have passed  */
/* 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.                                      */

printrelation()
{
  int i, j;
  double k, l;

  /* If we are calculating the difference between two dates, then display */
  /* the value and return, as with the -rd switch.                        */

  if (relation == 4) {
    printf("%.0f day%s %s passed between the dates in the two charts.\n",
	   JD, JD != 1.0 ? "s" : "", JD != 1.0 ? "have" : "has");
    return;
  }

  /* If we are doing a biorythm (-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.       */

  for (JD -= 7.0, i = -7; i <= 7; i++, JD += 1.0) {
    printf("T%c%d Day%c:", i < 0 ? '-' : '+', abs(i), abs(i) != 1 ? 's' : ' ');
    for (j = 1; j <= 3; j++) {
      putchar(' ');
      switch (j) {
      case 1: k = 23.0; printf("Physical");     break;
      case 2: k = 28.0; printf("Emotional");    break;
      case 3: k = 33.0; printf("Intellectual"); break;
      }

      /* The biorythm formula is below. */

      l = sin((JD/k)*PI*2.0)*100.0;
      printf(" at %c%3.0f%%", l < 0.0 ? '-' : '+', dabs(l));

      /* Print smiley face, medium face, or sad face based on current cycle. */

      printf(" :%c", l > 50.0 ? ')' : (l < -50.0 ? '(' : '|'));
      if (j < 3)
	putchar(',');
    }
    putchar('\n');
  }
}


/* 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)
{
  int todisp;
  todisp = todisplay & DASHE;
  if (todisp == 0)                            /* Assume the -v chart if user */
    todisp = todisplay = todisplay | DASHV;   /* didn't indicate anything.   */
  if (todisp & DASHV) {
    if (relation < 4)
      chartlocation(FALSE);
    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. */

      printrelation();
    if (todisp - (todisp & DASHV*2-1))
      printf("\n\n");
  }
  if (todisp & DASHW) {
    chartwheel();
    if (todisp - (todisp & DASHW*2-1))
      printf("\n\n");
  }
  if (todisp & DASHG) {
    if (relation != -1) {
      creategrid(FALSE);
      chartgrid(FALSE);
      if (todisplay & DASHG0) {    /* If -g0 switch in effect, then  */
	putchar('\n');             /* display aspect configurations. */
	displaygrands();
      }
    } else {

      /* Do a relationship aspect grid between two charts if -r0 in effect. */

      createrelationgrid(todisplay & DASHG0 ? 2 : FALSE);
      displayrelationgrid();
    }
    if (todisp - (todisp & DASHG*2-1))
      printf("\n\n");
  }
  if (todisp & DASHZ) {
    charthorizon();
    if (todisp - (todisp & DASHZ*2-1))
      printf("\n\n");
  }
  if (todisp & DASHS) {
    chartspace();
    if (todisp - (todisp & DASHS*2-1))
      printf("\n\n");
  }
  if (todisp & DASHI) {
    chartinfluence();
    if (todisp - (todisp & DASHI*2-1))
      printf("\n\n");
  }
  if (todisp & DASHL) {
    chartastrograph();
    if (todisp - (todisp & DASHL*2-1))
      printf("\n\n");
  }
  if (todisp & DASHD)
    displayinday(prog);
}

/**/