?? xcharts.c
字號:
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 + -