?? xcharts.c
字號(hào):
/*
** Astrolog (Version 4.00) File: xcharts.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"
#ifdef GRAPH
/*
******************************************************************************
** Single Chart Graphics Subprograms.
******************************************************************************
*/
/* Given a string, draw it on the screen using the given color. The */
/* position of the text is based the saved positions of where we drew the */
/* text the last time the routine was called, being either directly below */
/* in the same column or in the same row just to the right. This is used */
/* by the sidebar drawing routine to print a list of text on the chart. */
int DrawPrint(string, m, n)
char *string;
int m, n;
{
static int x0, x, y;
if (string == NULL) { /* Null string means just initialize position. */
x0 = x = m; y = n;
return y;
}
if (y >= charty) /* Don't draw if we've scrolled off the chart bottom. */
return y;
DrawColor(m);
DrawText(string, x, y, -1);
/* If the second parameter is TRUE, we stay on the same line, otherwise */
/* when FALSE we go to the next line at the original column setting. */
if (n)
x += StringLen(string)*FONTX*scalet;
else {
x = x0;
n = y;
y += FONTY*scalet;
}
return y;
}
/* Print text showing the chart information and house and planet positions */
/* of a chart in a "sidebar" to the right of the chart in question. This */
/* is always done for the -v and -w graphic wheel charts unless the -v0 */
/* switch flag is also set, in which case none of the stuff here is done. */
void DrawInfo()
{
char string[STRING];
int elemode[4][3], elem[4], mo[3], tot, pos, abo, lef, lea, i, y, a, s;
#ifdef INTERPRET
/* Hack: Just for fun, if interpretation is active (which normally has */
/* no effect whatsoever on graphics) we'll decorate the chart a little. */
if (interpret) {
if (screenwidth & 1) {
/* If screenwidth value is odd, draw a moire pattern in each corner. */
abo = charty/(screenwidth/10);
lef = chartx/(screenwidth/10);
for (y = 0; y <= 1; y++)
for (i = 0; i <= 1; i++)
for (s = 0; s <= 1; s++)
for (a = 1; a < (s ? lef : abo)*2; a++) {
DrawColor(a & 1 ? gray : off);
DrawLine(i ? chartx-1-lef : lef, y ? charty-1-abo : abo,
s ? (i ? chartx-1-a : a) : i*(chartx-1),
s ? y*(charty-1) : (y ? charty-1-a : a));
}
} else {
/* If screenwidth is even, draw spider web lines in each corner. */
DrawColor(gray);
tot = screenwidth*3/20;
abo = charty/4;
lef = chartx/4;
for (y = 0; y <= 1; y++)
for (i = 0; i <= 1; i++)
for (a = 1; a < tot; a++)
DrawLine(i*(chartx-1), y ? (charty-1-a*abo/tot) : a*abo/tot,
i ? chartx-1-lef+a*lef/tot : lef-a*lef/tot, y*(charty-1));
}
}
#endif
if (!xtext || (exdisplay & DASHv0) > 0) /* Don't draw sidebar if */
return; /* -v0 flag is set. */
a = ansi;
ansi = FALSE;
seconds = -seconds;
DrawColor(hilite);
if (xborder)
DrawLine(chartx-1, 0, chartx-1, charty-1);
chartx += SIDET;
DrawPrint(NULL, chartx-SIDET+FONTX*scalet, FONTY*7/5*scalet);
/* Print chart header and setting information. */
sprintf(string, "%s %s", appname, VERSION);
DrawPrint(string, on, FALSE);
if (Mon == -1)
sprintf(string, "No time or space.");
else if (relation == DASHrc)
sprintf(string, "Composite chart.");
else {
sprintf(string, "%c%c%c %s", DAYNAM(DayOfWeek(Mon, Day, Yea)),
CharDate(Mon, Day, Yea, TRUE));
DrawPrint(string, hilite, FALSE);
DrawPrint(CharTime((int)floor(Tim), (int)(FRACT(dabs(Tim))*100.0)),
hilite, TRUE);
sprintf(string, " (%d:%02d GMT)", (int)(-Zon),
(int)(FRACT(dabs(Zon))*100.0+ROUND));
}
DrawPrint(string, hilite, FALSE);
DrawPrint(CharLocation(Lon, Lat, 100.0), hilite, FALSE);
sprintf(string, "%s houses.", systemname[housesystem]);
DrawPrint(string, hilite, FALSE);
sprintf(string, "%s zodiac.", operation & DASHs ? "Siderial" : "Tropical");
DrawPrint(string, hilite, FALSE);
sprintf(string, "Julian Day = %10.3f", JulianDayFromTime(T));
DrawPrint(string, hilite, FALSE);
/* Print house cusp positions. */
DrawPrint("", hilite, FALSE);
for (i = 1; i <= SIGNS; i++) {
sprintf(string, "%2d%s house: ", i, post[i]);
y = DrawPrint(string, signcolor(i), TRUE);
if (!seconds && (scale == 100 || !xfont || !xfile) && y < charty) {
s = scale;
scale = 100*scalet;
DrawSign(i, chartx-12*scalet, y-(FONTY/2-1)*scalet);
scale = s;
}
DrawPrint(CharZodiac(house[i]), signcolor(ZTOS(house[i])), FALSE);
}
/* Print planet positions. */
DrawPrint("", hilite, FALSE);
for (i = 1; i <= total; i++) if (!ignore[i]) {
sprintf(string, seconds ? "%3.3s: " : "%4.4s: ", objectname[i]);
DrawPrint(string, objectcolor[i], TRUE);
y = DrawPrint(CharZodiac(planet[i]), signcolor(ZTOS(planet[i])), TRUE);
if (!seconds && i < S_LO &&
(scale == 100 || !xfont || !xfile) && y < charty) {
s = scale;
scale = 100*scalet;
DrawObject(i, chartx-12*scalet, y-(FONTY/2-1)*scalet);
scale = s;
}
sprintf(string, "%c ", ret[i] < 0.0 ? 'R' : ' ');
DrawPrint(string, on, TRUE);
DrawPrint(CharAltitude(planetalt[i]), hilite, FALSE);
}
/* Print element table information. */
DrawPrint("", hilite, FALSE);
CreateElemTable(elemode, elem, mo, &tot, &pos, &abo, &lef, &lea);
sprintf(string, "Fire: %d, Earth: %d,", elem[_FIR], elem[_EAR]);
DrawPrint(string, hilite, FALSE);
sprintf(string, "Air : %d, Water: %d", elem[_AIR], elem[_WAT]);
DrawPrint(string, hilite, FALSE);
sprintf(string, "Car: %d, Fix: %d, Mut: %d", mo[0], mo[1], mo[2]);
DrawPrint(string, hilite, FALSE);
sprintf(string, "Yang: %d, Yin: %d", pos, tot-pos);
DrawPrint(string, hilite, FALSE);
sprintf(string, "N: %d, S: %d, W: %d, E: %d", abo, tot-abo, tot-lef, lef);
DrawPrint(string, hilite, FALSE);
seconds = -seconds;
ansi = a;
}
/* Draw a wheel chart, in which the 12 signs and houses are delineated, and */
/* the planets are inserted in their proper places. This is the default */
/* graphics chart to generate, as is done when the -v or -w (or no) switches */
/* are included with -X. Draw the aspects in the middle of chart, too. */
void XChartWheel()
{
real xsign[SIGNS+1], xhouse[SIGNS+1], xplanet[TOTAL+1], symbol[TOTAL+1];
int cx, cy, i, j;
real asc, orb = DEFORB*256.0/(real)charty*(real)SCALE,
unitx, unity, px, py, temp;
/* Set up variables and temporarily automatically decrease the horizontal */
/* chart size to leave room for the sidebar if that mode is in effect. */
if (xtext && !(exdisplay & DASHv0))
chartx -= SIDET;
cx = chartx/2 - 1; cy = charty/2 - 1;
unitx = (real)cx; unity = (real)cy;
asc = xeast ? planet[abs(xeast)]+90*(xeast < 0) : house[1];
InitCircle();
/* Fill out arrays with the angular degree on the circle of where to */
/* place each object, cusp, and sign glyph based on how the chart mode. */
if (modex == MODEv) {
for (i = 1; i <= SIGNS; i++)
xhouse[i] = PZ(house[i]);
} else {
asc -= house[1];
for (i = 1; i <= SIGNS; i++)
xhouse[i] = PZ(STOZ(i));
}
for (i = 1; i <= SIGNS; i++)
xsign[i] = PZ(XHousePlaceIn(STOZ(i)));
for (i = 1; i <= total; i++)
xplanet[i] = PZ(XHousePlaceIn(planet[i]));
/* Draw Ascendant/Descendant and Midheaven/Nadir lines across whole chart. */
DrawColor(hilite);
DrawDash(cx+POINT(unitx, 0.99, PX(xhouse[1])),
cy+POINT(unity, 0.99, PY(xhouse[1])),
cx+POINT(unitx, 0.99, PX(xhouse[7])),
cy+POINT(unity, 0.99, PY(xhouse[7])), !xcolor);
DrawDash(cx+POINT(unitx, 0.99, PX(xhouse[10])),
cy+POINT(unity, 0.99, PY(xhouse[10])),
cx+POINT(unitx, 0.99, PX(xhouse[4])),
cy+POINT(unity, 0.99, PY(xhouse[4])), !xcolor);
/* Draw small five or one degree increments around the zodiac sign ring. */
for (i = 0; i < DEGR; i += 5-(xcolor || psfile || metafile)*4) {
temp = PZ(XHousePlaceIn((real)i));
px = PX(temp); py = PY(temp);
DrawColor(i%5 ? gray : on);
DrawDash(cx+POINT(unitx, 0.75, px), cy+POINT(unity, 0.75, py),
cx+POINT(unitx, 0.80, px), cy+POINT(unity, 0.80, py),
((psfile || metafile) && i%5)*2);
}
/* Draw circles for the zodiac sign and house rings. */
DrawColor(on);
DrawCircle(cx, cy, (int)(unitx*0.95+ROUND), (int)(unity*0.95+ROUND));
DrawCircle(cx, cy, (int)(unitx*0.80+ROUND), (int)(unity*0.80+ROUND));
DrawCircle(cx, cy, (int)(unitx*0.75+ROUND), (int)(unity*0.75+ROUND));
DrawCircle(cx, cy, (int)(unitx*0.65+ROUND), (int)(unity*0.65+ROUND));
/* Draw the glyphs for the signs and houses themselves. */
for (i = 1; i <= SIGNS; i++) {
temp = xsign[i];
DrawColor(on);
DrawLine(cx+POINT(unitx, 0.95, PX(temp)), /* Draw lines separating */
cy+POINT(unity, 0.95, PY(temp)), /* each sign and house */
cx+POINT(unitx, 0.80, PX(temp)), /* from each other. */
cy+POINT(unity, 0.80, PY(temp)));
DrawLine(cx+POINT(unitx, 0.75, PX(xhouse[i])),
cy+POINT(unity, 0.75, PY(xhouse[i])),
cx+POINT(unitx, 0.65, PX(xhouse[i])),
cy+POINT(unity, 0.65, PY(xhouse[i])));
if (xcolor && i%3 != 1) { /* Lines from */
DrawColor(gray); /* each house */
DrawDash(cx, cy, cx+POINT(unitx, 0.65, PX(xhouse[i])), /* to center */
cy+POINT(unity, 0.65, PY(xhouse[i])), 1); /* of wheel. */
}
temp = Midpoint(temp, xsign[Mod12(i+1)]);
DrawColor(signcolor(i));
DrawSign(i, cx+POINT(unitx, 0.875, PX(temp)),
cy+POINT(unity, 0.875, PY(temp)));
temp = Midpoint(xhouse[i], xhouse[Mod12(i+1)]);
DrawHouse(i, cx+POINT(unitx, 0.70, PX(temp)),
cy+POINT(unity, 0.70, PY(temp)));
}
for (i = 1; i <= total; i++) /* Figure out where to put planet glyphs. */
symbol[i] = xplanet[i];
FillSymbolRing(symbol);
/* For each planet, draw a small dot indicating where it is, and then */
/* a line from that point to the planet's glyph. */
for (i = 1; i <= total; i++) if (Proper(i)) {
if (xlabel) {
temp = symbol[i];
DrawColor(ret[i] < 0.0 ? gray : on);
DrawDash(cx+POINT(unitx, 0.52, PX(xplanet[i])),
cy+POINT(unity, 0.52, PY(xplanet[i])),
cx+POINT(unitx, 0.56, PX(temp)),
cy+POINT(unity, 0.56, PY(temp)),
(ret[i] < 0.0 ? 1 : 0) - xcolor);
DrawObject(i, cx+POINT(unitx, 0.60, PX(temp)),
cy+POINT(unity, 0.60, PY(temp)));
} else
DrawColor(objectcolor[i]);
DrawPoint(cx+POINT(unitx, 0.50, PX(xplanet[i])),
cy+POINT(unity, 0.50, PY(xplanet[i])));
}
/* Draw lines connecting planets which have aspects between them. */
if (!xbonus) { /* Don't draw aspects in bonus mode. */
CreateGrid(FALSE);
for (j = total; j >= 2; j--)
for (i = j-1; i >= 1; i--)
if (grid->n[i][j] && Proper(i) && Proper(j)) {
DrawColor(aspectcolor[grid->n[i][j]]);
DrawDash(cx+POINT(unitx, 0.48, PX(xplanet[i])),
cy+POINT(unity, 0.48, PY(xplanet[i])),
cx+POINT(unitx, 0.48, PX(xplanet[j])),
cy+POINT(unity, 0.48, PY(xplanet[j])),
abs(grid->v[i][j]/60/2));
}
}
/* Go draw sidebar with chart information and positions if need be. */
DrawInfo();
}
/* Draw an astro-graph chart on a map of the world, i.e. the draw the */
/* Ascendant, Descendant, Midheaven, and Nadir lines corresponding to the */
/* time in the chart. This chart is done when the -L switch is combined */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -