1 /* http://www.rwgrayprojects.com/rbfnotes/maps/graymap6.html
2 Slightly modified by jwz for xscreensaver
6 /**************************************************************/
8 /* This C program is copyrighted by Robert W. Gray and may */
9 /* not be used in ANY for-profit project without written */
12 /**************************************************************/
14 /* (Note: Robert Gray has kindly given me his permission to include
15 this code in xscreensaver. -- Jamie Zawinski, Apr 2018.)
19 /**************************************************************/
21 /* This C program contains the Dymaxion map coordinate */
22 /* transformation routines for converting longitude/latitude */
23 /* points to (X, Y) points on the Dymaxion map. */
25 /* This version uses the exact transformation equations. */
26 /**************************************************************/
36 #include "dymaxionmap-coords.h"
38 /************************************************************************/
39 /* NOTE: in C, array indexing starts with element zero (0). I choose */
40 /* to start my array indexing with elemennt one (1) so all arrays */
41 /* are defined one element longer than they need to be. */
42 /************************************************************************/
44 /************************************************************************/
45 /* global variables accessable to all procedures */
46 /************************************************************************/
48 static double v_x[13], v_y[13], v_z[13];
49 static double center_x[21], center_y[21], center_z[21];
50 static double garc, gt, gdve, gel;
52 /********************************************/
53 /* function pre-definitions */
54 /********************************************/
56 static double radians(double degrees);
57 static void rotate(double angle, double *x, double *y);
58 static void r2(int axis, double alpha, double *x, double *y, double *z);
59 static void init_stuff(void);
60 /*static void convert_s_t_p(double lng, double lat, double *x, double *y);*/
61 static void s_to_c(double theta, double phi, double *x, double *y, double *z);
62 static void c_to_s(double *theta, double *phi, double x, double y, double z);
63 static void s_tri_info(double x, double y, double z,
65 static void dymax_point(int tri, int lcd,
66 double x, double y, double z,
67 double *dx, double *dy);
68 static void conv_ll_t_sc(double lng, double lat, double *theta, double *phi);
71 /****************************************/
72 /* function definitions */
73 /****************************************/
79 (double lng, double lat, double *x, double *y)
81 /***********************************************************/
82 /* This is the main control procedure. */
83 /***********************************************************/
87 double px = 0, py = 0;
90 static int initted = 0;
96 /* Convert the given (long.,lat.) coordinate into spherical */
97 /* polar coordinates (r, theta, phi) with radius=1. */
98 /* Angles are given in radians, NOT degrees. */
100 conv_ll_t_sc(lng, lat, &theta, &phi);
102 /* convert the spherical polar coordinates into cartesian */
103 /* (x, y, z) coordinates. */
105 s_to_c(theta, phi, &hx, &hy, &hz);
107 /* determine which of the 20 spherical icosahedron triangles */
108 /* the given point is in and the LCD triangle. */
110 s_tri_info(hx, hy, hz, &tri, &hlcd);
112 /* Determine the corresponding Fuller map plane (x, y) point */
114 dymax_point(tri, hlcd, hx, hy, hz, &px, &py);
118 } /* end convert_s_t_p */
121 static void conv_ll_t_sc(double lng, double lat, double *theta, double *phi)
123 /* convert (long., lat.) point into spherical polar coordinates */
124 /* with r=radius=1. Angles are given in radians. */
126 double h_theta, h_phi;
128 h_theta = 90.0 - lat ;
130 if (lng < 0.0) {h_phi = lng + 360.0;}
131 *theta = radians(h_theta);
132 *phi = radians(h_phi);
134 } /* end conv_ll_t_sc */
137 static double radians(double degrees)
139 /* convert angles in degrees into angles in radians */
143 pi2 = 2 * 3.14159265358979323846;
145 return(c1 * degrees);
147 } /* end of radians function */
150 static void init_stuff()
152 /* initializes the global variables which includes the */
153 /* vertix coordinates and mid-face coordinates. */
155 double /* i, */ hold_x, hold_y, hold_z, magn;
156 /* double theta, phi; */
158 /* Cartesian coordinates for the 12 vertices of icosahedron */
160 v_x[1] = 0.420152426708710003;
161 v_y[1] = 0.078145249402782959;
162 v_z[1] = 0.904082550615019298;
163 v_x[2] = 0.995009439436241649 ;
164 v_y[2] = -0.091347795276427931 ;
165 v_z[2] = 0.040147175877166645 ;
166 v_x[3] = 0.518836730327364437 ;
167 v_y[3] = 0.835420380378235850 ;
168 v_z[3] = 0.181331837557262454 ;
169 v_x[4] = -0.414682225320335218 ;
170 v_y[4] = 0.655962405434800777 ;
171 v_z[4] = 0.630675807891475371 ;
172 v_x[5] = -0.515455959944041808 ;
173 v_y[5] = -0.381716898287133011 ;
174 v_z[5] = 0.767200992517747538 ;
175 v_x[6] = 0.355781402532944713 ;
176 v_y[6] = -0.843580002466178147 ;
177 v_z[6] = 0.402234226602925571 ;
178 v_x[7] = 0.414682225320335218 ;
179 v_y[7] = -0.655962405434800777 ;
180 v_z[7] = -0.630675807891475371 ;
181 v_x[8] = 0.515455959944041808 ;
182 v_y[8] = 0.381716898287133011 ;
183 v_z[8] = -0.767200992517747538 ;
184 v_x[9] = -0.355781402532944713 ;
185 v_y[9] = 0.843580002466178147 ;
186 v_z[9] = -0.402234226602925571 ;
187 v_x[10] = -0.995009439436241649 ;
188 v_y[10] = 0.091347795276427931 ;
189 v_z[10] = -0.040147175877166645 ;
190 v_x[11] = -0.518836730327364437 ;
191 v_y[11] = -0.835420380378235850 ;
192 v_z[11] = -0.181331837557262454 ;
193 v_x[12] = -0.420152426708710003 ;
194 v_y[12] = -0.078145249402782959 ;
195 v_z[12] = -0.904082550615019298 ;
197 /* now calculate mid face coordinates */
199 hold_x = (v_x[1] + v_x[2] + v_x[3]) / 3.0 ;
200 hold_y = (v_y[1] + v_y[2] + v_y[3]) / 3.0 ;
201 hold_z = (v_z[1] + v_z[2] + v_z[3]) / 3.0 ;
202 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
203 center_x[1] = hold_x / magn;
204 center_y[1] = hold_y / magn;
205 center_z[1] = hold_z / magn;
207 hold_x = (v_x[1] + v_x[3] + v_x[4]) / 3.0 ;
208 hold_y = (v_y[1] + v_y[3] + v_y[4]) / 3.0 ;
209 hold_z = (v_z[1] + v_z[3] + v_z[4]) / 3.0 ;
210 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
211 center_x[2] = hold_x / magn;
212 center_y[2] = hold_y / magn;
213 center_z[2] = hold_z / magn;
215 hold_x = (v_x[1] + v_x[4] + v_x[5]) / 3.0 ;
216 hold_y = (v_y[1] + v_y[4] + v_y[5]) / 3.0 ;
217 hold_z = (v_z[1] + v_z[4] + v_z[5]) / 3.0 ;
218 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
219 center_x[3] = hold_x / magn;
220 center_y[3] = hold_y / magn;
221 center_z[3] = hold_z / magn;
223 hold_x = (v_x[1] + v_x[5] + v_x[6]) / 3.0 ;
224 hold_y = (v_y[1] + v_y[5] + v_y[6]) / 3.0 ;
225 hold_z = (v_z[1] + v_z[5] + v_z[6]) / 3.0 ;
226 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
227 center_x[4] = hold_x / magn;
228 center_y[4] = hold_y / magn;
229 center_z[4] = hold_z / magn;
231 hold_x = (v_x[1] + v_x[2] + v_x[6]) / 3.0 ;
232 hold_y = (v_y[1] + v_y[2] + v_y[6]) / 3.0 ;
233 hold_z = (v_z[1] + v_z[2] + v_z[6]) / 3.0 ;
234 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
235 center_x[5] = hold_x / magn;
236 center_y[5] = hold_y / magn;
237 center_z[5] = hold_z / magn;
239 hold_x = (v_x[2] + v_x[3] + v_x[8]) / 3.0 ;
240 hold_y = (v_y[2] + v_y[3] + v_y[8]) / 3.0 ;
241 hold_z = (v_z[2] + v_z[3] + v_z[8]) / 3.0 ;
242 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
243 center_x[6] = hold_x / magn;
244 center_y[6] = hold_y / magn;
245 center_z[6] = hold_z / magn;
247 hold_x = (v_x[8] + v_x[3] + v_x[9]) / 3.0 ;
248 hold_y = (v_y[8] + v_y[3] + v_y[9]) / 3.0 ;
249 hold_z = (v_z[8] + v_z[3] + v_z[9]) / 3.0 ;
250 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
251 center_x[7] = hold_x / magn;
252 center_y[7] = hold_y / magn;
253 center_z[7] = hold_z / magn;
255 hold_x = (v_x[9] + v_x[3] + v_x[4]) / 3.0 ;
256 hold_y = (v_y[9] + v_y[3] + v_y[4]) / 3.0 ;
257 hold_z = (v_z[9] + v_z[3] + v_z[4]) / 3.0 ;
258 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
259 center_x[8] = hold_x / magn;
260 center_y[8] = hold_y / magn;
261 center_z[8] = hold_z / magn;
263 hold_x = (v_x[10] + v_x[9] + v_x[4]) / 3.0 ;
264 hold_y = (v_y[10] + v_y[9] + v_y[4]) / 3.0 ;
265 hold_z = (v_z[10] + v_z[9] + v_z[4]) / 3.0 ;
266 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
267 center_x[9] = hold_x / magn;
268 center_y[9] = hold_y / magn;
269 center_z[9] = hold_z / magn;
271 hold_x = (v_x[5] + v_x[10] + v_x[4]) / 3.0 ;
272 hold_y = (v_y[5] + v_y[10] + v_y[4]) / 3.0 ;
273 hold_z = (v_z[5] + v_z[10] + v_z[4]) / 3.0 ;
274 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
275 center_x[10] = hold_x / magn;
276 center_y[10] = hold_y / magn;
277 center_z[10] = hold_z / magn;
279 hold_x = (v_x[5] + v_x[11] + v_x[10]) / 3.0 ;
280 hold_y = (v_y[5] + v_y[11] + v_y[10]) / 3.0 ;
281 hold_z = (v_z[5] + v_z[11] + v_z[10]) / 3.0 ;
282 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
283 center_x[11] = hold_x / magn;
284 center_y[11] = hold_y / magn;
285 center_z[11] = hold_z / magn;
287 hold_x = (v_x[5] + v_x[6] + v_x[11]) / 3.0 ;
288 hold_y = (v_y[5] + v_y[6] + v_y[11]) / 3.0 ;
289 hold_z = (v_z[5] + v_z[6] + v_z[11]) / 3.0 ;
290 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
291 center_x[12] = hold_x / magn;
292 center_y[12] = hold_y / magn;
293 center_z[12] = hold_z / magn;
295 hold_x = (v_x[11] + v_x[6] + v_x[7]) / 3.0 ;
296 hold_y = (v_y[11] + v_y[6] + v_y[7]) / 3.0 ;
297 hold_z = (v_z[11] + v_z[6] + v_z[7]) / 3.0 ;
298 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
299 center_x[13] = hold_x / magn;
300 center_y[13] = hold_y / magn;
301 center_z[13] = hold_z / magn;
303 hold_x = (v_x[7] + v_x[6] + v_x[2]) / 3.0 ;
304 hold_y = (v_y[7] + v_y[6] + v_y[2]) / 3.0 ;
305 hold_z = (v_z[7] + v_z[6] + v_z[2]) / 3.0 ;
306 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
307 center_x[14] = hold_x / magn;
308 center_y[14] = hold_y / magn;
309 center_z[14] = hold_z / magn;
311 hold_x = (v_x[8] + v_x[7] + v_x[2]) / 3.0 ;
312 hold_y = (v_y[8] + v_y[7] + v_y[2]) / 3.0 ;
313 hold_z = (v_z[8] + v_z[7] + v_z[2]) / 3.0 ;
314 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
315 center_x[15] = hold_x / magn;
316 center_y[15] = hold_y / magn;
317 center_z[15] = hold_z / magn;
319 hold_x = (v_x[12] + v_x[9] + v_x[8]) / 3.0 ;
320 hold_y = (v_y[12] + v_y[9] + v_y[8]) / 3.0 ;
321 hold_z = (v_z[12] + v_z[9] + v_z[8]) / 3.0 ;
322 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
323 center_x[16] = hold_x / magn;
324 center_y[16] = hold_y / magn;
325 center_z[16] = hold_z / magn;
327 hold_x = (v_x[12] + v_x[9] + v_x[10]) / 3.0 ;
328 hold_y = (v_y[12] + v_y[9] + v_y[10]) / 3.0 ;
329 hold_z = (v_z[12] + v_z[9] + v_z[10]) / 3.0 ;
330 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
331 center_x[17] = hold_x / magn;
332 center_y[17] = hold_y / magn;
333 center_z[17] = hold_z / magn;
335 hold_x = (v_x[12] + v_x[11] + v_x[10]) / 3.0 ;
336 hold_y = (v_y[12] + v_y[11] + v_y[10]) / 3.0 ;
337 hold_z = (v_z[12] + v_z[11] + v_z[10]) / 3.0 ;
338 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
339 center_x[18] = hold_x / magn;
340 center_y[18] = hold_y / magn;
341 center_z[18] = hold_z / magn;
343 hold_x = (v_x[12] + v_x[11] + v_x[7]) / 3.0 ;
344 hold_y = (v_y[12] + v_y[11] + v_y[7]) / 3.0 ;
345 hold_z = (v_z[12] + v_z[11] + v_z[7]) / 3.0 ;
346 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
347 center_x[19] = hold_x / magn;
348 center_y[19] = hold_y / magn;
349 center_z[19] = hold_z / magn;
351 hold_x = (v_x[12] + v_x[8] + v_x[7]) / 3.0 ;
352 hold_y = (v_y[12] + v_y[8] + v_y[7]) / 3.0 ;
353 hold_z = (v_z[12] + v_z[8] + v_z[7]) / 3.0 ;
354 magn = sqrt(hold_x * hold_x + hold_y * hold_y + hold_z * hold_z);
355 center_x[20] = hold_x / magn;
356 center_y[20] = hold_y / magn;
357 center_z[20] = hold_z / magn;
359 garc = 2.0 * asin( sqrt( 5 - sqrt(5)) / sqrt(10) );
362 gdve = sqrt( 3 + sqrt(5) ) / sqrt( 5 + sqrt(5) );
363 gel = sqrt(8) / sqrt(5 + sqrt(5));
365 } /* end of int_stuff procedure */
368 static void s_to_c(double theta, double phi, double *x, double *y, double *z)
370 /* Covert spherical polar coordinates to cartesian coordinates. */
371 /* The angles are given in radians. */
373 *x = sin(theta) * cos(phi);
374 *y = sin(theta) * sin(phi);
380 static void c_to_s(double *lng, double *lat, double x, double y, double z)
382 /* convert cartesian coordinates into spherical polar coordinates. */
383 /* The angles are given in radians. */
387 if (x>0.0 && y>0.0){a = radians(0.0);}
388 if (x<0.0 && y>0.0){a = radians(180.0);}
389 if (x<0.0 && y<0.0){a = radians(180.0);}
390 if (x>0.0 && y<0.0){a = radians(360.0);}
392 if (x==0.0 && y>0.0){*lng = radians(90.0);}
393 if (x==0.0 && y<0.0){*lng = radians(270.0);}
394 if (x>0.0 && y==0.0){*lng = radians(0.0);}
395 if (x<0.0 && y==0.0){*lng = radians(180.0);}
396 if (x!=0.0 && y!=0.0){*lng = atan(y/x) + a;}
401 void s_tri_info(double x, double y, double z,
404 /* Determine which triangle and LCD triangle the point is in. */
406 double h_dist1, h_dist2, h_dist3, h1, h2, h3;
407 int i, h_tri, h_lcd ;
408 int v1 = 0, v2 = 0, v3 = 0;
413 /* Which triangle face center is the closest to the given point */
414 /* is the triangle in which the given point is in. */
416 for (i = 1; i <=20; i = i + 1)
418 h1 = center_x[i] - x;
419 h2 = center_y[i] - y;
420 h3 = center_z[i] - z;
421 h_dist2 = sqrt(h1 * h1 + h2 * h2 + h3 * h3);
422 if (h_dist2 < h_dist1)
426 } /* end the if statement */
427 } /* end the for statement */
431 /* Now the LCD triangle is determined. */
435 case 1: v1 = 1; v2 = 3; v3 = 2; break;
436 case 2: v1 = 1; v2 = 4; v3 = 3; break;
437 case 3: v1 = 1; v2 = 5; v3 = 4; break;
438 case 4: v1 = 1; v2 = 6; v3 = 5; break;
439 case 5: v1 = 1; v2 = 2; v3 = 6; break;
440 case 6: v1 = 2; v2 = 3; v3 = 8; break;
441 case 7: v1 = 3; v2 = 9; v3 = 8; break;
442 case 8: v1 = 3; v2 = 4; v3 = 9; break;
443 case 9: v1 = 4; v2 = 10; v3 = 9; break;
444 case 10: v1 = 4; v2 = 5; v3 = 10; break;
445 case 11: v1 = 5; v2 = 11; v3 = 10; break;
446 case 12: v1 = 5; v2 = 6; v3 = 11; break;
447 case 13: v1 = 6; v2 = 7; v3 = 11; break;
448 case 14: v1 = 2; v2 = 7; v3 = 6; break;
449 case 15: v1 = 2; v2 = 8; v3 = 7; break;
450 case 16: v1 = 8; v2 = 9; v3 = 12; break;
451 case 17: v1 = 9; v2 = 10; v3 = 12; break;
452 case 18: v1 = 10; v2 = 11; v3 = 12; break;
453 case 19: v1 = 11; v2 = 7; v3 = 12; break;
454 case 20: v1 = 8; v2 = 12; v3 = 7; break;
455 } /* end of switch statement */
460 h_dist1 = sqrt(h1 * h1 + h2 * h2 + h3 * h3);
465 h_dist2 = sqrt(h1 * h1 + h2 * h2 + h3 * h3);
470 h_dist3 = sqrt(h1 * h1 + h2 * h2 + h3 * h3);
472 if ( (h_dist1 <= h_dist2) && (h_dist2 <= h_dist3) ) {h_lcd = 1; }
473 if ( (h_dist1 <= h_dist3) && (h_dist3 <= h_dist2) ) {h_lcd = 6; }
474 if ( (h_dist2 <= h_dist1) && (h_dist1 <= h_dist3) ) {h_lcd = 2; }
475 if ( (h_dist2 <= h_dist3) && (h_dist3 <= h_dist1) ) {h_lcd = 3; }
476 if ( (h_dist3 <= h_dist1) && (h_dist1 <= h_dist2) ) {h_lcd = 5; }
477 if ( (h_dist3 <= h_dist2) && (h_dist2 <= h_dist1) ) {h_lcd = 4; }
481 } /* end s_tri_info */
484 static void dymax_point(int tri, int lcd,
485 double x, double y, double z,
486 double *px, double *py)
489 double hlng, hlat, h0x, h0y, h0z, h1x, h1y, h1z;
492 double gx, gy, gz, ga1,ga2,ga3,ga1p,ga2p,ga3p,gxp,gyp/*,gzp*/;
495 /* In order to rotate the given point into the template spherical */
496 /* triangle, we need the spherical polar coordinates of the center */
497 /* of the face and one of the face vertices. So set up which vertex */
502 case 1: v1 = 1; break;
503 case 2: v1 = 1; break;
504 case 3: v1 = 1; break;
505 case 4: v1 = 1; break;
506 case 5: v1 = 1; break;
507 case 6: v1 = 2; break;
508 case 7: v1 = 3; break;
509 case 8: v1 = 3; break;
510 case 9: v1 = 4; break;
511 case 10: v1 = 4; break;
512 case 11: v1 = 5; break;
513 case 12: v1 = 5; break;
514 case 13: v1 = 6; break;
515 case 14: v1 = 2; break;
516 case 15: v1 = 2; break;
517 case 16: v1 = 8; break;
518 case 17: v1 = 9; break;
519 case 18: v1 = 10; break;
520 case 19: v1 = 11; break;
521 case 20: v1 = 8; break;
522 } /* end of switch statement */
532 c_to_s(&hlng, &hlat, center_x[tri], center_y[tri], center_z[tri]);
535 r2(axis,hlng,&h0x,&h0y,&h0z);
536 r2(axis,hlng,&h1x,&h1y,&h1z);
539 r2(axis,hlat,&h0x,&h0y,&h0z);
540 r2(axis,hlat,&h1x,&h1y,&h1z);
542 c_to_s(&hlng,&hlat,h1x,h1y,h1z);
543 hlng = hlng - radians(90.0);
546 r2(axis,hlng,&h0x,&h0y,&h0z);
548 /* exact transformation equations */
550 gz = sqrt(1 - h0x * h0x - h0y * h0y);
551 gs = sqrt( 5 + 2 * sqrt(5) ) / ( gz * sqrt(15) );
556 ga1p = 2.0 * gyp / sqrt(3.0) + (gel / 3.0) ;
557 ga2p = gxp - (gyp / sqrt(3)) + (gel / 3.0) ;
558 ga3p = (gel / 3.0) - gxp - (gyp / sqrt(3));
560 ga1 = gt + atan( (ga1p - 0.5 * gel) / gdve);
561 ga2 = gt + atan( (ga2p - 0.5 * gel) / gdve);
562 ga3 = gt + atan( (ga3p - 0.5 * gel) / gdve);
564 gx = 0.5 * (ga2 - ga3) ;
566 gy = (1.0 / (2.0 * sqrt(3)) ) * (2 * ga1 - ga2 - ga3);
568 /* Re-scale so plane triangle edge length is 1. */
573 /* rotate and translate to correct position */
577 case 1: rotate(240.0,&x, &y);
578 *px = x + 2.0; *py = y + 7.0 / (2.0 * sqrt(3.0)) ; break;
579 case 2: rotate(300.0, &x, &y); *px = x + 2.0;
580 *py = y + 5.0 / (2.0 * sqrt(3.0)) ; break;
581 case 3: rotate(0.0, &x, &y);
582 *px = x + 2.5; *py = y + 2.0 / sqrt(3.0); break;
583 case 4: rotate(60.0, &x, &y);
584 *px = x + 3.0; *py = y + 5.0 / (2.0 * sqrt(3.0)) ; break;
585 case 5: rotate(180.0, &x, &y);
586 *px = x + 2.5; *py = y + 4.0 * sqrt(3.0) / 3.0; break;
587 case 6: rotate(300.0, &x, &y);
588 *px = x + 1.5; *py = y + 4.0 * sqrt(3.0) / 3.0; break;
589 case 7: rotate(300.0, &x, &y);
590 *px = x + 1.0; *py = y + 5.0 / (2.0 * sqrt(3.0)) ; break;
591 case 8: rotate(0.0, &x, &y);
592 *px = x + 1.5; *py = y + 2.0 / sqrt(3.0); break;
595 rotate(300.0, &x, &y);
596 *px = x + 1.5; *py = y + 1.0 / sqrt(3.0);
601 *px = x + 2.0; *py = y + 1.0 / (2.0 * sqrt(3.0));
605 case 10: rotate(60.0, &x, &y);
606 *px = x + 2.5; *py = y + 1.0 / sqrt(3.0); break;
607 case 11: rotate(60.0, &x, &y);
608 *px = x + 3.5; *py = y + 1.0 / sqrt(3.0); break;
609 case 12: rotate(120.0, &x, &y);
610 *px = x + 3.5; *py = y + 2.0 / sqrt(3.0); break;
611 case 13: rotate(60.0, &x, &y);
612 *px = x + 4.0; *py = y + 5.0 / (2.0 * sqrt(3.0)); break;
613 case 14: rotate(0.0, &x, &y);
614 *px = x + 4.0; *py = y + 7.0 / (2.0 * sqrt(3.0)) ; break;
615 case 15: rotate(0.0, &x, &y);
616 *px = x + 5.0; *py = y + 7.0 / (2.0 * sqrt(3.0)) ; break;
617 case 16: if (lcd < 4)
619 rotate(60.0, &x, &y);
620 *px = x + 0.5; *py = y + 1.0 / sqrt(3.0);
625 *px = x + 5.5; *py = y + 2.0 / sqrt(3.0);
628 case 17: rotate(0.0, &x, &y);
629 *px = x + 1.0; *py = y + 1.0 / (2.0 * sqrt(3.0)); break;
630 case 18: rotate(120.0, &x, &y);
631 *px = x + 4.0; *py = y + 1.0 / (2.0 * sqrt(3.0)); break;
632 case 19: rotate(120.0, &x, &y);
633 *px = x + 4.5; *py = y + 2.0 / sqrt(3.0); break;
634 case 20: rotate(300.0, &x, &y);
635 *px = x + 5.0; *py = y + 5.0 / (2.0 * sqrt(3.0)); break;
637 } /* end switch statement */
639 } /* end of dymax_point */
642 static void rotate(double angle, double *x, double *y)
644 /* Rotate the point to correct orientation in XY-plane. */
651 *x = hx * cos(ha) - hy * sin(ha);
652 *y = hx * sin(ha) + hy * cos(ha);
654 } /* end rotate procedure */
657 static void r2(int axis, double alpha, double *x, double *y, double *z)
659 /* Rotate a 3-D point about the specified axis. */
668 *y = b * cos(alpha) + c * sin(alpha);
669 *z = c * cos(alpha) - b * sin(alpha);
674 *x = a * cos(alpha) - c * sin(alpha);
675 *z = a * sin(alpha) + c * cos(alpha);
680 *x = a * cos(alpha) + b * sin(alpha);
681 *y = b * cos(alpha) - a * sin(alpha);