⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xcharts.c

📁 一个占星术算命游戏
💻 C
📖 第 1 页 / 共 3 页
字号:
  DrawColor(gray);
  DrawDash(cx, y1, cx, y2, 1);
  DrawDash((cx+x1)/2, y1, (cx+x1)/2, y2, 1);
  DrawDash((cx+x2)/2, y1, (cx+x2)/2, y2, 1);
  DrawColor(on);
  DrawEdge(x1, y1, x2, y2);
  DrawDash(x1, cy, x2, cy, 1);

  /* Calculate the local horizon coordinates of each planet. First convert */
  /* zodiac position and declination to zenith longitude and latitude.     */

  lon = DTOR(Mod(Lon)); lat = DTOR(Lat);
  for (i = 1; i <= total; i++) {
    lonz[i] = DTOR(planet[i]); latz[i] = DTOR(planetalt[i]);
    EclToEqu(&lonz[i], &latz[i]);
  }
  for (i = 1; i <= total; i++) if (Proper(i)) {
    lonz[i] = DTOR(Mod(RTOD(lonz[_MC]-lonz[i]+PI/2.0)));
    EquToLocal(&lonz[i], &latz[i], PI/2.0-lat);
    azi[i] = DEGREES-RTOD(lonz[i]); alt[i] = RTOD(latz[i]);
    x[i] = x1+(int)((real)xs*(Mod(DEGQUAD-azi[i]))/DEGREES+ROUND);
    y[i] = y1+(int)((real)ys*(DEGQUAD-alt[i])/DEGHALF+ROUND);
    m[i] = x[i]; n[i] = y[i]+unit/2;
  }

  /* As in the DrawGlobe() routine, we now determine where to draw the   */
  /* glyphs in relation to the actual points, so that the glyphs aren't  */
  /* drawn on top of each other if possible. Again, we assume that we'll */
  /* put the glyph right under the point, unless there would be some     */
  /* overlap and the above position is better off.                       */

  for (i = 1; i <= total; i++) if (Proper(i)) {
    k = l = chartx+charty;
    for (j = 1; j < i; j++) if (Proper(j)) {
      k = MIN(k, abs(m[i]-m[j])+abs(n[i]-n[j]));
      l = MIN(l, abs(m[i]-m[j])+abs(n[i]-unit-n[j]));
    }
    if (k < unit || l < unit)
      if (k < l)
        n[i] -= unit;
  }
  for (i = total; i >= 1; i--) if (Proper(i))    /* Draw planet's glyph. */
    DrawObject(i, m[i], n[i]);
  for (i = total; i >= 1; i--) if (Proper(i)) {
    DrawColor(objectcolor[i]);
    if (!xbonus || i > BASE)
      DrawPoint(x[i], y[i]);    /* Draw small or large dot */
    else                        /* near glyph indicating   */
      DrawSpot(x[i], y[i]);     /* exact local location.   */
  }
}


/* Draw the local horizon, and draw in the planets where they are at the  */
/* time in question. This chart is done when the -Z0 is combined with the */
/* -X switch. This is an identical function to XChartHorizon(); however,  */
/* that routine's chart is entered on the horizon and meridian. Here we   */
/* center the chart around the center of the sky straight up from the     */
/* local horizon, with the horizon itself being an encompassing circle.   */

void XChartHorizonSky()
{
  real lon, lat, rx, ry, s, a, sqr2,
    lonz[TOTAL+1], latz[TOTAL+1], azi[TOTAL+1], alt[TOTAL+1];
  int x[TOTAL+1], y[TOTAL+1], m[TOTAL+1], n[TOTAL+1],
    cx = chartx / 2, cy = charty / 2, unit = 12*SCALE, i, j, k, l;

  /* Draw a circle in window to indicate horizon line, lines dividing   */
  /* the window into quadrants to indicate n/s and w/e meridians, and   */
  /* segments on these lines and the edges marking 5 degree increments. */

  sqr2 = sqrt(2.0);
  DrawColor(gray);
  DrawDash(cx, 0, cx, charty-1, 1);
  DrawDash(0, cy, chartx-1, cy, 1);
  DrawColor(hilite);
  for (i = -125; i <= 125; i += 5) {
    k = (2+(i/10*10 == i ? 1 : 0)+(i/30*30 == i ? 2 : 0))*scalet;
    s = 1.0/(DEGQUAD*sqr2);
    j = cy+(int)(s*cy*i);
    DrawLine(cx-k, j, cx+k, j);
    j = cx+(int)(s*cx*i);
    DrawLine(j, cy-k, j, cy+k);
  }
  for (i = 5; i < 55; i += 5) {
    k = (2+(i/10*10 == i ? 1 : 0)+(i/30*30 == i ? 2 : 0))*scalet;
    s = 1.0/(DEGHALF-DEGQUAD*sqr2);
    j = (int)(s*cy*i);
    DrawLine(0, j, k, j);
    DrawLine(0, charty-1-j, k, charty-1-j);
    DrawLine(chartx-1, j, chartx-1-k, j);
    DrawLine(chartx-1, charty-1-j, chartx-1-k, charty-1-j);
    j = (int)(s*cx*i);
    DrawLine(j, 0, j, k);
    DrawLine(chartx-1-j, 0, chartx-1-j, k);
    DrawLine(j, charty-1, j, charty-1-k);
    DrawLine(chartx-1-j, charty-1, chartx-1-j, charty-1-k);
  }
  rx = cx/sqr2; ry = cy/sqr2;
  DrawColor(on);
  DrawCircle(cx, cy, (int)rx, (int)ry);
  InitCircle();
  for (i = 0; i < DEGR; i += 5) {
    k = (2+(i/10*10 == i ? 1 : 0)+(i/30*30 == i ? 2 : 0))*scalet;
    DrawLine(cx+(int)((rx-k)*circ->x[i]), cy+(int)((ry-k)*circ->y[i]),
      cx+(int)((rx+k)*circ->x[i]), cy+(int)((ry+k)*circ->y[i]));
  }

  /* Calculate the local horizon coordinates of each planet. First convert */
  /* zodiac position and declination to zenith longitude and latitude.     */

  lon = DTOR(Mod(Lon)); lat = DTOR(Lat);
  for (i = 1; i <= total; i++) {
    lonz[i] = DTOR(planet[i]); latz[i] = DTOR(planetalt[i]);
    EclToEqu(&lonz[i], &latz[i]);
  }
  for (i = 1; i <= total; i++) if (Proper(i)) {
    lonz[i] = DTOR(Mod(RTOD(lonz[_MC]-lonz[i]+PI/2.0)));
    EquToLocal(&lonz[i], &latz[i], PI/2.0-lat);
    azi[i] = a = DEGREES-RTOD(lonz[i]); alt[i] = DEGQUAD-RTOD(latz[i]);
    s = alt[i]/DEGQUAD;
    x[i] = cx+(int)(rx*s*COSD(DEGHALF+azi[i])+ROUND);
    y[i] = cy+(int)(ry*s*SIND(DEGHALF+azi[i])+ROUND);
    if (!ISCHART(x[i], y[i]))
      x[i] = -1000;
    m[i] = x[i]; n[i] = y[i]+unit/2;
  }

  /* As in the DrawGlobe() routine, we now determine where to draw the   */
  /* glyphs in relation to the actual points, so that the glyphs aren't  */
  /* drawn on top of each other if possible. Again, we assume that we'll */
  /* put the glyph right under the point, unless there would be some     */
  /* overlap and the above position is better off.                       */

  for (i = 1; i <= total; i++) if (Proper(i)) {
    k = l = chartx+charty;
    for (j = 1; j < i; j++) if (Proper(j)) {
      k = MIN(k, abs(m[i]-m[j])+abs(n[i]-n[j]));
      l = MIN(l, abs(m[i]-m[j])+abs(n[i]-unit-n[j]));
    }
    if (k < unit || l < unit)
      if (k < l)
        n[i] -= unit;
  }
  for (i = total; i >= 1; i--) if (m[i] >= 0 && Proper(i))    /* Draw glyph. */
    DrawObject(i, m[i], n[i]);
  for (i = total; i >= 1; i--) if (x[i] >= 0 && Proper(i)) {
    DrawColor(objectcolor[i]);
    if (!xbonus || i > BASE)
      DrawPoint(x[i], y[i]);    /* Draw small or large dot */
    else                        /* near glyph indicating   */
      DrawSpot(x[i], y[i]);     /* exact local location.   */
  }
}


