1 /* look up which star atlas an ra/dec is in.
2  * Urano and Mill contributed by Atsuo Ohki <ohki@gssm.otsuka.tsukuba.ac.jp>
3  * U2K by Robert Lane <roblane@alum.mit.edu>
4  *
5  * N.B. skylist.c assumes a certain max length for any returned string.
6  */
7 
8 #include <stdio.h>
9 #include <string.h>
10 
11 #include "astro.h"
12 
13 /* for Millennium Star Atlas */
14 static int msa_charts[] = {
15     /* 90*/  2, /* 84*/  4, /* 78*/  8, /* 72*/ 10, /* 66*/ 12,
16     /* 60*/ 14, /* 54*/ 16, /* 48*/ 20, /* 42*/ 20, /* 36*/ 22,
17     /* 30*/ 22, /* 24*/ 24, /* 18*/ 24, /* 12*/ 24, /*  6*/ 24,
18     /*  0*/ 24,
19     /* -6*/ 24, /*-12*/ 24, /*-18*/ 24, /*-24*/ 24, /*-30*/ 22,
20     /*-36*/ 22, /*-42*/ 20, /*-48*/ 20, /*-54*/ 16, /*-60*/ 14,
21     /*-66*/ 12, /*-72*/ 10, /*-78*/  8, /*-84*/  4, /*-90*/  2
22 };
23 
24 /*
25  * find the chart number of Millennium Star Atlas and return pointer to static
26  * string describing location.
27  * 0 <= ra < 24;  -90 <= dec <= 90
28  */
29 char *
msa_atlas(double ra,double dec)30 msa_atlas(double ra, double dec)
31 {
32 	static char buf[512];
33 	int zone, band;
34 	int i, p;
35 
36 	ra = radhr(ra);
37 	dec = raddeg(dec);
38 	buf[0] = 0;
39 	if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec)
40 	    return (buf);
41 	zone = (int)(ra/8.0);
42 	band = -((int)(dec+((dec>=0)?3:-3))/6 - 15);
43 	for (p=0, i=0; i <= band; i++)
44 	    p += msa_charts[i];
45 	i = (int)((ra - 8.0*zone) / (8.0/msa_charts[band]));
46 	sprintf(buf, "V%d - P%3d", zone+1, p-i+zone*516);
47 	return (buf);
48 }
49 
50 /* for original Uranometria */
51 static struct {
52     double l;
53     int n;
54 } um_zones[] = {
55     /* 84 - 90 */ { 84.5,  2},
56     /* 72 - 85 */ { 72.5, 12},
57     /* 60 - 73 */ { 61.0, 20},
58     /* 49 - 62 */ { 50.0, 24},
59     /* 38 - 51 */ { 39.0, 30},
60     /* 27 - 40 */ { 28.0, 36},
61     /* 16 - 29 */ { 17.0, 45},
62     /*  5 - 18 */ {  5.5, 45},
63     /*  0 -  6 */ {  0.0, 45},
64 		  {  0.0,  0}
65 };
66 
67 /*
68  * find the chart number of Uranometria first edition and return pointer to
69  * static string describing location.
70  * 0 <= ra < 24;  -90 <= dec <= 90
71  */
72 char *
um_atlas(double ra,double dec)73 um_atlas(double ra, double dec)
74 {
75 	static char buf[512];
76 	int band, south;
77 	int p;
78 	double w;
79 
80 	ra = radhr(ra);
81 	dec = raddeg(dec);
82 	buf[0] = 0;
83 	if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec)
84 	    return (buf);
85 	p = 0;
86 	if (dec < 0.0) {
87 	    dec = -dec;
88 	    south = 1;
89 	} else
90 	    south = 0;
91 	p = 1;
92 	for (band=0; um_zones[band].n; band++) {
93 	    if (um_zones[band].l <= dec)
94 		break;
95 	    p += um_zones[band].n;
96 	}
97 	if (!um_zones[band].n)
98 	    return (buf);
99 	w = 24.0 / um_zones[band].n;
100 	if (band) {
101 	    ra += w/2.0;
102 	    if (ra >= 24.0)
103 		ra -= 24.0;
104 	}
105 	if (south && um_zones[band+1].n)
106 	    p = 475 - p - um_zones[band].n;
107 	if (south && band == 0) {
108 	    /* south pole part is mis-ordered! */
109 	    ra = 24.0 - ra;
110 	}
111 	sprintf(buf, "V%d - P%3d", south+1, p+(int)(ra/w));
112 	return (buf);
113 }
114 
115 /* for Uranometria 2000.0 */
116 static struct {
117     double lowDec; 	/* lower dec cutoff */
118     int numZones;	/* number of panels (aka zones) */
119 
120 } u2k_zones[] = { /* array of book layout info */
121     /* 84 - 90 */ { 84.5,  1}, /* lower dec cutoff, # of panels in band */
122     /* 73 - 85 */ { 73.5,  6},
123     /* 62 - 74 */ { 62.0, 10},
124     /* 51 - 63 */ { 51.0, 12},
125     /* 40 - 52 */ { 40.0, 15},
126     /* 29 - 41 */ { 29.0, 18},
127     /* 17 - 30 */ { 17.0, 18},
128     /*  5 - 18 */ {  5.5, 20},
129     /*  0 -  6 */ {  0.0, 20},
130                   {  0.0,  0} /*numZones value in this line is a stopper.*/
131 };
132 
133 /* find the chart number of Uranometria 2000.0 and return pointer to static
134  * string describing location.
135  * 0 <= ra < 24;  -90 <= dec <= 90
136  */
137 char *
u2k_atlas(double ra,double dec)138 u2k_atlas(double ra, double dec)
139 {
140 	static char buf[512];
141 	static char err[] = "???";
142 	int band; 		/* index to array */
143 	int south;		/* flag for volume 2*/
144 	int panel;		/* panel number */
145 
146 	ra = radhr(ra);
147 	dec = raddeg(dec);
148 	buf[0] = 0;
149 	if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec) {
150 	    strcpy (buf, err);
151 	    return (buf); /* range checking */
152 	}
153 
154 	if (dec < 0.0) {
155 	    dec = -dec;
156 	    south = 1; /* South is mirror of North */
157 	} else
158 	    south = 0;
159 
160 	panel = 1;
161 	band = 0;
162 
163 	/* scan u2k_zones for the correct band: */
164 	while (u2k_zones[band].numZones != 0 && dec <= u2k_zones[band].lowDec ){
165 	    panel += u2k_zones[band].numZones; /*accumulate total panels */
166 	    band++ ;
167 	}
168 
169 	if (!u2k_zones[band].numZones) { /* hit end of array with no match. */
170 	    strcpy (buf, err);
171 	    return (buf);
172 	}
173 
174 	ra -= 12.0 / u2k_zones[band].numZones; /*offset by half-width of panel*/
175 	if (ra >= 24.0)			/* reality check. shouldn't happen. */
176 	    ra -= 24.0;
177 
178 	if (ra < 0.0)			/* offset could give negative ra */
179 	    ra += 24.0;
180 
181 	if (south && u2k_zones[band+1].numZones)
182 	    panel = 222 - panel - u2k_zones[band].numZones;
183 
184 	/* resultant panel number is accumulated panels in prior bands plus
185 	 * ra's fraction of panels in dec's band. panel # goes up as ra goes
186 	 * down.
187 	 */
188 	sprintf(buf, "V%d - P%3d", south+1,
189 	panel+(int)(u2k_zones[band].numZones*(24.0 - ra)/24.0));
190 
191 	return (buf);
192 }
193 
194 
195