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