/* Draw a chart depicting an aerial view of the solar system in space, with */
/* all the planets drawn around the Sun, and the specified central planet   */
/* in the middle, as done when the -S is combined with the -X switch.       */

void XChartSpace()
{
  int x[TOTAL+1], y[TOTAL+1], m[TOTAL+1], n[TOTAL+1],
    cx = chartx / 2, cy = charty / 2, unit, x1, y1, x2, y2, i, j, k, l;
  real sx, sy, sz = 30.0, xp, yp, a;

  unit = MAX(xtext*12, 6*SCALE);
  x1 = unit; y1 = unit; x2 = chartx-1-unit; y2 = charty-1-unit;
  unit = 12*SCALE;

  /* Determine the scale of the window. For a scale size of 300, make    */
  /* the window 6 AU in radius (enough for inner planets out to asteroid */
  /* belt). For a scale of 200, make window 30 AU in radius (enough for  */
  /* planets out to Neptune). For scale of 100, make it 90 AU in radius  */
  /* (enough for all planets including the orbits of the uranians.)      */

  if (SCALE < 2)
    sz = 90.0;
  else if (SCALE > 2)
    sz = 6.0;
  sx = (real)(cx-x1)/sz; sy = (real)(cy-y1)/sz;
  for (i = 0; i <= BASE; i++) if (Proper(i)) {

    /* Determine what glyph corresponds to our current planet. Normally the */
    /* array indices are the same, however we have to do some swapping for  */
    /* non-geocentric based charts where a planet gets replaced with Earth. */

    if (centerplanet == 0)
      j = i < 2 ? 1-i : i;
    else if (centerplanet == 1)
      j = i;
    else
      j = i == 0 ? centerplanet : (i == centerplanet ? 0 : i);
    xp = spacex[j]; yp = spacey[j];
    x[i] = cx-(int)(xp*sx); y[i] = cy+(int)(yp*sy);
    m[i] = x[i]; n[i] = y[i]+unit/2;
  }

  /* As in the DrawGlobe() routine, we now determine where to draw the   */
  /* glyphs in relation to the actual points, so that the glyphs aren't  */
  /* drawn on top of each other if possible. Again, we assume that we'll */
  /* put the glyph right under the point, unless there would be some     */
  /* overlap and the above position is better off.                       */

  for (i = 0; i <= BASE; i++) if (Proper(i)) {
    k = l = chartx+charty;
    for (j = 0; j < i; j++) if (Proper(j)) {
      k = MIN(k, abs(m[i]-m[j])+abs(n[i]-n[j]));
      l = MIN(l, abs(m[i]-m[j])+abs(n[i]-unit-n[j]));
    }
    if (k < unit || l < unit)
      if (k < l)
        n[i] -= unit;
  }

  /* Draw the 12 sign boundaries from the center body to edges of screen. */

  a = Mod(RTOD(Angle(spacex[_JUP], spacey[_JUP]))-planet[_JUP]);
  DrawColor(gray);
  for (i = 0; i < SIGNS; i++) {
    k = cx+2*(int)((real)cx*COSD((real)i*30.0+a));
    l = cy+2*(int)((real)cy*SIND((real)i*30.0+a));
    DrawClip(cx, cy, k, l, x1, y1, x2, y2, 1);
  }
  DrawColor(hilite);
  DrawEdge(x1, y1, x2, y2);
  for (i = BASE; i >= 0; i--)
    if (Proper(i) && ISLEGAL(m[i], n[i], x1, y1, x2, y2))
      DrawObject(i, m[i], n[i]);
  for (i = BASE; i >= 0; i--)
    if (Proper(i) && ISLEGAL(x[i], y[i], x1, y1, x2, y2)) {
      DrawColor(objectcolor[i]);
      if (!xbonus || i > BASE)
        DrawPoint(x[i], y[i]);    /* Draw small or large dot */
      else                        /* near glyph indicating   */
        DrawSpot(x[i], y[i]);     /* exact local location.   */
    }
}


