GRASS GIS 7 Programmer's Manual  7.0.3(2016)-r00000
gsd_objs.c
Go to the documentation of this file.
1 
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include <grass/gis.h>
23 #include <grass/ogsf.h>
24 
25 #include "gsget.h"
26 #include "math.h"
27 #include "rowcol.h"
28 
29 static void init_stuff(void);
30 
34 float Octo[6][3] = {
35  {1.0, 0.0, 0.0},
36  {0.0, 1.0, 0.0},
37  {0.0, 0.0, 1.0},
38  {-1.0, 0.0, 0.0},
39  {0.0, -1.0, 0.0},
40  {0.0, 0.0, -1.0}
41 };
42 
43 #define ONORM .57445626
44 
48 float OctoN[8][3] = {
49  {ONORM, ONORM, ONORM},
50  {-ONORM, ONORM, ONORM},
51  {ONORM, -ONORM, ONORM},
52  {-ONORM, -ONORM, ONORM},
53  {ONORM, ONORM, -ONORM},
54  {-ONORM, ONORM, -ONORM},
55  {ONORM, -ONORM, -ONORM},
56  {-ONORM, -ONORM, -ONORM},
57 };
58 
71 float CubeNormals[3][3] = {
72  {0, -ONORM, 0},
73  {0, 0, ONORM},
74  {ONORM, 0, 0}
75 };
76 
77 float CubeVertices[8][3] = {
78  {-1.0, -1.0, -1.0},
79  {1.0, -1.0, -1.0},
80  {1.0, 1.0, -1.0},
81  {-1.0, 1.0, -1.0},
82  {-1.0, -1.0, 1.0},
83  {1.0, -1.0, 1.0},
84  {1.0, 1.0, 1.0},
85  {-1.0, 1.0, 1.0}
86 };
87 
88 float origin[3] = { 0.0, 0.0, 0.0 };
89 
90 #define UP_NORM Octo[2]
91 #define DOWN_NORM Octo[5]
92 #define ORIGIN origin
93 
97 float ogverts[8][3];
98 
102 float ogvertsplus[8][3];
103 
104 float Pi;
105 
106 static void init_stuff(void)
107 {
108  float cos45;
109  int i;
110  static int first = 1;
111 
112  if (first) {
113  first = 0;
114 
115  cos45 = cos(atan(1.0));
116 
117  for (i = 0; i < 8; i++) {
118  ogverts[i][Z] = 0.0;
119  ogvertsplus[i][Z] = 1.0;
120  }
121 
122  ogverts[0][X] = ogvertsplus[0][X] = 1.0;
123  ogverts[0][Y] = ogvertsplus[0][Y] = 0.0;
124  ogverts[1][X] = ogvertsplus[1][X] = cos45;
125  ogverts[1][Y] = ogvertsplus[1][Y] = cos45;
126  ogverts[2][X] = ogvertsplus[2][X] = 0.0;
127  ogverts[2][Y] = ogvertsplus[2][Y] = 1.0;
128  ogverts[3][X] = ogvertsplus[3][X] = -cos45;
129  ogverts[3][Y] = ogvertsplus[3][Y] = cos45;
130  ogverts[4][X] = ogvertsplus[4][X] = -1.0;
131  ogverts[4][Y] = ogvertsplus[4][Y] = 0.0;
132  ogverts[5][X] = ogvertsplus[5][X] = -cos45;
133  ogverts[5][Y] = ogvertsplus[5][Y] = -cos45;
134  ogverts[6][X] = ogvertsplus[6][X] = 0.0;
135  ogverts[6][Y] = ogvertsplus[6][Y] = -1.0;
136  ogverts[7][X] = ogvertsplus[7][X] = cos45;
137  ogverts[7][Y] = ogvertsplus[7][Y] = -cos45;
138 
139  Pi = 4.0 * atan(1.0);
140  }
141 
142  return;
143 }
144 
152 void gsd_plus(float *center, int colr, float siz)
153 {
154  float v1[3], v2[3];
155 
156  gsd_color_func(colr);
157  siz *= .5;
158 
159  v1[Z] = v2[Z] = center[Z];
160 
161  v1[X] = v2[X] = center[X];
162  v1[Y] = center[Y] - siz;
163  v2[Y] = center[Y] + siz;
164  gsd_bgnline();
165  gsd_vert_func(v1);
166  gsd_vert_func(v2);
167  gsd_endline();
168 
169  v1[Y] = v2[Y] = center[Y];
170  v1[X] = center[X] - siz;
171  v2[X] = center[X] + siz;
172  gsd_bgnline();
173  gsd_vert_func(v1);
174  gsd_vert_func(v2);
175  gsd_endline();
176 
177  return;
178 }
179 
189 void gsd_line_onsurf(geosurf * gs, float *v1, float *v2)
190 {
191  int i, np;
192  Point3 *pts;
193  float fudge;
194 
195  pts = gsdrape_get_segments(gs, v1, v2, &np);
196  if (pts) {
197  fudge = FUDGE(gs);
198  gsd_bgnline();
199 
200  for (i = 0; i < np; i++) {
201  /* ACS */
202  /* reverting back, as it broke displaying X symbol and query line */
203  pts[i][Z] += fudge;
204  /*pts[i][Z] *= fudge;*/
205  gsd_vert_func(pts[i]);
206  }
207 
208  gsd_endline();
209 
210  /* fix Z values? */
211  v1[Z] = pts[0][Z];
212  v2[Z] = pts[np - 1][Z];
213  }
214 
215  return;
216 }
217 
235 int gsd_nline_onsurf(geosurf * gs, float *v1, float *v2, float *pt, int n)
236 {
237  int i, np, pdraw;
238  Point3 *pts;
239  float fudge;
240 
241  pts = gsdrape_get_segments(gs, v1, v2, &np);
242 
243  if (pts) {
244  pdraw = n < np ? n : np;
245  fudge = FUDGE(gs);
246  gsd_bgnline();
247 
248  for (i = 0; i < pdraw; i++) {
249  pts[i][Z] += fudge;
250  gsd_vert_func(pts[i]);
251  }
252 
253  gsd_endline();
254 
255  pt[X] = pts[i - 1][X];
256  pt[Y] = pts[i - 1][Y];
257 
258  /* fix Z values? */
259  v1[Z] = pts[0][Z];
260  v2[Z] = pts[np - 1][Z];
261 
262  return (i);
263  }
264 
265  return (0);
266 }
267 
278 void gsd_x(geosurf * gs, float *center, int colr, float siz)
279 {
280  float v1[3], v2[3];
281 
282  gsd_color_func(colr);
283  siz *= .5;
284 
285  v1[Z] = v2[Z] = center[Z];
286 
287  v1[X] = center[X] - siz;
288  v2[X] = center[X] + siz;
289  v1[Y] = center[Y] - siz;
290  v2[Y] = center[Y] + siz;
291 
292  if (gs) {
293  gsd_line_onsurf(gs, v1, v2);
294  }
295  else {
296  gsd_bgnline();
297  gsd_vert_func(v1);
298  gsd_vert_func(v2);
299  gsd_endline();
300  }
301 
302  v1[X] = center[X] - siz;
303  v2[X] = center[X] + siz;
304  v1[Y] = center[Y] + siz;
305  v2[Y] = center[Y] - siz;
306 
307  if (gs) {
308  gsd_line_onsurf(gs, v1, v2);
309  }
310  else {
311  gsd_bgnline();
312  gsd_vert_func(v1);
313  gsd_vert_func(v2);
314  gsd_endline();
315  }
316 
317  return;
318 }
319 
327 void gsd_diamond(float *center, unsigned long colr, float siz)
328 {
329  int preshade;
330 
331  /* seems right, but isn't
332  siz *= .5;
333  */
334 
335  gsd_pushmatrix();
336  gsd_translate(center[X], center[Y], center[Z]);
337  gsd_scale(siz, siz, siz);
338  preshade = gsd_getshademodel();
339  gsd_shademodel(0); /* want flat shading */
340 
341  gsd_bgnpolygon();
342  gsd_litvert_func(OctoN[0], colr, Octo[0]);
343  gsd_litvert_func(OctoN[0], colr, Octo[1]);
344  gsd_litvert_func(OctoN[0], colr, Octo[2]);
345  gsd_endpolygon();
346 
347  gsd_bgnpolygon();
348  gsd_litvert_func(OctoN[1], colr, Octo[2]);
349  gsd_litvert_func(OctoN[1], colr, Octo[1]);
350  gsd_litvert_func(OctoN[1], colr, Octo[3]);
351  gsd_endpolygon();
352 
353  gsd_bgnpolygon();
354  gsd_litvert_func(OctoN[2], colr, Octo[2]);
355  gsd_litvert_func(OctoN[2], colr, Octo[4]);
356  gsd_litvert_func(OctoN[2], colr, Octo[0]);
357  gsd_endpolygon();
358 
359  gsd_bgnpolygon();
360  gsd_litvert_func(OctoN[3], colr, Octo[2]);
361  gsd_litvert_func(OctoN[3], colr, Octo[3]);
362  gsd_litvert_func(OctoN[3], colr, Octo[4]);
363  gsd_endpolygon();
364 
365  gsd_bgnpolygon();
366  gsd_litvert_func(OctoN[4], colr, Octo[0]);
367  gsd_litvert_func(OctoN[4], colr, Octo[5]);
368  gsd_litvert_func(OctoN[4], colr, Octo[1]);
369  gsd_endpolygon();
370 
371  gsd_bgnpolygon();
372  gsd_litvert_func(OctoN[5], colr, Octo[1]);
373  gsd_litvert_func(OctoN[5], colr, Octo[5]);
374  gsd_litvert_func(OctoN[5], colr, Octo[3]);
375  gsd_endpolygon();
376 
377  gsd_bgnpolygon();
378  gsd_litvert_func(OctoN[6], colr, Octo[5]);
379  gsd_litvert_func(OctoN[6], colr, Octo[0]);
380  gsd_litvert_func(OctoN[6], colr, Octo[4]);
381  gsd_endpolygon();
382 
383  gsd_bgnpolygon();
384  gsd_litvert_func(OctoN[7], colr, Octo[5]);
385  gsd_litvert_func(OctoN[7], colr, Octo[4]);
386  gsd_litvert_func(OctoN[7], colr, Octo[3]);
387  gsd_endpolygon();
388 
389 #ifdef OCT_SHADED
390  {
391  gsd_bgntmesh();
392  gsd_litvert_func(Octo[0], colr, Octo[0]);
393  gsd_litvert_func(Octo[1], colr, Octo[1]);
394  gsd_swaptmesh();
395  gsd_litvert_func(Octo[2], colr, Octo[2]);
396  gsd_swaptmesh();
397  gsd_litvert_func(Octo[4], colr, Octo[4]);
398  gsd_swaptmesh();
399  gsd_litvert_func(Octo[5], colr, Octo[5]);
400  gsd_swaptmesh();
401  gsd_litvert_func(Octo[1], colr, Octo[1]);
402  gsd_litvert_func(Octo[3], colr, Octo[3]);
403  gsd_litvert_func(Octo[2], colr, Octo[2]);
404  gsd_swaptmesh();
405  gsd_litvert_func(Octo[4], colr, Octo[4]);
406  gsd_swaptmesh();
407  gsd_litvert_func(Octo[5], colr, Octo[5]);
408  gsd_swaptmesh();
409  gsd_litvert_func(Octo[1], colr, Octo[1]);
410  gsd_endtmesh();
411  }
412 #endif
413 
414  gsd_popmatrix();
415  gsd_shademodel(preshade);
416 
417  return;
418 }
419 
429 void gsd_cube(float *center, unsigned long colr, float siz)
430 {
431  int preshade;
432 
433  /* see gsd_diamond() "seems right, but isn't" */
434  siz *= .5;
435 
436  gsd_pushmatrix();
437  gsd_translate(center[X], center[Y], center[Z]);
438  gsd_scale(siz, siz, siz);
439  preshade = gsd_getshademodel();
440  gsd_shademodel(0); /* want flat shading */
441 
442 
443  /* N wall: */
444  gsd_bgnpolygon();
449  gsd_endpolygon();
450 
451  /* S wall: */
452  gsd_bgnpolygon();
457  gsd_endpolygon();
458 
459  /* E wall: */
460  gsd_bgnpolygon();
465  gsd_endpolygon();
466 
467  /* W wall: */
468  gsd_bgnpolygon();
473  gsd_endpolygon();
474 
475  /* lower wall: */
476  gsd_bgnpolygon();
481  gsd_endpolygon();
482 
483  /* top wall: */
484  gsd_bgnpolygon();
489  gsd_endpolygon();
490 
491  gsd_popmatrix();
492  gsd_shademodel(preshade);
493 
494  return;
495 }
496 
506 void gsd_draw_box(float *center, unsigned long colr, float siz)
507 {
508 
509  /* see gsd_diamond() "seems right, but isn't" */
510  siz *= .5;
511 
512  gsd_pushmatrix();
513  gsd_translate(center[X], center[Y], center[Z]);
514  gsd_scale(siz, siz, siz);
515  gsd_color_func(colr);
516 
517  gsd_bgnline(); /* N wall */
523  gsd_endline();
524 
525  gsd_bgnline(); /* S wall */
531  gsd_endline();
532 
533  gsd_bgnline();
536  gsd_endline();
537 
538  gsd_bgnline();
541  gsd_endline();
542 
543  gsd_bgnline();
546  gsd_endline();
547 
548  gsd_bgnline();
551  gsd_endline();
552 
553  gsd_popmatrix();
554 
555  return;
556 }
557 
565 void gsd_drawsphere(float *center, unsigned long colr, float siz)
566 {
567  siz *= .5; /* siz is diameter, gsd_sphere uses radius */
568  gsd_color_func(colr);
569  gsd_sphere(center, siz);
570 
571  return;
572 }
573 
578 {
579  gsd_bgnline();
580  gsd_vert_func(Octo[0]);
581  gsd_vert_func(Octo[3]);
582  gsd_endline();
583 
584  gsd_bgnline();
585  gsd_vert_func(Octo[1]);
586  gsd_vert_func(Octo[4]);
587  gsd_endline();
588 
589  gsd_bgnline();
590  gsd_vert_func(Octo[2]);
591  gsd_vert_func(Octo[5]);
592  gsd_endline();
593 
594  return;
595 }
596 
604 void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
605 {
606  float angle;
607 
608  angle = 45.; /* degrees */
609 
610  gsd_pushmatrix();
611  gsd_translate(center[X], center[Y], center[Z]);
612  gsd_scale(siz, siz, siz);
613  gsd_color_func(colr);
614 
616 
617  gsd_pushmatrix();
618  gsd_rot(angle, 'x');
620  gsd_popmatrix();
621 
622  gsd_pushmatrix();
623  gsd_rot(-angle, 'x');
625  gsd_popmatrix();
626 
627  gsd_pushmatrix();
628  gsd_rot(angle, 'y');
630  gsd_popmatrix();
631 
632  gsd_pushmatrix();
633  gsd_rot(-angle, 'y');
635  gsd_popmatrix();
636 
637  gsd_pushmatrix();
638  gsd_rot(angle, 'z');
640  gsd_popmatrix();
641 
642  gsd_pushmatrix();
643  gsd_rot(-angle, 'z');
645  gsd_popmatrix();
646 
647  gsd_popmatrix();
648 
649  return;
650 }
651 
659 void gsd_draw_gyro(float *center, unsigned long colr, float siz)
660 {
661  int i;
662 
663  gsd_pushmatrix();
664  gsd_translate(center[X], center[Y], center[Z]);
665  gsd_scale(siz, siz, siz);
666  gsd_color_func(colr);
667 
668  /* vert axis */
669  gsd_bgnline();
670  gsd_vert_func(Octo[2]);
671  gsd_vert_func(Octo[5]);
672  gsd_endline();
673 
674  /* spokes */
675  gsd_pushmatrix();
676 
677  for (i = 0; i < 6; i++) {
678  gsd_rot(30., 'z');
679  gsd_bgnline();
680  gsd_vert_func(Octo[0]);
681  gsd_vert_func(Octo[3]);
682  gsd_endline();
683  }
684 
685  gsd_popmatrix();
686 
687  gsd_color_func(colr);
688 
689  gsd_circ(0., 0., 1.);
690 
691  gsd_pushmatrix();
692  gsd_rot(90., 'x');
693  gsd_circ(0., 0., 1.);
694  gsd_popmatrix();
695 
696  gsd_pushmatrix();
697  gsd_rot(90., 'y');
698  gsd_circ(0., 0., 1.);
699  gsd_popmatrix();
700 
701  gsd_popmatrix();
702 
703  return;
704 }
705 
711 void gsd_3dcursor(float *pt)
712 {
713  float big, vert[3];
714 
715  big = 10000.;
716 
717  gsd_bgnline();
718  vert[X] = pt[X];
719  vert[Y] = pt[Y];
720  vert[Z] = big;
721  gsd_vert_func(vert);
722  vert[Z] = -big;
723  gsd_vert_func(vert);
724  gsd_endline();
725 
726  gsd_bgnline();
727  vert[X] = pt[X];
728  vert[Z] = pt[Z];
729  vert[Y] = big;
730  gsd_vert_func(vert);
731  vert[Y] = -big;
732  gsd_vert_func(vert);
733  gsd_endline();
734 
735  gsd_bgnline();
736  vert[Y] = pt[Y];
737  vert[Z] = pt[Z];
738  vert[X] = big;
739  gsd_vert_func(vert);
740  vert[X] = -big;
741  gsd_vert_func(vert);
742  gsd_endline();
743 
744  return;
745 }
746 
755 void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
756 {
757  float dx, dy, dz;
758  float costheta, theta, adjacent;
759 
760  dx = dir[X];
761  dy = dir[Y];
762  dz = dir[Z];
763 
764  /* project vector <dx,dy,dz> onto plane of constant z containing
765  * final value should be 0.0 to 3600.0 */
766  if (dx == 0 && dy == 0) {
767  *aspect = 0.;
768  }
769  else {
770  if (dx == 0) {
771  theta = 90.0;
772  }
773  else {
774  costheta = dx / sqrt(dx * dx + dy * dy);
775  theta = acos(costheta);
776  }
777 
778  if (dy < 0) {
779  theta = (2 * Pi) - theta;
780  }
781 
782  *aspect = theta;
783  }
784 
785  /* project vector <dx,dy,dz> onto plane of constant y containing
786  * final value should be -900.0 (looking up) to 900.0 (looking down) */
787  if (dz == 0) {
788  theta = 0.0;
789  }
790  else if (dx == 0 && dy == 0) {
791  theta = Pi / 2.;
792  }
793  else {
794  adjacent = sqrt(dx * dx + dy * dy);
795  costheta = adjacent / sqrt(adjacent * adjacent + dz * dz);
796  theta = acos(costheta);
797  }
798 
799  if (dz > 0) {
800  theta = -theta;
801  }
802 
803  *slope = theta;
804 
805  if (degrees) {
806  *aspect = *aspect * (180. / Pi);
807  *slope = *slope * (180. / Pi);
808  }
809 
810  return;
811 }
812 
813 
825 /*TODO: Store arrow somewhere to enable it's removal/change.
826  Add option to specify north text and font. */
827 int gsd_north_arrow(float *pos2, float len, GLuint fontbase,
828  unsigned long arw_clr, unsigned long text_clr)
829 {
830  const char *txt;
831  float v[4][3];
832  float base[3][3];
833  float Ntop[] = { 0.0, 0.0, 1.0 };
834 
835  base[0][Z] = base[1][Z] = base[2][Z] = pos2[Z];
836  v[0][Z] = v[1][Z] = v[2][Z] = v[3][Z] = pos2[Z];
837 
838  base[0][X] = pos2[X] - len / 16.;
839  base[1][X] = pos2[X] + len / 16.;
840  base[0][Y] = base[1][Y] = pos2[Y] - len / 2.;
841  base[2][X] = pos2[X];
842  base[2][Y] = pos2[Y] + .45 * len;
843 
844  v[0][X] = v[2][X] = pos2[X];
845  v[1][X] = pos2[X] + len / 8.;
846  v[3][X] = pos2[X] - len / 8.;
847  v[0][Y] = pos2[Y] + .2 * len;
848  v[1][Y] = v[3][Y] = pos2[Y] + .1 * len;
849  v[2][Y] = pos2[Y] + .5 * len;
850 
851  /* make sure we are drawing in front buffer */
852  GS_set_draw(GSD_FRONT);
853 
854  gsd_pushmatrix();
855  gsd_do_scale(1);
856 
857  glNormal3fv(Ntop);
858  gsd_color_func(arw_clr);
859 
860  gsd_bgnpolygon();
861  glVertex3fv(base[0]);
862  glVertex3fv(base[1]);
863  glVertex3fv(base[2]);
864  gsd_endpolygon();
865 
866  gsd_bgnpolygon();
867  glVertex3fv(v[0]);
868  glVertex3fv(v[1]);
869  glVertex3fv(v[2]);
870  glVertex3fv(v[0]);
871  gsd_endpolygon();
872 
873  gsd_bgnpolygon();
874  glVertex3fv(v[0]);
875  glVertex3fv(v[2]);
876  glVertex3fv(v[3]);
877  glVertex3fv(v[0]);
878  gsd_endpolygon();
879 
880  /* draw N for North */
881  /* Need to pick a nice generic font */
882  /* TODO -- project text position off arrow
883  * bottom along azimuth
884  */
885 
886  gsd_color_func(text_clr);
887  txt = "North";
888  /* adjust position of N text */
889  base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
890  base[0][Y] -= gsd_get_txtheight(18) - 20.;
891 
892  glRasterPos3fv(base[0]);
893  glListBase(fontbase);
894  glCallLists(strlen(txt), GL_UNSIGNED_BYTE, (const GLvoid *)txt);
895  GS_done_draw();
896 
897  gsd_popmatrix();
898  gsd_flush();
899 
900  return (1);
901 
902 }
903 
923 int gsd_arrow(float *center, unsigned long colr, float siz, float *dir,
924  float sz, geosurf * onsurf)
925 {
926  float slope, aspect;
927  float tmp[3];
928  static int first = 1;
929 
930  if (first) {
931  init_stuff();
932  first = 0;
933  }
934 
935  dir[Z] /= sz;
936 
937  GS_v3norm(dir);
938 
939  if (NULL != onsurf) {
940  float base[3], tip[3], len;
941 
942  base[X] = center[X];
943  base[Y] = center[Y];
944 
945  /* project dir to surface, after zexag */
946  len = GS_P2distance(ORIGIN, dir); /* in case dir isn't normalized */
947  tip[X] = center[X] + dir[X] * len * siz;
948  tip[Y] = center[Y] + dir[Y] * len * siz;
949 
950  return gsd_arrow_onsurf(base, tip, colr, 2, onsurf);
951  }
952 
953  dir_to_slope_aspect(dir, &slope, &aspect, 1);
954 
955  gsd_pushmatrix();
956  gsd_translate(center[X], center[Y], center[Z]);
957  gsd_scale(1.0, 1.0, 1.0 / sz);
958  gsd_rot(aspect + 90, 'z');
959  gsd_rot(slope + 90., 'x');
960  gsd_scale(siz, siz, siz);
961  gsd_color_func(colr);
962 
963  tmp[X] = 0.2;
964  tmp[Y] = 0.0;
965  tmp[Z] = 0.65;
966 
967  gsd_bgnline();
970  gsd_endline();
971 
972  gsd_bgnline();
973  gsd_vert_func(tmp);
975  tmp[X] = -0.2;
976  gsd_vert_func(tmp);
977  gsd_endline();
978 
979  gsd_popmatrix();
980 
981  return (1);
982 }
983 
995 int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid,
996  geosurf * gs)
997 {
998  static int first = 1;
999 
1000  if (first) {
1001  init_stuff();
1002  first = 0;
1003  }
1004 
1005  gsd_linewidth(wid);
1006  gsd_color_func(colr);
1007 
1008  G_debug(3, "gsd_arrow_onsurf");
1009  G_debug(3, " %f %f -> %f %f", base[X], base[Y], tip[X], tip[Y]);
1010 
1011  gsd_line_onsurf(gs, base, tip);
1012 
1013 #ifdef DO_SPHERE_BASE
1014  {
1015  GS_v3dir(tip, base, dir0);
1016  GS_v3mag(dir0, &len);
1017  gsd_disc(base[X], base[Y], len / 10.);
1018  }
1019 #endif
1020 
1021 #ifdef ARROW_READY
1022  {
1023  base[Z] = tip[Z] = 0.0;
1024  GS_v3dir(tip, base, dir0);
1025 
1026  G_debug(3, " dir0: %f %f %f", dir0[X], dir0[Y], dir0[Z]);
1027 
1028  /* rotate this direction 90 degrees */
1029  GS_v3cross(dir0, UP_NORM, dir2);
1030  GS_v3mag(dir0, &len);
1031  GS_v3eq(dir1, dir0);
1032 
1033  G_debug(3, " len: %f", len);
1034  G_debug(3, " a-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1035  G_debug(3, " a-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1036 
1037  dim1 = len * .7;
1038  dim2 = len * .2;
1039  GS_v3mult(dir1, dim1);
1040  GS_v3mult(dir2, dim2);
1041 
1042  G_debug(3, " b-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1043  G_debug(3, " b-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1044 
1045  GS_v3eq(tmp, base);
1046  GS_v3add(tmp, dir1);
1047  GS_v3add(tmp, dir2);
1048 
1049  G_debug(3, " %f %f -> ", tmp[X], tmp[Y]);
1050 
1051  gsd_line_onsurf(gs, tmp, tip);
1052 
1053  GS_v3cross(dir0, DOWN_NORM, dir2);
1054  GS_v3mult(dir2, dim2);
1055  GS_v3eq(tmp, base);
1056 
1057  G_debug(3, " dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1058  G_debug(3, " dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1059 
1060  GS_v3add(tmp, dir1);
1061  GS_v3add(tmp, dir2);
1062 
1063  G_debug(3, " %f %f", tmp[X], tmp[Y]);
1064 
1065  gsd_line_onsurf(gs, tip, tmp);
1066  }
1067 #endif
1068 
1069  return (0);
1070 }
1071 
1082 void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2,
1083  float *dir, float sz)
1084 {
1085  float slope, aspect;
1086  int preshade;
1087  static int first = 1;
1088  static int list;
1089  static int debugint = 1;
1090 
1091  dir[Z] /= sz;
1092 
1093  GS_v3norm(dir);
1094  dir_to_slope_aspect(dir, &slope, &aspect, 1);
1095 
1096  if (debugint > 100) {
1097  G_debug(3, "gsd_3darrow()");
1098  G_debug(3, " pt: %f,%f,%f dir: %f,%f,%f slope: %f aspect: %f",
1099  center[X], center[Y], center[Z], dir[X], dir[Y], dir[Z],
1100  slope, aspect);
1101  debugint = 1;
1102  }
1103  debugint++;
1104 
1105  preshade = gsd_getshademodel();
1106 
1107  /*
1108  gsd_shademodel(0);
1109  want flat shading? */
1110  gsd_pushmatrix();
1111  gsd_translate(center[X], center[Y], center[Z]);
1112  gsd_scale(1.0, 1.0, 1.0 / sz);
1113  gsd_rot(aspect + 90, 'z');
1114  gsd_rot(slope + 90., 'x');
1115  gsd_scale(siz2, siz2, siz1);
1116  gsd_color_func(colr);
1117 
1118  if (first) {
1119  /* combine these into an object */
1120  first = 0;
1121  list = gsd_makelist();
1122  gsd_bgnlist(list, 1);
1123  gsd_backface(1);
1124 
1125  gsd_pushmatrix();
1126  gsd_scale(.10, .10, .75); /* narrow cyl */
1127  primitive_cylinder(colr, 0);
1128  gsd_popmatrix();
1129 
1130  gsd_pushmatrix();
1131  gsd_translate(0.0, 0.0, .60);
1132  gsd_scale(0.3, 0.3, 0.4); /* cone */
1133  primitive_cone(colr);
1134  gsd_popmatrix();
1135 
1136  gsd_backface(0);
1137  gsd_endlist();
1138  }
1139  else {
1140  gsd_calllist(list);
1141  }
1142 
1143  gsd_popmatrix();
1144  gsd_shademodel(preshade);
1145 
1146  return;
1147 }
1148 
1161 int gsd_scalebar(float *pos2, float len, GLuint fontbase,
1162  unsigned long bar_clr, unsigned long text_clr)
1163 {
1164  char txt[100];
1165  float base[4][3];
1166  float Ntop[] = { 0.0, 0.0, 1.0 };
1167 
1168 
1169  base[0][Z] = base[1][Z] = base[2][Z] = base[3][Z] = pos2[Z];
1170 
1171  /* simple 1:8 rectangle *//* bump to X/20. for a 1:10 narrower bar? */
1172  base[0][X] = base[1][X] = pos2[X] - len / 2.;
1173  base[2][X] = base[3][X] = pos2[X] + len / 2.;
1174 
1175  base[0][Y] = base[3][Y] = pos2[Y] - len / 16.;
1176  base[1][Y] = base[2][Y] = pos2[Y] + len / 16.;
1177 
1178  /* make sure we are drawing in front buffer */
1179  GS_set_draw(GSD_FRONT);
1180 
1181  gsd_pushmatrix();
1182  gsd_do_scale(1); /* get map scale factor */
1183 
1184  glNormal3fv(Ntop);
1185 
1186  gsd_color_func(bar_clr);
1187 
1188  gsd_bgnpolygon();
1189  glVertex3fv(base[0]);
1190  glVertex3fv(base[1]);
1191  glVertex3fv(base[2]);
1192  glVertex3fv(base[3]);
1193  glVertex3fv(base[0]);
1194  gsd_endpolygon();
1195 
1196  /* draw units */
1197  /* Need to pick a nice generic font */
1198  /* TODO -- project text position off bar bottom along azimuth */
1199 
1200  gsd_color_func(text_clr);
1201 
1202  /* format text in a nice way */
1203  if (strcmp("meters", G_database_unit_name(TRUE)) == 0) {
1204  if (len > 2500)
1205  sprintf(txt, "%g km", len / 1000);
1206  else
1207  sprintf(txt, "%g meters", len);
1208  }
1209  else if (strcmp("feet", G_database_unit_name(TRUE)) == 0) {
1210  if (len > 5280)
1211  sprintf(txt, "%g miles", len / 5280);
1212  else if (len == 5280)
1213  sprintf(txt, "1 mile");
1214  else
1215  sprintf(txt, "%g feet", len);
1216  }
1217  else {
1218  sprintf(txt, "%g %s", len, G_database_unit_name(TRUE));
1219  }
1220 
1221  /* adjust position of text (In map units?!) */
1222  base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
1223  base[0][Y] -= gsd_get_txtheight(18) - 20.;
1224 
1225 
1226  glRasterPos3fv(base[0]);
1227  glListBase(fontbase);
1228  glCallLists(strlen(txt), GL_BYTE, (GLubyte *) txt);
1229  GS_done_draw();
1230 
1231  gsd_popmatrix();
1232  gsd_flush();
1233 
1234  return (1);
1235 }
1236 
1249 int gsd_scalebar_v2(float *pos, float len, GLuint fontbase,
1250  unsigned long bar_clr, unsigned long text_clr)
1251 {
1252  float base[6][3];
1253  float Ntop[] = { 0.0, 0.0, 1.0 };
1254 
1255  base[0][Z] = base[1][Z] = base[2][Z] = pos[Z];
1256  base[3][Z] = base[4][Z] = base[5][Z] = pos[Z];
1257 
1258  /* simple scalebar: |------| */
1259  base[0][X] = base[2][X] = base[3][X] = pos[X] - len / 2.;
1260  base[1][X] = base[4][X] = base[5][X] = pos[X] + len / 2.;
1261  base[0][Y] = base[1][Y] = pos[Y];
1262  base[2][Y] = base[4][Y] = pos[Y] - len / 12;
1263  base[3][Y] = base[5][Y] = pos[Y] + len / 12;
1264 
1265  /* make sure we are drawing in front buffer */
1266  GS_set_draw(GSD_FRONT);
1267 
1268  gsd_pushmatrix();
1269  gsd_do_scale(1); /* get map scale factor */
1270 
1271  glNormal3fv(Ntop);
1272 
1273  gsd_color_func(bar_clr);
1274 
1275  gsd_linewidth(3); /* could be optional */
1276 
1277  /* ------- */
1278  gsd_bgnline();
1279  gsd_vert_func(base[0]);
1280  gsd_vert_func(base[1]);
1281  gsd_endline();
1282 
1283  /* |------- */
1284  gsd_bgnline();
1285  gsd_vert_func(base[2]);
1286  gsd_vert_func(base[3]);
1287  gsd_endline();
1288 
1289  /* |-------| */
1290  gsd_bgnline();
1291  gsd_vert_func(base[4]);
1292  gsd_vert_func(base[5]);
1293  gsd_endline();
1294 
1295  /* TODO -- draw units */
1296 
1297  GS_done_draw();
1298 
1299  gsd_popmatrix();
1300  gsd_flush();
1301 
1302  return 1;
1303 }
1304 
1312 void primitive_cone(unsigned long col)
1313 {
1314  float tip[3];
1315  static int first = 1;
1316 
1317  if (first) {
1318  init_stuff();
1319  first = 0;
1320  }
1321 
1322  tip[X] = tip[Y] = 0.0;
1323  tip[Z] = 1.0;
1324 
1325  gsd_bgntfan();
1326  gsd_litvert_func2(UP_NORM, col, tip);
1327  gsd_litvert_func2(ogverts[0], col, ogverts[0]);
1328  gsd_litvert_func2(ogverts[1], col, ogverts[1]);
1329  gsd_litvert_func2(ogverts[2], col, ogverts[2]);
1330  gsd_litvert_func2(ogverts[3], col, ogverts[3]);
1331  gsd_litvert_func2(ogverts[4], col, ogverts[4]);
1332  gsd_litvert_func2(ogverts[5], col, ogverts[5]);
1333  gsd_litvert_func2(ogverts[6], col, ogverts[6]);
1334  gsd_litvert_func2(ogverts[7], col, ogverts[7]);
1335  gsd_litvert_func2(ogverts[0], col, ogverts[0]);
1336  gsd_endtfan();
1337 
1338  return;
1339 }
1340 
1349 void primitive_cylinder(unsigned long col, int caps)
1350 {
1351  static int first = 1;
1352 
1353  if (first) {
1354  init_stuff();
1355  first = 0;
1356  }
1357 
1358  gsd_bgnqstrip();
1359  gsd_litvert_func2(ogverts[0], col, ogvertsplus[0]);
1360  gsd_litvert_func2(ogverts[0], col, ogverts[0]);
1361  gsd_litvert_func2(ogverts[1], col, ogvertsplus[1]);
1362  gsd_litvert_func2(ogverts[1], col, ogverts[1]);
1363  gsd_litvert_func2(ogverts[2], col, ogvertsplus[2]);
1364  gsd_litvert_func2(ogverts[2], col, ogverts[2]);
1365  gsd_litvert_func2(ogverts[3], col, ogvertsplus[3]);
1366  gsd_litvert_func2(ogverts[3], col, ogverts[3]);
1367  gsd_litvert_func2(ogverts[4], col, ogvertsplus[4]);
1368  gsd_litvert_func2(ogverts[4], col, ogverts[4]);
1369  gsd_litvert_func2(ogverts[5], col, ogvertsplus[5]);
1370  gsd_litvert_func2(ogverts[5], col, ogverts[5]);
1371  gsd_litvert_func2(ogverts[6], col, ogvertsplus[6]);
1372  gsd_litvert_func2(ogverts[6], col, ogverts[6]);
1373  gsd_litvert_func2(ogverts[7], col, ogvertsplus[7]);
1374  gsd_litvert_func2(ogverts[7], col, ogverts[7]);
1375  gsd_litvert_func2(ogverts[0], col, ogvertsplus[0]);
1376  gsd_litvert_func2(ogverts[0], col, ogverts[0]);
1377  gsd_endqstrip();
1378 
1379  if (caps) {
1380  /* draw top */
1381  gsd_bgntfan();
1392  gsd_endtfan();
1393 
1394  /* draw bottom */
1395  gsd_bgntfan();
1406  gsd_endtfan();
1407  }
1408 
1409  return;
1410 }
1411 
1412 /*** ACS_MODIFY_BEGIN - sites_attribute management ********************************/
1413 /*
1414  Draws boxes that are used for histograms by gpd_obj function in gpd.c
1415  for site_attribute management
1416  */
1417 
1421 float Box[8][3] =
1422  { {1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0}, {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0},
1423 {1.0, -1.0, -1.0}, {-1.0, -1.0, -1.0}, {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}
1424 };
1425 
1426 float BoxN[6][3] =
1427  { {0, 0, -ONORM}, {0, 0, ONORM}, {0, ONORM, 0}, {0, -ONORM, 0}, {ONORM, 0,
1428  0},
1429  {-ONORM, 0, 0} };
1430 
1440 void gsd_box(float *center, int colr, float *siz)
1441 {
1442  int preshade;
1443 
1444  gsd_pushmatrix();
1445  gsd_translate(center[X], center[Y], center[Z] + siz[2]);
1446  gsd_scale(siz[0], siz[1], siz[2]);
1447  preshade = gsd_getshademodel();
1448  gsd_shademodel(0); /* want flat shading */
1449 
1450  /* Top */
1451  gsd_bgnpolygon();
1452  gsd_litvert_func(BoxN[2], colr, Box[0]);
1453  gsd_litvert_func(BoxN[2], colr, Box[1]);
1454  gsd_litvert_func(BoxN[2], colr, Box[2]);
1455  gsd_litvert_func(BoxN[2], colr, Box[3]);
1456  gsd_endpolygon();
1457 
1458  /* Bottom */
1459  gsd_bgnpolygon();
1460  gsd_litvert_func(BoxN[3], colr, Box[7]);
1461  gsd_litvert_func(BoxN[3], colr, Box[6]);
1462  gsd_litvert_func(BoxN[3], colr, Box[5]);
1463  gsd_litvert_func(BoxN[3], colr, Box[4]);
1464  gsd_endpolygon();
1465 
1466  /* Right */
1467  gsd_bgnpolygon();
1468  gsd_litvert_func(BoxN[4], colr, Box[0]);
1469  gsd_litvert_func(BoxN[4], colr, Box[3]);
1470  gsd_litvert_func(BoxN[4], colr, Box[7]);
1471  gsd_litvert_func(BoxN[4], colr, Box[4]);
1472  gsd_endpolygon();
1473 
1474  /* Left */
1475  gsd_bgnpolygon();
1476  gsd_litvert_func(BoxN[5], colr, Box[1]);
1477  gsd_litvert_func(BoxN[5], colr, Box[5]);
1478  gsd_litvert_func(BoxN[5], colr, Box[6]);
1479  gsd_litvert_func(BoxN[5], colr, Box[2]);
1480  gsd_endpolygon();
1481 
1482  /* Front */
1483  gsd_bgnpolygon();
1484  gsd_litvert_func(BoxN[0], colr, Box[0]);
1485  gsd_litvert_func(BoxN[0], colr, Box[4]);
1486  gsd_litvert_func(BoxN[0], colr, Box[5]);
1487  gsd_litvert_func(BoxN[0], colr, Box[1]);
1488  gsd_endpolygon();
1489 
1490  /* Back */
1491  gsd_bgnpolygon();
1492  gsd_litvert_func(BoxN[1], colr, Box[3]);
1493  gsd_litvert_func(BoxN[1], colr, Box[2]);
1494  gsd_litvert_func(BoxN[1], colr, Box[6]);
1495  gsd_litvert_func(BoxN[1], colr, Box[7]);
1496  gsd_endpolygon();
1497 
1498  gsd_popmatrix();
1499  gsd_shademodel(preshade);
1500  return;
1501 }
1502 
1503 /*** ACS_MODIFY_END - sites_attribute management ********************************/
void gsd_3dcursor(float *pt)
Draw 3d cursor.
Definition: gsd_objs.c:711
void gsd_calllist(int listno)
ADD.
Definition: gsd_prim.c:1154
float Octo[6][3]
vertices for octohedron
Definition: gsd_objs.c:34
void gsd_endlist(void)
End list.
Definition: gsd_prim.c:1121
void gsd_diamond_lines(void)
Draw diamond lines.
Definition: gsd_objs.c:577
void gsd_endqstrip(void)
ADD.
Definition: gsd_prim.c:277
void gsd_bgntmesh(void)
ADD.
Definition: gsd_prim.c:287
float origin[3]
Definition: gsd_objs.c:88
void gsd_circ(float x, float y, float rad)
ADD.
Definition: gsd_prim.c:157
float ogverts[8][3]
vertices & normals for octagon in xy plane
Definition: gsd_objs.c:97
float Box[8][3]
Vertices for box.
Definition: gsd_objs.c:1421
void gsd_do_scale(int doexag)
Set current scale.
Definition: gsd_views.c:355
void gsd_sphere(float *center, float siz)
ADD.
Definition: gsd_prim.c:197
int gsd_makelist(void)
ADD.
Definition: gsd_prim.c:1074
int GS_v3dir(float *v1, float *v2, float *v3)
Get a normalized direction from v1 to v2, store in v3.
Definition: gs_util.c:353
#define ONORM
Definition: gsd_objs.c:43
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:362
void gsd_draw_box(float *center, unsigned long colr, float siz)
Draw box.
Definition: gsd_objs.c:506
int GS_v3norm(float *v1)
Change v1 so that it is a unit vector (2D)
Definition: gs_util.c:246
void GS_v3add(float *v1, float *v2)
Sum vectors.
Definition: gs_util.c:195
void gsd_color_func(unsigned int col)
Set current color.
Definition: gsd_prim.c:689
#define NULL
Definition: ccmath.h:32
void gsd_endtmesh(void)
ADD.
Definition: gsd_prim.c:297
float BoxN[6][3]
Definition: gsd_objs.c:1426
int gsd_north_arrow(float *pos2, float len, GLuint fontbase, unsigned long arw_clr, unsigned long text_clr)
Draw North Arrow takes OpenGL coords and size.
Definition: gsd_objs.c:827
void gsd_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:526
void gsd_litvert_func(float *norm, unsigned long col, float *pt)
Set the current normal vector & specify vertex.
Definition: gsd_prim.c:648
void gsd_shademodel(int bool)
Set shaded model.
Definition: gsd_prim.c:409
void GS_v3cross(float *v1, float *v2, float *v3)
Get the cross product v3 = v1 cross v2.
Definition: gs_util.c:406
#define UP_NORM
Definition: gsd_objs.c:90
#define Y(n)
Definition: plot.c:141
void gsd_plus(float *center, int colr, float siz)
ADD.
Definition: gsd_objs.c:152
void gsd_x(geosurf *gs, float *center, int colr, float siz)
Draw X symbol.
Definition: gsd_objs.c:278
void gsd_swaptmesh(void)
ADD.
Definition: gsd_prim.c:347
void gsd_bgntfan(void)
ADD.
Definition: gsd_prim.c:327
int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid, geosurf *gs)
Draw north arrow on surface.
Definition: gsd_objs.c:995
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:498
void gsd_bgnqstrip(void)
ADD.
Definition: gsd_prim.c:267
void gsd_backface(int n)
ADD.
Definition: gsd_prim.c:244
int gsd_get_txtheight(int size)
Get text height.
Definition: gsd_fonts.c:53
void gsd_cube(float *center, unsigned long colr, float siz)
Draw cube.
Definition: gsd_objs.c:429
void gsd_bgnlist(int listno, int do_draw)
ADD.
Definition: gsd_prim.c:1106
void gsd_diamond(float *center, unsigned long colr, float siz)
Draw diamond symbol.
Definition: gsd_objs.c:327
float OctoN[8][3]
normals for flat-shaded octohedron
Definition: gsd_objs.c:48
void gsd_endline(void)
End line.
Definition: gsd_prim.c:397
void GS_v3mult(float *v1, float k)
Multiple vectors.
Definition: gs_util.c:229
#define TRUE
Definition: dbfopen.c:118
struct list * list
Definition: read_list.c:24
void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
ADD.
Definition: gsd_objs.c:755
void gsd_endtfan(void)
ADD.
Definition: gsd_prim.c:337
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
float CubeVertices[8][3]
Definition: gsd_objs.c:77
void gsd_disc(float x, float y, float z, float rad)
ADD.
Definition: gsd_prim.c:177
void gsd_rot(float angle, char axis)
ADD.
Definition: gsd_prim.c:597
int gsd_scalebar(float *pos2, float len, GLuint fontbase, unsigned long bar_clr, unsigned long text_clr)
Draw Scalebar takes OpenGL coords and size.
Definition: gsd_objs.c:1161
int gsd_nline_onsurf(geosurf *gs, float *v1, float *v2, float *pt, int n)
Multiline on surface, fix z-values.
Definition: gsd_objs.c:235
void primitive_cylinder(unsigned long col, int caps)
Primitives only called after transforms.
Definition: gsd_objs.c:1349
#define DOWN_NORM
Definition: gsd_objs.c:91
void gsd_litvert_func2(float *norm, unsigned long col, float *pt)
ADD.
Definition: gsd_prim.c:664
float Pi
Definition: gsd_objs.c:104
#define ORIGIN
Definition: gsd_objs.c:92
void gsd_vert_func(float *pt)
ADD.
Definition: gsd_prim.c:677
void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
Draw asterisk.
Definition: gsd_objs.c:604
float ogvertsplus[8][3]
vertices for octagon in xy plane, z=1
Definition: gsd_objs.c:102
void gsd_line_onsurf(geosurf *gs, float *v1, float *v2)
Line on surface, fix z-values.
Definition: gsd_objs.c:189
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition: gs2.c:2463
Point3 * gsdrape_get_segments(geosurf *gs, float *bgn, float *end, int *num)
ADD.
Definition: gsdrape.c:350
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:377
void GS_v3eq(float *v1, float *v2)
Copy vector values.
Definition: gs_util.c:178
float CubeNormals[3][3]
Definition: gsd_objs.c:71
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition: gsd_prim.c:257
void gsd_flush(void)
Mostly for flushing drawing commands accross a network.
Definition: gsd_prim.c:74
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:488
void gsd_box(float *center, int colr, float *siz)
Draw box.
Definition: gsd_objs.c:1440
int gsd_getshademodel(void)
Get shaded model.
Definition: gsd_prim.c:428
#define X(e)
Definition: plot.c:140
int gsd_scalebar_v2(float *pos, float len, GLuint fontbase, unsigned long bar_clr, unsigned long text_clr)
Draw Scalebar (as lines)
Definition: gsd_objs.c:1249
void gsd_draw_gyro(float *center, unsigned long colr, float siz)
Draw gyro.
Definition: gsd_objs.c:659
void primitive_cone(unsigned long col)
Primitives only called after transforms.
Definition: gsd_objs.c:1312
void gsd_scale(float xs, float ys, float zs)
Multiply the current matrix by a general scaling matrix.
Definition: gsd_prim.c:512
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:387
void GS_v3mag(float *v1, float *mag)
Magnitude of vector.
Definition: gs_util.c:421
void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2, float *dir, float sz)
Draw 3d north arrow.
Definition: gsd_objs.c:1082
float GS_P2distance(float *from, float *to)
Calculate distance in plane.
Definition: gs_util.c:160
int gsd_get_txtwidth(const char *s, int size)
Get text width.
Definition: gsd_fonts.c:36
void gsd_drawsphere(float *center, unsigned long colr, float siz)
Draw sphere.
Definition: gsd_objs.c:565
int gsd_arrow(float *center, unsigned long colr, float siz, float *dir, float sz, geosurf *onsurf)
ADD.
Definition: gsd_objs.c:923
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2502
float Ntop[]
Definition: gsd_fringe.c:36
const char * G_database_unit_name(int plural)
Get units (localized) name for the current location.
Definition: proj3.c:50