home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / star.lzh / star.18 < prev    next >
Encoding:
Text File  |  1990-04-06  |  31.9 KB  |  1,103 lines

  1.  
  2. #! /bin/sh
  3. # This is a shell archive.  Remove anything before this line, then unpack
  4. # it by saving it into a file and typing "sh file".  To overwrite existing
  5. # files, type "sh file -c".  You can also feed this as standard input via
  6. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  7. # will see the following message at the end:
  8. #        "End of archive 18 (of 32)."
  9. # Contents:  starchart/ssup.c.ab
  10. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  11. if test -f 'starchart/ssup.c.ab' -a "${1}" != "-c" ; then 
  12.   echo shar: Will not clobber existing file \"'starchart/ssup.c.ab'\"
  13. else
  14. echo shar: Extracting \"'starchart/ssup.c.ab'\" \(30231 characters\)
  15. sed "s/^X//" >'starchart/ssup.c.ab' <<'END_OF_FILE'
  16. X  double xroot1, xroot2;
  17. X  double yr1, yr2, r1, r2;
  18. X  int n;
  19. X  int x1, y1;
  20. X  double lat_1, lon_1;
  21. X  int in;
  22. X
  23. X  if (fabs(x_2 - x_1) < 1e-5) {        /* Line has infinite slope */
  24. X    *x = x_1;
  25. X    *y = a*x_1*x_1 + b;
  26. X    *int_1 = TRUE;
  27. X  } else {                /* Line slope may be calculated */
  28. X    c = (y_2 - y_1)/(x_2 - x_1);
  29. X    d = y_1 - c * x_1;
  30. X    if (a < 1e-5) {            /* virtually a straight line y = b */
  31. X      if (fabs(c) < 1e-5) {        /* Constant y */
  32. X    n = 0;
  33. X      } else {
  34. X    xroot1 = (b - d)/c;
  35. X    n = 1;
  36. X      };
  37. X    } else {
  38. X      quadrat(a, -c, b-d, &xroot1, &xroot2, &n);
  39. X    };
  40. X    if (n == 0) {            /* No intersection */
  41. X      *int_1 = FALSE;
  42. X    } else if (n == 1) {        /* One intersection */
  43. X      *x = xroot1;
  44. X      *y = a*xroot1*xroot1 + b;
  45. X      *int_1 = TRUE;
  46. X    } else {                /* Two intersections */
  47. X      yr1 = c*xroot1 + d;
  48. X      yr2 = c*xroot2 + d;
  49. X      r1 = (xroot1-x_1)*(xroot1-x_1) + (yr1-y_1)*(yr1-y_1)
  50. X        + (xroot1-x_2)*(xroot1-x_2) + (yr1-y_2)*(yr1-y_2);
  51. X      r2 = (xroot2-x_1)*(xroot2-x_1) + (yr2-y_1)*(yr2-y_1)
  52. X        + (xroot2-x_2)*(xroot2-x_2) + (yr2-y_2)*(yr2-y_2);
  53. X      if (r1 > r2) {
  54. X    *x = xroot2;
  55. X    *y = yr2;
  56. X    *int_1 = TRUE;
  57. X      } else {
  58. X    *x = xroot1;
  59. X    *y = yr1;
  60. X    *int_1 = TRUE;
  61. X      };
  62. X    }
  63. X  }
  64. X
  65. X  if (*int_1)
  66. X    if (((((y_1-Fuz) <= *y) && (*y <= (y_2+Fuz)))
  67. X     || (((y_2-Fuz) <= *y) && (*y <= (y_1+Fuz))))
  68. X    && ((((x_1-Fuz) <= *x) && (*x <= (x_2+Fuz)))
  69. X        || (((x_2-Fuz) <= *x) && (*x <= (x_1+Fuz)))))
  70. X      *int_1 = TRUE;
  71. X    else
  72. X      *int_1 = FALSE;
  73. X
  74. X  if (*int_1) {
  75. X    inv_gt(*x, *y, &lat_1, &lon_1);
  76. X    xform(lat_1, lon_1, &x1, &y1, &in);
  77. X    if (!in) *int_1 = FALSE;
  78. X  }
  79. X}
  80. X
  81. X
  82. Xellip_intersect(x_1, y_1, x_2, y_2, a, b, y0, x, y, int_1)
  83. X     double x_1, y_1, x_2, y_2, *x, *y;
  84. X     double a, b, y0;        /* x*x/a + (y-y0)*(y-y0)/b - 1 = 0 */
  85. X     int *int_1;
  86. X{
  87. X  double c, d;
  88. X  double xroot1, xroot2;
  89. X  double yr1, yr2, r1, r2;
  90. X  int n;
  91. X  int x1, y1;
  92. X  double lat_1, lon_1;
  93. X  int in;
  94. X
  95. X  if (fabs(x_2 - x_1) < 1e-5) {        /* Line has infinite slope */
  96. X    xroot1 = xroot2 = *x = x_1;
  97. X    if (x_1*x_1/a > 1.0) {
  98. X      n = 0;
  99. X      *int_1 = FALSE;
  100. X    } else if (x_1*x_1/a == 1.0) {
  101. X      yr1 = y0;
  102. X      n = 1;
  103. X      *int_1 = TRUE;
  104. X    } else {
  105. X      yr1 = y0 + sqrt(b*(1 - x_1*x_1/a));
  106. X      yr2 = y0 - sqrt(b*(1 - x_1*x_1/a));
  107. X      n = 2;
  108. X      *int_1 = TRUE;
  109. X    }
  110. X  } else {                /* Line slope may be calculated */
  111. X    c = (y_2 - y_1)/(x_2 - x_1);
  112. X    d = y_1 - c * x_1;
  113. X    quadrat(b + a*c*c, 2*a*c*(d - y0), a*(d - y0)*(d - y0) - a*b,
  114. X        &xroot1, &xroot2, &n);
  115. X    if (n == 0) {        /* No intersection */
  116. X      *int_1 = FALSE;
  117. X    } else if (n == 1) {    /* One intersection */
  118. X      *x = xroot1;
  119. X      *y = c*xroot1 + d;
  120. X      *int_1 = TRUE;
  121. X    } else {            /* Two intersections */
  122. X      yr1 = c*xroot1 + d;
  123. X      yr2 = c*xroot2 + d;
  124. X      *int_1 = TRUE;
  125. X    };
  126. X  };
  127. X
  128. X  
  129. X  if (n == 2) {
  130. X    r1 = (xroot1-x_1)*(xroot1-x_1) + (yr1-y_1)*(yr1-y_1)
  131. X          + (xroot1-x_2)*(xroot1-x_2) + (yr1-y_2)*(yr1-y_2);
  132. X    r2 = (xroot2-x_1)*(xroot2-x_1) + (yr2-y_1)*(yr2-y_1)
  133. X          + (xroot2-x_2)*(xroot2-x_2) + (yr2-y_2)*(yr2-y_2);
  134. X    if (r1 > r2) {
  135. X      *x = xroot2;
  136. X      *y = yr2;
  137. X      *int_1 = TRUE;
  138. X    } else {
  139. X      *x = xroot1;
  140. X      *y = yr1;
  141. X      *int_1 = TRUE;
  142. X    }
  143. X  }
  144. X
  145. X  if (*int_1)
  146. X    if ((((y_1 <= *y) && (*y <= y_2)) || ((y_2 <= *y) && (*y <= y_1)))
  147. X    && (((x_1 <= *x) && (*x <= x_2)) || ((x_2 <= *x) && (*x <= x_1))))
  148. X      *int_1 = TRUE;
  149. X    else
  150. X      *int_1 = FALSE;
  151. X
  152. X  if (*int_1) {
  153. X    inv_gt(*x, *y, &lat_1, &lon_1);
  154. X    xform(lat_1, lon_1, &x1, &y1, &in);
  155. X    if (!in) *int_1 = FALSE;
  156. X  }
  157. X}
  158. X
  159. X
  160. Xcirc_intersect(x_1, y_1, x_2, y_2, r, x1, y1, int_1, x2, y2, int_2)
  161. X     double x_1, y_1, x_2, y_2, *x1, *y1, *x2, *y2;
  162. X     double r;
  163. X     int *int_1, *int_2;
  164. X{
  165. X  double c, d;
  166. X  double xroot1, xroot2;
  167. X  double yr1, yr2, r1, r2;
  168. X  int n;
  169. X  int xt1, yt1;
  170. X  double lat_1, lon_1;
  171. X  int in;
  172. X
  173. X  if (fabs(x_2 - x_1) < 1e-5) {        /* Line has infinite slope */
  174. X    xroot1 = xroot2 = *x1 = *x2 = x_1;
  175. X    if (fabs(r) > fabs(x_1)) {
  176. X      yr1 = sqrt(r*r - x_1*x_1);
  177. X      yr2 = -yr1;
  178. X      n = 2;
  179. X      *int_1 = *int_2 = TRUE;
  180. X    } else if (fabs(r) == fabs(x_1)) {
  181. X      yr1 = 0;
  182. X      n = 1;
  183. X      *int_1 = *int_2 = TRUE;
  184. X    } else {
  185. X      n = 0;
  186. X      *int_1 = *int_2 = FALSE;
  187. X    };
  188. X  } else {                /* Line slope may be calculated */
  189. X    c = (y_2 - y_1)/(x_2 - x_1);
  190. X    d = y_1 - c * x_1;
  191. X    quadrat(1 + c*c, 2*c*d, d*d - r*r,
  192. X        &xroot1, &xroot2, &n);
  193. X    if (n == 0) {        /* No intersection */
  194. X      *int_1 = *int_2 = FALSE;
  195. X    } else if (n == 1) {    /* One intersection */
  196. X      *x1 = xroot1;
  197. X      *y1 = c*xroot1 + d;
  198. X      *int_1 = TRUE;
  199. X      *int_2 = FALSE;
  200. X    } else {            /* Two intersections */
  201. X      yr1 = c*xroot1 + d;
  202. X      yr2 = c*xroot2 + d;
  203. X      *int_1 = *int_2 = TRUE;
  204. X    };
  205. X  };
  206. X
  207. X  if (n == 2) {
  208. X    r1 = (xroot1-x_1)*(xroot1-x_1) + (yr1-y_1)*(yr1-y_1)
  209. X          + (xroot1-x_2)*(xroot1-x_2) + (yr1-y_2)*(yr1-y_2);
  210. X    r2 = (xroot2-x_1)*(xroot2-x_1) + (yr2-y_1)*(yr2-y_1)
  211. X          + (xroot2-x_2)*(xroot2-x_2) + (yr2-y_2)*(yr2-y_2);
  212. X    if (r1 > r2) {
  213. X      *x1 = xroot2;
  214. X      *y1 = yr2;
  215. X      *x2 = xroot1;
  216. X      *y2 = yr1;
  217. X      *int_1 = *int_2 = TRUE;
  218. X    } else {
  219. X      *x1 = xroot1;
  220. X      *y1 = yr1;
  221. X      *x2 = xroot2;
  222. X      *y2 = yr2;
  223. X      *int_1 = *int_2 = TRUE;
  224. X    }
  225. X  }
  226. X
  227. X  if (*int_1)
  228. X    if ((((y_1 <= *y1) && (*y1 <= y_2)) || ((y_2 <= *y1) && (*y1 <= y_1)))
  229. X    && (((x_1 <= *x1) && (*x1 <= x_2)) || ((x_2 <= *x1) && (*x1 <= x_1))))
  230. X      *int_1 = TRUE;
  231. X    else
  232. X      *int_1 = FALSE;
  233. X
  234. X  if (*int_1) {
  235. X    inv_gt(*x1, *y1, &lat_1, &lon_1);
  236. X    xform(lat_1, lon_1, &xt1, &yt1, &in);
  237. X    if (!in) *int_1 = FALSE;
  238. X  }
  239. X
  240. X  if (*int_2)
  241. X    if ((((y_1 <= *y2) && (*y2 <= y_2)) || ((y_2 <= *y2) && (*y2 <= y_1)))
  242. X    && (((x_1 <= *x2) && (*x2 <= x_2)) || ((x_2 <= *x2) && (*x2 <= x_1))))
  243. X      *int_2 = TRUE;
  244. X    else
  245. X      *int_2 = FALSE;
  246. X
  247. X  if (*int_2) {
  248. X    inv_gt(*x2, *y2, &lat_1, &lon_1);
  249. X    xform(lat_1, lon_1, &xt1, &yt1, &in);
  250. X    if (!in) *int_2 = FALSE;
  251. X  }
  252. X}
  253. X
  254. X
  255. Xquadrat(a, b, c, x_1, x_2, n)
  256. X     double a, b, c, *x_1, *x_2;
  257. X     int *n;
  258. X{
  259. X  double t;
  260. X
  261. X  if (a == 0) {
  262. X    *n = 0;
  263. X  } else {
  264. X    t = b * b - 4 * a * c;
  265. X    if (t < 0) {
  266. X      *n = 0;
  267. X    } else if (t == 0) {
  268. X      *x_1 = -b/(2*a);
  269. X      *n = 1;
  270. X    } else {
  271. X      *x_1 = (-b + sqrt(t))/(2*a);
  272. X      *x_2 = (-b - sqrt(t))/(2*a);
  273. X      *n = 2;
  274. X    };
  275. X  };
  276. X}
  277. X
  278. X/* Draw a curved line between points 1 and 2.
  279. Xclipxform has been called, xloc1, yloc1, xloc2, yloc2 are in bounds */
  280. X
  281. Xdrawcurveline(lat1, lon1, lat2, lon2,
  282. X          xloc1, yloc1, xloc2, yloc2, line_style, great_circle, clevel)
  283. X     int xloc1, yloc1, xloc2, yloc2;
  284. X     double lat1, lon1, lat2, lon2;
  285. X     int line_style;
  286. X     int great_circle;     /* draw as great circle */
  287. X     int clevel;         /* safety valve */
  288. X{
  289. X  double mlat, mlon;    /* midpoint lat and long */
  290. X  double tlat1, tlat2;    /* temporary */
  291. X  int txloc1, tyloc1, in;
  292. X  int txloc2, tyloc2;
  293. X  double slope1;
  294. X  int mxloc, myloc;    /* transformed */
  295. X  int mpx, mpy;        /* from given x,y */
  296. X  int inregion;
  297. X
  298. X/* ra difference should be less than 180 degrees: take shortest path */
  299. X  if ((xfs_proj_mode == STEREOGR) || (xfs_proj_mode == GNOMONIC)
  300. X      || (xfs_proj_mode == ORTHOGR))
  301. X    if ((lon1 - lon2) > 180.0) lon1 -= 360.0;
  302. X    else if ((lon2 - lon1) > 180.0) lon2 -= 360.0;
  303. X
  304. X/* Adjust so lon1 and lon2 are continuous across region: see xform */
  305. X/* needed so midpoint is correct */
  306. X  if ((xfs_proj_mode == SANSONS) || (xfs_proj_mode == RECTANGULAR)) {
  307. X    if ((xf_west < 0.0) && (lon1>(xf_west+360.0))) lon1 -= 360.0;
  308. X    if ((xf_east > 360.0) && (lon1<(xf_east-360.0))) lon1 += 360.0;
  309. X    if ((xf_west < 0.0) && (lon2>(xf_west+360.0))) lon2 -= 360.0;
  310. X    if ((xf_east > 360.0) && (lon2<(xf_east-360.0))) lon2 += 360.0;
  311. X
  312. X    /* path crosses boundary of map */
  313. X    /* if the distance from point1 to left (East) + point2 to right
  314. X       or point2 to right and point2 to left
  315. X       is less than distance from point1 to point2,
  316. X       then we have a problem. */
  317. X    if (xfs_wide_warn)
  318. X      if ((fabs(lon1-xf_east) + fabs(xf_west-lon2)) < (fabs(lon1-lon2))) {
  319. X    slope1 = (lat2 - lat1)/(fabs(lon1-xf_east) + fabs(xf_west-lon2));
  320. X
  321. X    tlat1 = lat1 + slope1 * fabs(lon1-(xf_east-xf_c_scale));
  322. X    xform(tlat1, xf_east-xf_c_scale, &txloc1, &tyloc1, &in);
  323. X    drawcurveline(lat1, lon1, tlat1, xf_east-xf_c_scale, xloc1, yloc1,
  324. X              txloc1, tyloc1, line_style, great_circle, 0);
  325. X
  326. X    tlat2 = lat2 - slope1 * fabs(lon2-(xf_west+xf_c_scale));
  327. X    xform(tlat2, xf_west+xf_c_scale, &txloc2, &tyloc2, &in);
  328. X    drawcurveline(tlat2, xf_west+xf_c_scale, lat2, lon2, txloc2, tyloc2,
  329. X              xloc2, yloc2, line_style, great_circle, 0);
  330. X    return;
  331. X      } else if ((fabs(lon2-xf_east)+fabs(xf_west-lon1)) < (fabs(lon1-lon2))) {
  332. X    slope1 = (lat1 - lat2)/(fabs(lon2-xf_east) + fabs(xf_west-lon1));
  333. X
  334. X    tlat1 = lat2 + slope1 * fabs(lon2-(xf_east-xf_c_scale));
  335. X    xform(tlat1, xf_east-xf_c_scale, &txloc1, &tyloc1, &in);
  336. X    drawcurveline(lat2, lon2, tlat1, xf_east-xf_c_scale, xloc2, yloc2, 
  337. X              txloc1, tyloc1, line_style, great_circle, 0);
  338. X
  339. X    tlat2 = lat1 - slope1 * fabs(lon1-(xf_west+xf_c_scale));
  340. X    xform(tlat2, xf_west+xf_c_scale, &txloc2, &tyloc2, &in);
  341. X    drawcurveline(tlat2, xf_west+xf_c_scale, lat1, lon1, txloc2, tyloc2,
  342. X              xloc1, yloc1, line_style, great_circle, 0);
  343. X    return;
  344. X      };
  345. X  }
  346. X
  347. X
  348. X  if (great_circle) {
  349. X    gcmidpoint(lat1, lon1, lat2, lon2, &mlat, &mlon);
  350. X  } else {
  351. X    mlat = (lat1 + lat2)/2;
  352. X    mlon = (lon1 + lon2)/2;
  353. X  };
  354. X
  355. X
  356. X
  357. X  xform(mlat, mlon, &mxloc, &myloc, &inregion);
  358. X
  359. X  mpx = (xloc1 + xloc2)/2;
  360. X  mpy = (yloc1 + yloc2)/2;
  361. X
  362. X  if (((abs(mpx - mxloc) + abs(mpy - myloc)) > 0) && (clevel < 100)) {
  363. X    /* center is not where it should be */
  364. X    drawcurveline(lat1, lon1, mlat, mlon, xloc1, yloc1,
  365. X          mxloc, myloc, line_style, great_circle, ++clevel);
  366. X    drawcurveline(mlat, mlon, lat2, lon2, mxloc, myloc,
  367. X          xloc2, yloc2, line_style, great_circle, ++clevel);
  368. X  } else {
  369. X    D_movedraw(xloc1, yloc1, xloc2, yloc2, line_style);
  370. X  }
  371. X}
  372. X
  373. Xgcmidpoint(lat1, lon1, lat2, lon2, pmlat, pmlon)
  374. X     double lat1, lon1, lat2, lon2, *pmlat, *pmlon;
  375. X{
  376. X  double l1, m1, n1;
  377. X  double l2, m2, n2;
  378. X  double l3, m3, n3;
  379. X
  380. X  /* transform from (ra, dec) to l m n direction cosines */
  381. X  l1 = DCOS(lat1)*DCOS(lon1);
  382. X  m1 = DCOS(lat1)*DSIN(lon1);
  383. X  n1 = DSIN(lat1);
  384. X
  385. X  l2 = DCOS(lat2)*DCOS(lon2);
  386. X  m2 = DCOS(lat2)*DSIN(lon2);
  387. X  n2 = DSIN(lat2);
  388. X
  389. X  l3 = l1 + l2;
  390. X  m3 = m1 + m2;
  391. X  n3 = n1 + n2;
  392. X  n3 /= sqrt(l3*l3 + m3*m3 + n3*n3);
  393. X
  394. X  *pmlon = atan2(m3, l3) / 0.0174532925199;
  395. X  if ((*pmlon < 0) && (lon1 > 0) && (lon2 > 0)) *pmlon += 360.0;
  396. X  *pmlat = asin(n3) / 0.0174532925199;
  397. X}
  398. X
  399. X
  400. X
  401. X/* Area handling */
  402. X/* Works often, but is far from rigorous */
  403. Xstatic struct t_area_struct {
  404. X  double lat, lon;
  405. X  int great_circle;
  406. X  int clipped_at;
  407. X} area_raw[100], area_clip[200], area_1[200], area_2[200];
  408. Xstatic int nsegments = 0, nseg_clip = 0, nseg_1 = 0, nseg_2 = 0;
  409. X
  410. Xareastart(lat, lon, great_circle)
  411. X     double lat, lon;
  412. X     int great_circle;
  413. X{
  414. X  if (nsegments != 0)
  415. X    areafinish();
  416. X
  417. X  nsegments = 0;
  418. X  area_raw[nsegments].lat = lat;
  419. X  area_raw[nsegments].lon = lon;
  420. X  area_raw[nsegments].great_circle = great_circle;
  421. X  nsegments++;
  422. X}
  423. X
  424. X
  425. Xareaadd(lat, lon, great_circle)
  426. X     double lat, lon;
  427. X     int great_circle;
  428. X{
  429. X  area_raw[nsegments].lat = lat;
  430. X  area_raw[nsegments].lon = lon;
  431. X  area_raw[nsegments].great_circle = great_circle;
  432. X  nsegments++;
  433. X}
  434. X
  435. Xint wrap_area();
  436. X
  437. Xareafinish()
  438. X{
  439. X  int i;
  440. X  int xloc, yloc, xloc2, yloc2;
  441. X  int inregion;
  442. X  double tlat1, tlon1, tlat2, tlon2, tlat3, tlon3, tlat4, tlon4;
  443. X  double slope1;
  444. X  int done, old_n;
  445. X  int curr_area;
  446. X  int gt12;
  447. X  int wraps;
  448. X  int done_clip;
  449. X  done_clip = FALSE;
  450. X  nseg_clip = nseg_1 = nseg_2 = 0;
  451. X  wraps = FALSE;
  452. X
  453. X
  454. X  /* skip if no point is within region */
  455. X  done = TRUE;
  456. X  for (i = 0; i < nsegments; i++) {
  457. X    xform(area_raw[i].lat, area_raw[i].lon, &xloc, &yloc, &inregion);
  458. X    if (inregion) done = FALSE;
  459. X  };
  460. X  if (done) return;
  461. X
  462. X  if ((xfs_proj_mode == SANSONS) || (xfs_proj_mode == RECTANGULAR)) {
  463. X    if (xfs_wide_warn)
  464. X      for (i = 0; i < (nsegments - 1); i++)
  465. X    if (wrap_area(area_raw[i].lat, area_raw[i].lon,
  466. X              area_raw[i+1].lat, area_raw[i+1].lon, 
  467. X              &tlat1, &tlon1, &tlat2, &tlon2))
  468. X      wraps = TRUE;
  469. X
  470. X    if (!xfs_wide_warn) {
  471. X      /* Use algorithm to clip area_raw to rectangular region */
  472. X      /* Use area_1 and area_2 as scratch */
  473. X
  474. X      /* clip against west from area_raw to area_1 */
  475. X      tlat1 = area_raw[nsegments-1].lat;
  476. X      tlon1 = area_raw[nsegments-1].lon;
  477. X      for (i = 0, nseg_1 = 0; i < nsegments; i++) {
  478. X    tlat4 = area_raw[i].lat;
  479. X    tlon4 = area_raw[i].lon;
  480. X
  481. X    if (eastof(tlon4, xf_west)) {
  482. X      if (eastof(tlon1, xf_west)) {
  483. X        /* last point and new point (4) are in, add new point */
  484. X      } else {
  485. X        /* new point in, but old out.
  486. X         Calculate intersection point (2), add it and new point */
  487. X        slope1 = (tlat4 - tlat1) / (tlon4 - tlon1);
  488. X
  489. X        tlat2 = tlat1 + slope1 * (xf_west-tlon1);
  490. X        tlon2 = xf_west;
  491. X        area_1[nseg_1].lat = tlat2;
  492. X        area_1[nseg_1].lon = tlon2;
  493. X        area_1[nseg_1].great_circle = area_raw[i].great_circle;
  494. X        area_1[nseg_1].clipped_at = WEST_CLIP;
  495. X        nseg_1++;
  496. X      }
  497. X      area_1[nseg_1].lat = tlat4;
  498. X      area_1[nseg_1].lon = tlon4;
  499. X      area_1[nseg_1].great_circle = area_raw[i].great_circle;
  500. X      area_1[nseg_1].clipped_at = 0;
  501. X      nseg_1++;
  502. X    } else {
  503. X      if (eastof(tlon1, xf_west)) {
  504. X        /* new point out, but old point in.
  505. X           Calculate intersection and add it */
  506. X        slope1 = (tlat4 - tlat1) / (tlon4 - tlon1);
  507. X
  508. X        tlat2 = tlat1 + slope1 * (xf_west-tlon1);
  509. X        tlon2 = xf_west;
  510. X        area_1[nseg_1].lat = tlat2;
  511. X        area_1[nseg_1].lon = tlon2;
  512. X        area_1[nseg_1].great_circle = area_raw[i].great_circle;
  513. X        area_1[nseg_1].clipped_at = WEST_CLIP;
  514. X        nseg_1++;
  515. X      }
  516. X    }
  517. X    tlat1 = tlat4;
  518. X    tlon1 = tlon4;
  519. X      }
  520. X
  521. X
  522. X      /* clip against south from area_1 to area_2 */
  523. X      tlat1 = area_1[nseg_1-1].lat;
  524. X      tlon1 = area_1[nseg_1-1].lon;
  525. X      for (i = 0, nseg_2 = 0; i < nseg_1; i++) {
  526. X    tlat4 = area_1[i].lat;
  527. X    tlon4 = area_1[i].lon;
  528. X
  529. X    if (tlat4 > xf_south) {
  530. X      if (tlat1 > xf_south) {
  531. X        /* last point and new point (4) are in, add new point */
  532. X      } else {
  533. X        /* new point in, but old out.
  534. X         Calculate intersection point (2), add it and new point */
  535. X        slope1 = (tlon4 - tlon1) / (tlat4 - tlat1);
  536. X
  537. X        tlat2 = xf_south;
  538. X        tlon2 = tlon1 + slope1 * (xf_south-tlat1);
  539. X        area_2[nseg_2].lat = tlat2;
  540. X        area_2[nseg_2].lon = tlon2;
  541. X        area_2[nseg_2].great_circle = area_1[i].great_circle;
  542. X        area_2[nseg_2].clipped_at = SOUTH_CLIP;
  543. X        nseg_2++;
  544. X      }
  545. X      area_2[nseg_2].lat = tlat4;
  546. X      area_2[nseg_2].lon = tlon4;
  547. X      area_2[nseg_2].great_circle = area_1[i].great_circle;
  548. X      area_2[nseg_2].clipped_at = 0;
  549. X      nseg_2++;
  550. X    } else {
  551. X      if (tlat1 > xf_south) {
  552. X        /* new point out, but old point in.
  553. X           Calculate intersection and add it */
  554. X        slope1 = (tlon4 - tlon1) / (tlat4 - tlat1);
  555. X
  556. X        tlat2 = xf_south;
  557. X        tlon2 = tlon1 + slope1 * (xf_south-tlat1);
  558. X        area_2[nseg_2].lat = tlat2;
  559. X        area_2[nseg_2].lon = tlon2;
  560. X        area_2[nseg_2].great_circle = area_1[i].great_circle;
  561. X        area_2[nseg_2].clipped_at = SOUTH_CLIP;
  562. X        nseg_2++;
  563. X      }
  564. X    }
  565. X    tlat1 = tlat4;
  566. X    tlon1 = tlon4;
  567. X      }
  568. X
  569. X      /* clip against east from area_2 to area_1 */
  570. X      tlat1 = area_2[nseg_2-1].lat;
  571. X      tlon1 = area_2[nseg_2-1].lon;
  572. X      for (i = 0, nseg_1 = 0; i < nseg_2; i++) {
  573. X    tlat4 = area_2[i].lat;
  574. X    tlon4 = area_2[i].lon;
  575. X
  576. X    if (westof(tlon4, xf_east)) {
  577. X      if (westof(tlon1, xf_east)) {
  578. X        /* last point and new point (4) are in, add new point */
  579. X      } else {
  580. X        /* new point in, but old out.
  581. X         Calculate intersection point (2), add it and new point */
  582. X        slope1 = (tlat4 - tlat1) / (tlon4 - tlon1);
  583. X
  584. X        tlat2 = tlat1 + slope1 * (xf_east-tlon1);
  585. X        tlon2 = xf_east;
  586. X        area_1[nseg_1].lat = tlat2;
  587. X        area_1[nseg_1].lon = tlon2;
  588. X        area_1[nseg_1].great_circle = area_2[i].great_circle;
  589. X        area_1[nseg_1].clipped_at = EAST_CLIP;
  590. X        nseg_1++;
  591. X      }
  592. X      area_1[nseg_1].lat = tlat4;
  593. X      area_1[nseg_1].lon = tlon4;
  594. X      area_1[nseg_1].great_circle = area_2[i].great_circle;
  595. X      area_1[nseg_1].clipped_at = 0;
  596. X      nseg_1++;
  597. X    } else {
  598. X      if (westof(tlon1, xf_east)) {
  599. X        /* new point out, but old point in.
  600. X           Calculate intersection and add it */
  601. X        slope1 = (tlat4 - tlat1) / (tlon4 - tlon1);
  602. X
  603. X        tlat2 = tlat1 + slope1 * (xf_east-tlon1);
  604. X        tlon2 = xf_east;
  605. X        area_1[nseg_1].lat = tlat2;
  606. X        area_1[nseg_1].lon = tlon2;
  607. X        area_1[nseg_1].great_circle = area_2[i].great_circle;
  608. X        area_1[nseg_1].clipped_at = EAST_CLIP;
  609. X        nseg_1++;
  610. X      }
  611. X    }
  612. X    tlat1 = tlat4;
  613. X    tlon1 = tlon4;
  614. X      }
  615. X
  616. X      /* clip against north from area_1 to area_clip */
  617. X      tlat1 = area_1[nseg_1-1].lat;
  618. X      tlon1 = area_1[nseg_1-1].lon;
  619. X      for (i = 0, nseg_clip = 0; i < nseg_1; i++) {
  620. X    tlat4 = area_1[i].lat;
  621. X    tlon4 = area_1[i].lon;
  622. X
  623. X    if (tlat4 < xf_north) {
  624. X      if (tlat1 < xf_north) {
  625. X        /* last point and new point (4) are in, add new point */
  626. X      } else {
  627. X        /* new point in, but old out.
  628. X         Calculate intersection point (2), add it and new point */
  629. X        slope1 = (tlon4 - tlon1) / (tlat4 - tlat1);
  630. X
  631. X        tlat2 = xf_north;
  632. X        tlon2 = tlon1 + slope1 * (xf_north-tlat1);
  633. X        area_clip[nseg_clip].lat = tlat2;
  634. X        area_clip[nseg_clip].lon = tlon2;
  635. X        area_clip[nseg_clip].great_circle = area_1[i].great_circle;
  636. X        area_clip[nseg_clip].clipped_at = NORTH_CLIP;
  637. X        nseg_clip++;
  638. X      }
  639. X      area_clip[nseg_clip].lat = tlat4;
  640. X      area_clip[nseg_clip].lon = tlon4;
  641. X      area_clip[nseg_clip].great_circle = area_1[i].great_circle;
  642. X      area_clip[nseg_clip].clipped_at = 0;
  643. X      nseg_clip++;
  644. X    } else {
  645. X      if (tlat1 < xf_north) {
  646. X        /* new point out, but old point in.
  647. X           Calculate intersection and add it */
  648. X        slope1 = (tlon4 - tlon1) / (tlat4 - tlat1);
  649. X
  650. X        tlat2 = xf_north;
  651. X        tlon2 = tlon1 + slope1 * (xf_north-tlat1);
  652. X        area_clip[nseg_clip].lat = tlat2;
  653. X        area_clip[nseg_clip].lon = tlon2;
  654. X        area_clip[nseg_clip].great_circle = area_1[i].great_circle;
  655. X        area_clip[nseg_clip].clipped_at = NORTH_CLIP;
  656. X        nseg_clip++;
  657. X      }
  658. X    }
  659. X    tlat1 = tlat4;
  660. X    tlon1 = tlon4;
  661. X      }
  662. X
  663. X      if ((area_clip[0].lat != area_clip[nseg_clip-1].lat)
  664. X      || (area_clip[0].lon != area_clip[nseg_clip-1].lon)) {
  665. X    area_clip[nseg_clip].lat = area_clip[0].lat;
  666. X    area_clip[nseg_clip].lon = area_clip[0].lon;
  667. X    area_clip[nseg_clip].great_circle = area_raw[i].great_circle;
  668. X    area_clip[nseg_clip].clipped_at = WEST_CLIP;
  669. X    nseg_clip++;
  670. X      }
  671. X
  672. X      if (nseg_clip > 0) doarea(area_clip, nseg_clip);
  673. X
  674. X      done_clip = TRUE;
  675. X    };
  676. X  };
  677. X
  678. X  if (!done_clip) {
  679. X    /* Scan list of segments, constructing clipped polygon */
  680. X    for (i = 0; i < (nsegments - 1); i++) {
  681. X      if (clipr_xform(area_raw[i].lat, area_raw[i].lon,
  682. X              area_raw[i+1].lat, area_raw[i+1].lon, 
  683. X              &xloc, &yloc, &xloc2, &yloc2, area_raw[i+1].great_circle,
  684. X              &tlat1, &tlon1, &tlat2, &tlon2)) {
  685. X    addsegment(tlat1, tlon1, tlat2, tlon2,
  686. X           (nseg_clip > 0) ? area_clip[nseg_clip-1].clipped_at : 0,
  687. X           clip_at1, clip_at2,
  688. X           area_raw[i].great_circle, area_raw[i+1].great_circle);
  689. X      };
  690. X    };
  691. X
  692. X    /* ensure that area is closed. */
  693. X    /* redraw first segment */
  694. X    if ((nseg_clip > 0) && ((area_clip[nseg_clip-1].lat != area_clip[0].lat)
  695. X               || (area_clip[nseg_clip-1].lon != area_clip[0].lon))) {
  696. X      i = 0;
  697. X      done = FALSE;
  698. X      old_n = nseg_clip;
  699. X      do {
  700. X    if (clipr_xform(area_raw[i].lat, area_raw[i].lon,
  701. X            area_raw[i+1].lat, area_raw[i+1].lon, 
  702. X            &xloc, &yloc, &xloc2, &yloc2,
  703. X            area_raw[i+1].great_circle,
  704. X            &tlat1, &tlon1, &tlat2, &tlon2)) {
  705. X      addsegment(tlat1, tlon1, tlat2, tlon2,
  706. X             (nseg_clip > 0) ? area_clip[nseg_clip-1].clipped_at : 0,
  707. X             clip_at1, clip_at2,
  708. X             area_raw[i].great_circle, area_raw[i+1].great_circle);
  709. X      done = TRUE;
  710. X    }
  711. X    i++;
  712. X      } while ((i < (nsegments - 1)) && (!done));
  713. X      if ((old_n+1) < nseg_clip) nseg_clip--; /* only needed one added */
  714. X    }
  715. X
  716. X
  717. X    /* Now fix problem of areas crossing from left to right across boundary */
  718. X    /* if the distance from point1 to left (East) + point2 to right
  719. X       or point2 to right and point2 to left
  720. X       is less than distance from point1 to point2,
  721. X       then we have a problem. */
  722. X    curr_area = 1;
  723. X    for (i = 0; i < (nseg_clip - 1); i++) {
  724. X      if (wraps && wrap_area(area_clip[i].lat, area_clip[i].lon,
  725. X                 area_clip[i+1].lat, area_clip[i+1].lon, 
  726. X                 &tlat1, &tlon1, &tlat2, &tlon2)) {
  727. X    /* Crosses boundary */
  728. X    switch (curr_area) {
  729. X    case 1:
  730. X                /* finish segment in part 1,
  731. X                   begin part 2 */
  732. X      area_1[nseg_1].lat = area_clip[i].lat;
  733. X      area_1[nseg_1].lon = area_clip[i].lon;
  734. X      area_1[nseg_1].great_circle = area_clip[i].great_circle;
  735. X      area_1[nseg_1].clipped_at = area_clip[i].clipped_at;
  736. X      nseg_1++;
  737. X
  738. X      area_1[nseg_1].lat = tlat1;
  739. X      area_1[nseg_1].lon = tlon1;
  740. X      area_1[nseg_1].great_circle = area_clip[i].great_circle;
  741. X      area_1[nseg_1].clipped_at = area_clip[i].clipped_at;
  742. X      nseg_1++;
  743. X
  744. X      curr_area = 2;
  745. X
  746. X      area_2[nseg_2].lat = tlat2;
  747. X      area_2[nseg_2].lon = tlon2;
  748. X      area_2[nseg_2].great_circle = area_clip[i].great_circle;
  749. X      area_2[nseg_2].clipped_at = area_clip[i].clipped_at;
  750. X      nseg_2++;
  751. X
  752. X      gt12 = (tlon1 > tlon2); /* area 1 greater than area 2 */
  753. X      break;
  754. X    case 2:
  755. X                /* finish part 2, draw it,
  756. X                   close gap in part 1 */
  757. X      if (((gt12) && (tlon1 < tlon2))
  758. X          || ((!gt12) && (tlon1 > tlon2))){
  759. X        tlat3 = tlat1;
  760. X        tlon3 = tlon1;
  761. X        tlat1 = tlat2;
  762. X        tlon1 = tlon2;
  763. X        tlat2 = tlat3;
  764. X        tlon2 = tlon3;
  765. X      };
  766. X      area_2[nseg_2].lat = area_clip[i].lat;
  767. X      area_2[nseg_2].lon = area_clip[i].lon;
  768. X      area_2[nseg_2].great_circle = area_clip[i].great_circle;
  769. X      area_2[nseg_2].clipped_at = area_clip[i].clipped_at;
  770. X      nseg_2++;
  771. X
  772. X      area_2[nseg_2].lat = tlat2;
  773. X      area_2[nseg_2].lon = tlon2;
  774. X      area_2[nseg_2].great_circle = area_clip[i].great_circle;
  775. X      area_2[nseg_2].clipped_at = area_clip[i].clipped_at;
  776. X      nseg_2++;
  777. X
  778. X      area_2[nseg_2].lat = area_2[0].lat;
  779. X      area_2[nseg_2].lon = area_2[0].lon;
  780. X      area_2[nseg_2].great_circle = TRUE;
  781. X      area_2[nseg_2].clipped_at = area_2[0].clipped_at;
  782. X      nseg_2++;
  783. X
  784. X      doarea(area_2, nseg_2);
  785. X
  786. X      curr_area = 1;
  787. X
  788. X      area_1[nseg_1].lat = tlat1;
  789. X      area_1[nseg_1].lon = tlon1;
  790. X      area_1[nseg_1].great_circle = TRUE;
  791. X      area_1[nseg_1].clipped_at = area_1[nseg_1-1].clipped_at;
  792. X      nseg_1++;
  793. X
  794. X      break;
  795. X    default:
  796. X      break;
  797. X    };
  798. X      } else {
  799. X    switch (curr_area) {
  800. X    case 1:
  801. X      area_1[nseg_1].lat = area_clip[i].lat;
  802. X      area_1[nseg_1].lon = area_clip[i].lon;
  803. X      area_1[nseg_1].great_circle = area_clip[i].great_circle;
  804. X      area_1[nseg_1].clipped_at = area_clip[i].clipped_at;
  805. X      nseg_1++;
  806. X      break;
  807. X    case 2:
  808. X      area_2[nseg_2].lat = area_clip[i].lat;
  809. X      area_2[nseg_2].lon = area_clip[i].lon;
  810. X      area_2[nseg_2].great_circle = area_clip[i].great_circle;
  811. X      area_2[nseg_2].clipped_at = area_clip[i].clipped_at;
  812. X      nseg_2++;
  813. X      break;
  814. X    default:
  815. X      break;
  816. X    }
  817. X      }
  818. X    };
  819. X    if (nseg_clip > 0) {
  820. X      area_1[nseg_1].lat = area_clip[nseg_clip-1].lat;
  821. X      area_1[nseg_1].lon = area_clip[nseg_clip-1].lon;
  822. X      area_1[nseg_1].great_circle = area_clip[nseg_clip-1].great_circle;
  823. X      area_1[nseg_1].clipped_at = area_clip[nseg_clip-1].clipped_at;
  824. X      nseg_1++;
  825. X    };
  826. X
  827. X    if (nseg_1 > 0) doarea(area_1, nseg_1);
  828. X  };
  829. X
  830. X  /* Mark it done */
  831. X  nsegments = 0;
  832. X}
  833. X
  834. Xdoarea(area, nseg)
  835. X     struct t_area_struct area[];
  836. X     int nseg;
  837. X{
  838. X  int i;
  839. X  int xloc, yloc, xloc2, yloc2;
  840. X  double tlat1, tlon1, tlat2, tlon2;
  841. X
  842. X  for (i = 0; i < (nseg - 1); i++) {
  843. X    if (clipr_xform(area[i].lat, area[i].lon,
  844. X            area[i+1].lat, area[i+1].lon, 
  845. X            &xloc, &yloc, &xloc2, &yloc2, area[i+1].great_circle,
  846. X            &tlat1, &tlon1, &tlat2, &tlon2)) {
  847. X
  848. X      if (i == 0) D_areamove(xloc, yloc);
  849. X      /* Here we can add tests to add segments along the boundary of
  850. X     projection modes other than SANSONS and RECTANGULAR */
  851. X
  852. X      addareacurved(tlat1, tlon1, tlat2, tlon2,
  853. X            xloc, yloc, xloc2, yloc2,
  854. X            area[i+1].great_circle, 0);
  855. X      if (i == (nseg - 2)) D_areafill(xloc2, yloc2);
  856. X    }
  857. X  }
  858. X}
  859. X
  860. Xint wrap_area(lat1, lon1, lat2, lon2, plat1, plon1, plat2, plon2)
  861. X     double lat1, lon1, lat2, lon2;
  862. X     double *plat1, *plon1, *plat2, *plon2;
  863. X{
  864. X  double slope1, tlat1, tlat2;
  865. X
  866. X/* Adjust so lon1 and lon2 are continuous across region: see xform */
  867. X/* needed so midpoint is correct */
  868. X  if ((xfs_proj_mode == SANSONS) || (xfs_proj_mode == RECTANGULAR)) {
  869. X    if ((xf_west < 0.0) && (lon1>(xf_west+360.0))) lon1 -= 360.0;
  870. X    if ((xf_east > 360.0) && (lon1<(xf_east-360.0))) lon1 += 360.0;
  871. X    if ((xf_west < 0.0) && (lon2>(xf_west+360.0))) lon2 -= 360.0;
  872. X    if ((xf_east > 360.0) && (lon2<(xf_east-360.0))) lon2 += 360.0;
  873. X
  874. X    /* path crosses boundary of map */
  875. X    /* if the distance from point1 to left (East) + point2 to right
  876. X       or point2 to right and point2 to left
  877. X       is less than distance from point1 to point2,
  878. X       then we have a problem. */
  879. X    if (xfs_wide_warn)
  880. X      if ((fabs(lon1-xf_east) + fabs(xf_west-lon2)) < (fabs(lon1-lon2))) {
  881. X    /* point 1 close to east boundary */
  882. X    slope1 = (lat2 - lat1)/(fabs(lon1-xf_east) + fabs(xf_west-lon2));
  883. X
  884. X    tlat1 = lat1 + slope1 * fabs(lon1-(xf_east-xf_c_scale));
  885. X
  886. X    /* segment from (lat1, lon1) to (tlat1, xf_east-xf_c_scale)
  887. X       is on one side of boundary */
  888. X    *plat1 = tlat1;
  889. X    *plon1 = xf_east-xf_c_scale;
  890. X    if (*plon1 > 360) *plon1 -= 360;
  891. X    if (*plon1 < 0) *plon1 += 360;
  892. X
  893. X    tlat2 = lat2 - slope1 * fabs(lon2-(xf_west+xf_c_scale));
  894. X    /* segment from (tlat2, xf_west+xf_c_scale) to (lat2, lon2)
  895. X       is on one side of boundary */
  896. X    *plat2 = tlat2;
  897. X    *plon2 = xf_west+xf_c_scale;
  898. X    if (*plon2 > 360) *plon2 -= 360;
  899. X    if (*plon2 < 0) *plon2 += 360;
  900. X    return TRUE;
  901. X      } else if ((fabs(lon2-xf_east)+fabs(xf_west-lon1)) < (fabs(lon1-lon2))) {
  902. X    /* point 1 close to west boundary */
  903. X    slope1 = (lat1 - lat2)/(fabs(lon2-xf_east) + fabs(xf_west-lon1));
  904. X
  905. X    tlat1 = lat2 + slope1 * fabs(lon2-(xf_east-xf_c_scale));
  906. X
  907. X    /* segment from (lat2, lon2) to (tlat1, xf_east-xf_c_scale)
  908. X       is on one side of boundary */
  909. X    *plat2 = tlat1;
  910. X    *plon2 = xf_east-xf_c_scale;
  911. X    if (*plon2 > 360) *plon2 -= 360;
  912. X    if (*plon2 < 0) *plon2 += 360;
  913. X
  914. X    tlat2 = lat1 - slope1 * fabs(lon1-(xf_west+xf_c_scale));
  915. X    /* segment from (tlat2, xf_west+xf_c_scale) to (lat1, lon1)
  916. X       is on one side of boundary */
  917. X    *plat1 = tlat2;
  918. X    *plon1 = xf_west+xf_c_scale;
  919. X    if (*plon1 > 360) *plon1 -= 360;
  920. X    if (*plon1 < 0) *plon1 += 360;
  921. X    return TRUE;
  922. X      };
  923. X  }
  924. X  return FALSE;
  925. X}
  926. X
  927. X
  928. Xaddsegment(tlat1, tlon1, tlat2, tlon2, last_clip, clip_1, clip_2,
  929. X       gc_1, gc_2)
  930. X     double tlat1, tlon1, tlat2, tlon2;
  931. X     int last_clip, clip_1, clip_2;
  932. X     int gc_1, gc_2;
  933. X{
  934. X
  935. X  /* just add a segment */
  936. X  area_clip[nseg_clip].lat = tlat1;
  937. X  area_clip[nseg_clip].lon = tlon1;
  938. X  area_clip[nseg_clip].great_circle = gc_1;
  939. X  area_clip[nseg_clip].clipped_at = clip_1;
  940. X  nseg_clip++;
  941. X  area_clip[nseg_clip].lat = tlat2;
  942. X  area_clip[nseg_clip].lon = tlon2;
  943. X  area_clip[nseg_clip].great_circle = gc_2;
  944. X  area_clip[nseg_clip].clipped_at = clip_2;
  945. X  nseg_clip++;
  946. X}
  947. X
  948. X
  949. X
  950. X/* addareacurved: add a set of boundary segments between points 1 and 2
  951. X   clipxform has been called, xloc1, yloc1, xloc2, yloc2 are in bounds */
  952. Xaddareacurved(lat1, lon1, lat2, lon2,
  953. X          xloc1, yloc1, xloc2, yloc2, great_circle, clevel)
  954. X     int xloc1, yloc1, xloc2, yloc2;
  955. X     double lat1, lon1, lat2, lon2;
  956. X     int great_circle;     /* draw as great circle */
  957. X     int clevel;         /* safety valve */
  958. X{
  959. X  double mlat, mlon;    /* midpoint lat and long */
  960. X  int mxloc, myloc;    /* transformed */
  961. X  int mpx, mpy;        /* from given x,y */
  962. X  int inregion;
  963. X  
  964. X/* ra difference should be less than 180 degrees: take shortest path */
  965. X  if ((xfs_proj_mode == STEREOGR) || (xfs_proj_mode == GNOMONIC)
  966. X      || (xfs_proj_mode == ORTHOGR))
  967. X    if ((lon1 - lon2) > 180.0) lon1 -= 360.0;
  968. X    else if ((lon2 - lon1) > 180.0) lon2 -= 360.0;
  969. X
  970. X/* Adjust so lon1 and lon2 are continuous across region: see xform */
  971. X/* needed so midpoint is correct */
  972. X  if ((xfs_proj_mode == SANSONS) || (xfs_proj_mode == RECTANGULAR)) {
  973. X    if ((xf_west < 0.0) && (lon1>(xf_west+360.0))) lon1 -= 360.0;
  974. X    if ((xf_east > 360.0) && (lon1<(xf_east-360.0))) lon1 += 360.0;
  975. X    if ((xf_west < 0.0) && (lon2>(xf_west+360.0))) lon2 -= 360.0;
  976. X    if ((xf_east > 360.0) && (lon2<(xf_east-360.0))) lon2 += 360.0;
  977. X  }
  978. X
  979. X
  980. X  if (great_circle) {
  981. X    gcmidpoint(lat1, lon1, lat2, lon2, &mlat, &mlon);
  982. X  } else {
  983. X    mlat = (lat1 + lat2)/2;
  984. X    mlon = (lon1 + lon2)/2;
  985. X  };
  986. X
  987. X  xform(mlat, mlon, &mxloc, &myloc, &inregion);
  988. X
  989. X  mpx = (xloc1 + xloc2)/2;
  990. X  mpy = (yloc1 + yloc2)/2;
  991. X
  992. X  if (((abs(mpx - mxloc) + abs(mpy - myloc)) > 0) && (clevel < 100)) {
  993. X    /* center is not where it should be */
  994. X    addareacurved(lat1, lon1, mlat, mlon,
  995. X          xloc1, yloc1, mxloc, myloc, great_circle, ++clevel);
  996. X    addareacurved(mlat, mlon, lat2, lon2,
  997. X          mxloc, myloc, xloc2, yloc2, great_circle, ++clevel);
  998. X  } else {
  999. X    D_areaadd(xloc2, yloc2);
  1000. X  }
  1001. X}
  1002. X
  1003. X
  1004. X
  1005. X
  1006. X/* Translate two digit encoded size string */
  1007. X/* Maximum parsed: 89000 secs of arc = 24.666 degrees */
  1008. X/* Warning, should use 32 bit integers to allow this value */
  1009. Xlong size_obj(size_str)
  1010. X     char *size_str;
  1011. X{
  1012. X  char chr1, chr2;
  1013. X
  1014. X  chr1 = islower(size_str[0]) ? toupper(size_str[0]) : size_str[0];
  1015. X  chr2 = islower(size_str[1]) ? toupper(size_str[1]) : size_str[1];
  1016. X
  1017. X  if ((chr1 == ' ') && (chr2 == ' ')) return -1;
  1018. X  if (chr1 == ' ') return chr2 - '0';
  1019. X  if (isdigit(chr1)) return ((chr1-'0')*10L + (chr2-'0'));
  1020. X  if (chr1 < 'J') return ((chr1-'A'+1)*100L + (chr2-'0')*10L);
  1021. X  if (chr1 < 'S') return ((chr1-'I')*1000L + (chr2-'0')*100L);
  1022. X  if (chr1 <= 'Z') return ((chr1-'R')*10000L + (chr2-'0')*1000L);
  1023. X  return -1;
  1024. X}
  1025. X
  1026. X/*
  1027. XExamples:
  1028. X
  1029. X"  "        -1
  1030. X" 6"        6
  1031. X"09"        9
  1032. X"73"        73
  1033. X"A0"        100
  1034. X"C3"        330
  1035. X"D5"        450
  1036. X"I6"        960
  1037. X"J2"        1200
  1038. X"R3"        9300
  1039. X"S6"        16000
  1040. X"Z0"        80000
  1041. X"Z9"        89000
  1042. X*/
  1043. X
  1044. X/* Precession functions */
  1045. X/* precession based on formulae from
  1046. X   Astronomical Almanac, 1988, p B19
  1047. X*/
  1048. Xstatic double M, N;
  1049. Xinitprecess(eout)
  1050. X     double eout;
  1051. X{
  1052. X  double T;
  1053. X
  1054. X  T = (eout - 2000.0) / 100.0;
  1055. X  M = (1.2812323 + (0.0003879 + 0.0000101 * T) * T) * T;
  1056. X  N = (0.5567530 - (0.0001185 - 0.0000116 * T) * T) * T;
  1057. X}
  1058. X
  1059. Xdo_precess(lat, lon)
  1060. X     double *lat, *lon;
  1061. X{
  1062. X  double am, dm, a2, d2;
  1063. X
  1064. X  /* am = /alpha_m, dm = /delta_m */
  1065. X
  1066. X  am = *lon + (M + N * DSIN(*lon) * DTAN(*lat))/2.0;
  1067. X  dm = *lat + N*DCOS(am)/2.0;
  1068. X  a2 = *lon + M + N*DSIN(am)*DTAN(dm);
  1069. X  d2 = *lat + N * DCOS(am);
  1070. X
  1071. X  if (a2 >= 360.0) a2 -= 360.0;
  1072. X  if (a2 < 0.0) a2 += 360.0;
  1073. X
  1074. X  *lon = a2;
  1075. X  *lat = d2;
  1076. X}
  1077. X
  1078. END_OF_FILE
  1079. if test 30231 -ne `wc -c <'starchart/ssup.c.ab'`; then
  1080.     echo shar: \"'starchart/ssup.c.ab'\" unpacked with wrong size!
  1081. fi
  1082. # end of 'starchart/ssup.c.ab'
  1083. fi
  1084. echo shar: End of archive 18 \(of 32\).
  1085. cp /dev/null ark18isdone
  1086. MISSING=""
  1087. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do
  1088.     if test ! -f ark${I}isdone ; then
  1089.     MISSING="${MISSING} ${I}"
  1090.     fi
  1091. done
  1092. if test "${MISSING}" = "" ; then
  1093.     echo You have unpacked all 32 archives.
  1094.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1095. else
  1096.     echo You still need to unpack the following archives:
  1097.     echo "        " ${MISSING}
  1098. fi
  1099. ##  End of shell archive.
  1100. exit 0
  1101.  
  1102.  
  1103.