/* Draw a chart showing a graphical ephemeris for the given month (or year */
/* if -Ey in effect), with the date on the vertical access and the zodiac  */
/* on the horizontal, as done when the -E is combined with the -X switch.  */

void XChartEphemeris()
{
  real symbol[TOTAL*2+1];
  char string[4];
  int yea, unit = 6*SCALE, daytot, d = 1, day, mon, monsiz,
    x1, y1, x2, y2, xs, ys, m, n, u, v, i, j;

  yea = (exdisplay & DASHEy) > 0;    /* Is this -Ey -X or just -E -X? */
  if (yea) {
    daytot = DayInYear(Yea);
    day = 1; mon = 1; monsiz = 31;
  } else
    daytot = DayInMonth(Mon, Yea);
  x1 = yea ? 30 : 24; y1 = unit*2; x2 = chartx - x1; y2 = charty - y1;
  xs = x2 - x1; ys = y2 - y1;

  /* Display glyphs of the zodiac along the bottom axis. */
  for (i = 1; i <= SIGNS+1; i++) {
    m = x1 + xs * (i-1) / 12;
    j = i > SIGNS ? 1 : i;
    DrawColor(signcolor(j));
    DrawSign(j, m, y2 + unit);
    DrawColor(gray);
    DrawDash(m, y1, m, y2, 2);
  }

  /* Loop and display planet movements for one day segment. */
  while (d <= daytot + 1) {
    n = v;
    v = y1 + MULTDIV(ys, d-1, daytot);
    if (!yea || day == 1) {
      DrawColor(gray);
      DrawDash(x1, v, x2, v, 1);    /* Marker line for day or month. */
    }
    if (d > 1)
      for (i = 1; i <= total; i++)
        planet1[i] = planet[i];
    if (yea) {
      MM = mon; DD = day;
    } else {
      MM = Mon; DD = d;
    }
    YY = Yea; TT = 0.0; ZZ = defzone; OO = deflong; AA = deflat;
    CastChart(TRUE);

    /* Draw planet glyphs along top of chart. */
    if (d < 2) {
      for (i = 1; i <= total; i++) {
        symbol[i*2-1] = -LARGE;
        if (!Proper(i) || (i == _MOO && xbonus))
          symbol[i*2] = -LARGE;
        else
          symbol[i*2] = planet[i];
      }
      FillSymbolLine(symbol);
      for (i = total; i >= 1; i--)
        if (symbol[i*2] >= 0.0)
          DrawObject(i, x1 + (int)((real)xs * symbol[i*2] / DEGREES), unit);

    /* Draw a line segment for each object during this time section. */
    } else
      for (i = total; i >= 1; i--) {
        if (!Proper(i) || (i == _MOO && xbonus))
          continue;
        m = x1 + (int)((real)xs * planet1[i] / DEGREES);
        u = x1 + (int)((real)xs * planet[i]  / DEGREES);
        DrawColor(objectcolor[i]);
        DrawWrap(m, n, u, v, x1, x2, objectcolor[i]);
      }

    /* Label months or days in the month along the left and right edges. */
    if (d <= daytot && (!yea || day == 1)) {
      if (yea) {
        sprintf(string, "%c%c%c", MONNAM(mon));
        i = (mon == Mon);
      } else {
        sprintf(string, "%2d", d);
        i = (d == Day);
      }
      DrawColor(i ? on : hilite);
      DrawText(string,     FONTX   *scalet, v + (FONTY-2)*scalet, -1);
      DrawText(string, x2+(FONTX-1)*scalet, v + (FONTY-2)*scalet, -1);
    }

    /* Now increment the day counter. For a month we always go up by one. */
    /* For a year we go up by four or until the end of the month reached. */
    if (yea) {
      day += 4;
      if (day > monsiz) {
        d += 4-(day-monsiz-1);
        if (d <= daytot + 1) {
          mon++;
          monsiz = DayInMonth(mon, Yea);
          day = 1;
        }
      } else
        d += 4;
    } else
      d++;
  }
  DrawColor(hilite);
  DrawEdge(x1, y1, x2, y2);

  MM = Mon; DD = Day; TT = Tim;    /* Recast original chart. */
  CastChart(TRUE);
}
#endif /* GRAPH */

/* xcharts.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -