📄 xcharts.c
字号:
/* with the -X switch. */
void XChartAstroGraph()
{
real planet1[TOTAL+1], planet2[TOTAL+1],
end1[TOTAL*2+1], end2[TOTAL*2+1],
symbol1[TOTAL*2+1], symbol2[TOTAL*2+1],
lon = Lon, longm, x, y, z, ad, oa, am, od, dm, lat;
int unit = SCALE, stroke, lat1 = -60, lat2 = 75, y1, y2, xold1, xold2,
i, j, k, l;
/* Erase top and bottom parts of map. We don't draw the astro-graph lines */
/* above certain latitudes, and this gives us room for glyph labels, too. */
y1 = (91-lat1)*SCALE;
y2 = (91-lat2)*SCALE;
DrawColor(off);
DrawBlock(1, 1, chartx-2, y2-1);
DrawBlock(1, charty-2, chartx-2, y1+1);
DrawColor(hilite);
DrawDash(0, charty/2, chartx-2, charty/2, 4); /* Draw equator. */
DrawColor(on);
DrawLine(1, y2, chartx-2, y2);
DrawLine(1, y1, chartx-2, y1);
for (i = 1; i <= total*2; i++)
end1[i] = end2[i] = -LARGE;
/* Draw small hatches every 5 degrees along edges of world map. */
DrawColor(hilite);
for (i = lat1; i <= lat2; i += 5) {
j = (91-i)*SCALE;
k = (2+(i%10 == 0)+2*(i%30 == 0))*scalet;
DrawLine(1, j, k, j);
DrawLine(chartx-2, j, chartx-1-k, j);
}
for (i = -180; i < 180; i += 5) {
j = (180-i)*SCALE;
k = (2+(i%10 == 0)+2*(i%30 == 0)+(i%90 == 0))*scalet;
DrawLine(j, y2+1, j, y2+k);
DrawLine(j, y1-1, j, y1-k);
}
#ifdef MATRIX
/* Calculate zenith locations of each planet. */
for (i = 1; i <= total; i++) {
planet1[i] = DTOR(planet[i]);
planet2[i] = DTOR(planetalt[i]);
EclToEqu(&planet1[i], &planet2[i]);
}
/* Draw the Midheaven lines and zenith location markings. */
if (lon < 0.0)
lon += DEGREES;
for (i = 1; i <= total; i++) if (Proper(i)) {
x = DTOR(MC)-planet1[i];
if (x < 0.0)
x += 2.0*PI;
if (x > PI)
x -= 2.0*PI;
z = lon+RTOD(x);
if (z > DEGHALF)
z -= DEGREES;
j = (int) (Mod(DEGHALF-z+degree)*(real)SCALE);
DrawColor(elemcolor[_EAR]);
DrawLine(j, y1+unit*4, j, y2-unit*1);
end2[i*2-1] = (real) j;
y = RTOD(planet2[i]);
k = (int) ((91.0-y)*(real)SCALE);
DrawColor(hilite);
DrawBlock(j-1, k-1, j+1, k+1);
DrawColor(off);
DrawBlock(j, k, j, k);
/* Draw Nadir lines assuming we aren't in bonus chart mode. */
if (!xbonus) {
j += 180*SCALE;
if (j > chartx-2)
j -= (chartx-2);
end1[i*2-1] = (real) j;
DrawColor(elemcolor[_WAT]);
DrawLine(j, y1+unit*2, j, y2-unit*2);
}
}
/* Now, normally, unless we are in bonus chart mode, we will go on to draw */
/* the Ascendant and Descendant lines here. */
longm = DTOR(Mod(MC+lon));
if (!xbonus) for (i = 1; i <= total; i++) if (Proper(i)) {
xold1 = xold2 = -1000;
/* Hack: Normally we draw the Ascendant and Descendant line segments */
/* simultaneously. However, for the PostScript and metafile stroke */
/* graphics, this will case the file to get inordinately large due to */
/* the constant thrashing between the Asc and Desc colors. Hence for */
/* these charts only, we'll do two passes for Asc and Desc. */
stroke = psfile || metafile;
for (l = 0; l <= stroke; l++)
for (lat = (real)lat1; lat <= (real)lat2;
lat += 1.0/(real)(SCALE/scalet)) {
/* First compute and draw the current segment of Ascendant line. */
j = (int) ((91.0-lat)*(real)SCALE);
ad = tan(planet2[i])*tan(DTOR(lat));
if (ad*ad > 1.0)
ad = 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;
z = RTOD(z);
k = (int) (Mod(DEGHALF-z+degree)*(real)SCALE);
if (!stroke || !l) {
DrawColor(elemcolor[_FIR]);
DrawWrap(xold1, j+scalet, k, j, 1, chartx-2);
if (lat == (real) lat1) { /* Line segment */
DrawLine(k, y1, k, y1+unit*4); /* pointing to */
end2[i*2] = (real) k; /* Ascendant. */
}
} else if (lat == (real) lat1)
end2[i*2] = (real) k;
xold1 = k;
}
/* The curving Ascendant and Descendant lines actually touch each at */
/* low latitudes. Sometimes when we start out, a particular planet's */
/* lines haven't appeared yet, i.e. we are scanning at a latitude */
/* where our planet's lines don't exist. If this is the case, then */
/* when they finally do start, draw a thin horizontal line connecting */
/* the Ascendant and Descendant lines so they don't just start in */
/* space. Note that these connected lines aren't labeled with glyphs. */
if (ad == LARGE) {
if (xold1 >= 0) {
if (!stroke || !l) {
DrawColor(gray);
DrawWrap(xold1, j+1, xold2, j+1, 1, chartx-2);
}
lat = DEGQUAD;
}
} else {
/* Then compute and draw corresponding segment of Descendant line. */
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;
z = RTOD(z);
k = (int) (Mod(DEGHALF-z+degree)*(real)SCALE);
if (xold2 < 0 && lat > (real)lat1 && (!stroke || l)) {
DrawColor(gray);
DrawWrap(xold1, j, k, j, 1, chartx-2);
}
if (!stroke || l) {
DrawColor(elemcolor[_AIR]);
DrawWrap(xold2, j+scalet, k, j, 1, chartx-2);
if (lat == (real)lat1) /* Line segment */
DrawLine(k, y1, k, y1+unit*2); /* pointing to */
} /* Descendant. */
xold2 = k;
}
}
#endif /* MATRIX */
/* Draw segments pointing to top of Ascendant and Descendant lines. */
if (ad != LARGE) {
DrawColor(elemcolor[_FIR]);
DrawLine(xold1, y2, xold1, y2-unit*1);
DrawColor(elemcolor[_AIR]);
DrawLine(k, y2, k, y2-unit*2);
end1[i*2] = (real) k;
}
}
DrawColor(maincolor[5]);
DrawPoint((int)((181.0-Lon)*(real)SCALE),
(int)((91.0-Lat)*(real)SCALE));
/* Determine where to draw the planet glyphs. We have four sets of each */
/* planet - each planet's glyph appearing in the chart up to four times - */
/* one for each type of line. The Midheaven and Ascendant lines are always */
/* labeled at the bottom of the chart, while the Nadir and Midheaven lines */
/* at the top. Therefore we need to place two sets of glyphs, twice. */
for (i = 1; i <= total*2; i++) {
symbol1[i] = end1[i];
symbol2[i] = end2[i];
}
FillSymbolLine(symbol1);
FillSymbolLine(symbol2);
/* Now actually draw the planet glyphs. */
for (i = 1; i <= total*2; i++) {
j = (i+1)/2;
if (Proper(j)) {
if ((turtlex = (int) symbol1[i]) > 0 && xlabel) {
DrawColor(ret[j] < 0.0 ? gray : on);
DrawDash((int) end1[i], y2-unit*2, (int) symbol1[i], y2-unit*4,
(ret[i] < 0.0 ? 1 : 0) - xcolor);
DrawObject(j, turtlex, y2-unit*10);
}
if ((turtlex = (int) symbol2[i]) > 0) {
DrawColor(ret[j] < 0.0 ? gray : on);
DrawDash((int) end2[i], y1+unit*4, (int) symbol2[i], y1+unit*8,
(ret[i] < 0.0 ? 1 : 0) - xcolor);
DrawObject(j, turtlex, y1+unit*14);
DrawTurtle(objectdraw[i & 1 ? _MC : _ASC], (int) symbol2[i],
y1+unit*24);
}
}
}
}
/* Draw an aspect and midpoint grid in the window, with planets labeled down */
/* the diagonal. This chart is done when the -g switch is combined with the */
/* -X switch. The chart always has a certain number of cells; hence based */
/* how the restrictions are set up, there may be blank columns and rows, */
/* or else only the first number of unrestricted objects will be included. */
void XChartGrid()
{
char string[STRING];
int unit, siz, x, y, i, j, k;
colpal c;
unit = CELLSIZE*SCALE; siz = gridobjects*unit;
CreateGrid(xbonus);
/* Loop through each cell in each row and column of grid. */
for (y = 1, j = 0; y <= gridobjects; y++) {
do {
j++;
} while (ignore[j] && j <= total);
DrawColor(gray);
DrawDash(0, y*unit, siz, y*unit, !xcolor);
DrawDash(y*unit, 0, y*unit, siz, !xcolor);
if (j <= total) for (x = 1, i = 0; x <= gridobjects; x++) {
do {
i++;
} while (ignore[i] && i <= total);
if (i <= total) {
turtlex = x*unit-unit/2;
turtley = y*unit-unit/2 - (SCALE/scalet > 2 ? 5*scalet : 0);
/* If this is an aspect cell, draw glyph of aspect in effect. */
if (xbonus ? x > y : x < y) {
DrawColor(c = aspectcolor[grid->n[i][j]]);
DrawAspect(grid->n[i][j], turtlex, turtley);
/* If this is a midpoint cell, draw glyph of sign of midpoint. */
} else if (xbonus ? x < y : x > y) {
DrawColor(c = signcolor(grid->n[i][j]));
DrawSign(grid->n[i][j], turtlex, turtley);
/* For cells on main diagonal, draw glyph of planet. */
} else {
DrawColor(hilite);
DrawEdge((y-1)*unit, (y-1)*unit, y*unit, y*unit);
DrawObject(i, turtlex, turtley);
}
/* When the scale size is 300, we can print text in each cell: */
if (SCALE/scalet > 2 && xlabel) {
k = abs(grid->v[i][j]);
/* For the aspect portion, print the orb in degrees and minutes. */
if (xbonus ? x > y : x < y) {
if (grid->n[i][j])
sprintf(string, "%c%d %02d'", k != grid->v[i][j] ? '-' : '+',
k/60, k%60);
else
sprintf(string, "");
/* For the midpoint portion, print the degrees and minutes. */
} else if (xbonus ? x < y : x > y)
sprintf(string, "%2d %02d'", k/60, k%60);
/* For the main diagonal, print degree and sign of each planet. */
else {
c = signcolor(grid->n[i][j]);
sprintf(string, "%c%c%c %02d", SIGNAM(grid->n[i][j]), k);
}
DrawColor(c);
DrawText(string, x*unit-unit/2, y*unit-3*scalet, TRUE);
}
}
}
}
}
/* Draw the local horizon, and draw in the planets where they are at the */
/* time in question, as done when the -Z is combined with the -X switch. */
void XChartHorizon()
{
real lon, lat,
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,
x1, y1, x2, y2, xs, ys, i, j, k, l;
/* Make a slightly smaller rectangle within the window to draw the planets */
/* in. Make segments on all four edges marking 5 degree increments. */
x1 = y1 = unit/2; x2 = chartx-x1; y2 = charty-y1;
xs = x2-x1; ys = y2-y1;
DrawColor(hilite);
for (i = 0; i < 180; i += 5) {
j = y1+(int)((real)i*(real)ys/DEGHALF);
k = (2+(i%10 == 0)+2*(i%30 == 0))*scalet;
DrawLine(x1+1, j, x1+1+k, j);
DrawLine(x2-1, j, x2-1-k, j);
}
for (i = 0; i < DEGR; i += 5) {
j = x1+(int)((real)i*(real)xs/DEGREES);
k = (2+(i%10 == 0)+2*(i%30 == 0))*scalet;
DrawLine(j, y1+1, j, y1+1+k);
DrawLine(j, y2-1, j, y2-1-k);
}
/* Draw vertical lines dividing our rectangle into four areas. In our */
/* local space chart, the middle line represents due south, the left line */
/* due east, the right line due west, and the edges due north. A fourth */
/* horizontal line divides that which is above and below the horizon. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -