GRASS GIS 8 Programmer's Manual 8.2.0(2022)-exported
gsd_objs.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gsd_label.c
3
4 \brief OGSF library - objects management (lower level functions)
5
6 GRASS OpenGL gsurf OGSF Library
7
8 (C) 1999-2008 by the GRASS Development Team
9
10 This program is free software under the
11 GNU General Public License (>=v2).
12 Read the file COPYING that comes with GRASS
13 for details.
14
15 \author Bill Brown USACERL (October 1993)
16 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
17 */
18
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
29static void init_stuff(void);
30
31/*!
32 \brief vertices for octahedron
33 */
34float 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
45/*!
46 \brief normals for flat-shaded octahedron
47 */
48float 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
59/*!
60 ???? not sure if any of these are needed for correct lighting.
61 float CubeNormals[6][3] = {
62 {ONORM, 0, 0},
63 {-ONORM, 0, 0},
64 {0, ONORM, 0},
65 {0, -ONORM, 0},
66 {0, 0, ONORM},
67 {0, 0, -ONORM}
68 };
69 */
70
71float CubeNormals[3][3] = {
72 {0, -ONORM, 0},
73 {0, 0, ONORM},
74 {ONORM, 0, 0}
75};
76
77float 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
88float 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
94/*!
95 \brief vertices & normals for octagon in xy plane
96 */
97float ogverts[8][3];
98
99/*!
100 \brief vertices for octagon in xy plane, z=1
101 */
102float ogvertsplus[8][3];
103
104float Pi;
105
106static 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
145/*!
146 \brief ADD
147
148 \param center center point
149 \param colr color value
150 \param siz size value
151 */
152void 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
180/*!
181 \brief Line on surface, fix z-values
182
183 \todo remove fudge, instead fudge the Z buffer
184
185 \param gs surface (geosurf)
186 \param v1 first point
187 \param v2 second point
188 */
189void 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
218/*!
219 \brief Multiline on surface, fix z-values
220
221 \todo remove fudge, instead fudge the Z buffer
222
223 Like above, except only draws first n points of line, or np,
224 whichever is less. Returns number of points used. Fills
225 pt with last pt drawn.
226
227 \param gs surface (geosurf)
228 \param v1 first point
229 \param v2 second point
230 \param pt
231 \param n number of segments
232
233 \param number of vertices
234 */
235int 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
268/*!
269 \brief Draw X symbol
270
271 Note gs: NULL if flat
272
273 \param gs surface (geosurf)
274 \param center
275 \param colr color value
276 \param siz size value
277 */
278void 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
320/*!
321 \brief Draw diamond symbol
322
323 \param center center point
324 \param colr color value
325 \param size size value
326 */
327void 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
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
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]);
346
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]);
352
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]);
358
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]);
364
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]);
370
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]);
376
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]);
382
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]);
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]);
395 gsd_litvert_func(Octo[2], colr, Octo[2]);
397 gsd_litvert_func(Octo[4], colr, Octo[4]);
399 gsd_litvert_func(Octo[5], colr, Octo[5]);
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]);
405 gsd_litvert_func(Octo[4], colr, Octo[4]);
407 gsd_litvert_func(Octo[5], colr, Octo[5]);
409 gsd_litvert_func(Octo[1], colr, Octo[1]);
410 gsd_endtmesh();
411 }
412#endif
413
415 gsd_shademodel(preshade);
416
417 return;
418}
419
420/*!
421 \brief Draw cube
422
423 Added by Hamish Bowman Nov 2005
424
425 \param center center point
426 \param colr color value
427 \param siz size value
428 */
429void 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
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: */
450
451 /* S wall: */
458
459 /* E wall: */
466
467 /* W wall: */
474
475 /* lower wall: */
482
483 /* top wall: */
490
492 gsd_shademodel(preshade);
493
494 return;
495}
496
497/*!
498 \brief Draw box
499
500 Added by Hamish Bowman Nov 2005
501
502 \param center center point
503 \param colr color value
504 \param siz size value
505 */
506void 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
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
554
555 return;
556}
557
558/*!
559 \brief Draw sphere
560
561 \param center center point
562 \param colr color value
563 \param size size value
564 */
565void 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
574/*!
575 \brief Draw diamond lines
576 */
578{
579 gsd_bgnline();
582 gsd_endline();
583
584 gsd_bgnline();
587 gsd_endline();
588
589 gsd_bgnline();
592 gsd_endline();
593
594 return;
595}
596
597/*!
598 \brief Draw asterisk
599
600 \param center center point
601 \param colr color value
602 \param siz size value
603 */
604void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
605{
606 float angle;
607
608 angle = 45.; /* degrees */
609
611 gsd_translate(center[X], center[Y], center[Z]);
612 gsd_scale(siz, siz, siz);
613 gsd_color_func(colr);
614
616
618 gsd_rot(angle, 'x');
621
623 gsd_rot(-angle, 'x');
626
628 gsd_rot(angle, 'y');
631
633 gsd_rot(-angle, 'y');
636
638 gsd_rot(angle, 'z');
641
643 gsd_rot(-angle, 'z');
646
648
649 return;
650}
651
652/*!
653 \brief Draw gyro
654
655 \param center center point
656 \param colr color value
657 \param siz size value
658 */
659void gsd_draw_gyro(float *center, unsigned long colr, float siz)
660{
661 int i;
662
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();
672 gsd_endline();
673
674 /* spokes */
676
677 for (i = 0; i < 6; i++) {
678 gsd_rot(30., 'z');
679 gsd_bgnline();
682 gsd_endline();
683 }
684
686
687 gsd_color_func(colr);
688
689 gsd_circ(0., 0., 1.);
690
692 gsd_rot(90., 'x');
693 gsd_circ(0., 0., 1.);
695
697 gsd_rot(90., 'y');
698 gsd_circ(0., 0., 1.);
700
702
703 return;
704}
705
706/*!
707 \brief Draw 3d cursor
708
709 \param pt point
710 */
711void 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
747/*!
748 \brief ADD
749
750 \param dir
751 \param slope
752 \param ascpect
753 \param degrees
754 */
755void 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
814/*!
815 \brief Draw North Arrow takes OpenGL coords and size
816
817 \param pos2
818 \param len
819 \param fontbase
820 \param arw_clr north arrow color
821 \param text_clr text color
822
823 \return 1
824 */
825/*TODO: Store arrow somewhere to enable it's removal/change.
826 Add option to specify north text and font. */
827int 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
855 gsd_do_scale(1);
856
857 glNormal3fv(Ntop);
858 gsd_color_func(arw_clr);
859
861 glVertex3fv(base[0]);
862 glVertex3fv(base[1]);
863 glVertex3fv(base[2]);
865
867 glVertex3fv(v[0]);
868 glVertex3fv(v[1]);
869 glVertex3fv(v[2]);
870 glVertex3fv(v[0]);
872
874 glVertex3fv(v[0]);
875 glVertex3fv(v[2]);
876 glVertex3fv(v[3]);
877 glVertex3fv(v[0]);
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
898 gsd_flush();
899
900 return (1);
901
902}
903
904/*!
905 \brief ADD
906
907 siz is height, sz is global exag to correct for.
908
909 If onsurf in non-null, z component of dir is dropped and
910 line-on-suf is used, resulting in length of arrow being proportional
911 to slope
912
913 \param center center point
914 \param colr color value
915 \param siz size value
916 \param dir
917 \param sz
918 \param onsurf surface (geosurf)
919
920 \return 1 no surface given
921 \return 0 on surface
922 */
923int 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
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
980
981 return (1);
982}
983
984/*!
985 \brief Draw north arrow on surface
986
987 \param base
988 \param tip
989 \param colr
990 \param wid
991 \param gs surface (geosurf)
992
993 \return 0
994 */
995int 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
1072/*!
1073 \brief Draw 3d north arrow
1074
1075 \param center center point
1076 \param colr color value
1077 \param siz1 height
1078 \param siz2 is diameter
1079 \param dir
1080 \param sz
1081 */
1082void 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? */
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
1126 gsd_scale(.10, .10, .75); /* narrow cyl */
1127 primitive_cylinder(colr, 0);
1128 gsd_popmatrix();
1129
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 {
1141 }
1142
1143 gsd_popmatrix();
1144 gsd_shademodel(preshade);
1145
1146 return;
1147}
1148
1149/*!
1150 \brief Draw Scalebar takes OpenGL coords and size
1151
1152 Adapted from gsd_north_arrow Hamish Bowman Dec 2006
1153
1154 \param pos2
1155 \param fontbase font-base
1156 \param bar_clr barscale color
1157 \param text_clr text color
1158
1159 \return 1
1160 */
1161int 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
1182 gsd_do_scale(1); /* get map scale factor */
1183
1184 glNormal3fv(Ntop);
1185
1186 gsd_color_func(bar_clr);
1187
1189 glVertex3fv(base[0]);
1190 glVertex3fv(base[1]);
1191 glVertex3fv(base[2]);
1192 glVertex3fv(base[3]);
1193 glVertex3fv(base[0]);
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
1237/*!
1238 \brief Draw Scalebar (as lines)
1239
1240 Adapted from gsd_scalebar A.Kratochvilova 2011
1241
1242 \param pos2 scalebar position
1243 \param fontbase font-base (unused)
1244 \param bar_clr barscale color
1245 \param text_clr text color (unused)
1246
1247 \return 1
1248 */
1249int 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
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
1305/*!
1306 \brief Primitives only called after transforms
1307
1308 Center is actually center at base of 8 sided cone
1309
1310 \param col color value
1311 */
1312void 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
1341/*!
1342 \brief Primitives only called after transforms
1343
1344 Center is actually center at base of 8 sided cylinder
1345
1346 \param col color value
1347 \param caps
1348 */
1349void 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();
1360 gsd_litvert_func2(ogverts[0], col, ogverts[0]);
1362 gsd_litvert_func2(ogverts[1], col, ogverts[1]);
1364 gsd_litvert_func2(ogverts[2], col, ogverts[2]);
1366 gsd_litvert_func2(ogverts[3], col, ogverts[3]);
1368 gsd_litvert_func2(ogverts[4], col, ogverts[4]);
1370 gsd_litvert_func2(ogverts[5], col, ogverts[5]);
1372 gsd_litvert_func2(ogverts[6], col, ogverts[6]);
1374 gsd_litvert_func2(ogverts[7], col, ogverts[7]);
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
1418/*!
1419 \brief Vertices for box
1420 */
1421float 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
1426float 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
1431/*!
1432 \brief Draw box
1433
1434 Warning siz is an array (we need it for scale only Z in histograms)
1435
1436 \param center center point
1437 \param colr color value
1438 \param siz size value
1439 */
1440void gsd_box(float *center, int colr, float *siz)
1441{
1442 int preshade;
1443
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 */
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]);
1457
1458 /* Bottom */
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]);
1465
1466 /* Right */
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]);
1473
1474 /* Left */
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]);
1481
1482 /* Front */
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]);
1489
1490 /* Back */
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]);
1497
1498 gsd_popmatrix();
1499 gsd_shademodel(preshade);
1500 return;
1501}
1502
1503/*** ACS_MODIFY_END - sites_attribute management ********************************/
#define NULL
Definition: ccmath.h:32
#define TRUE
Definition: dbfopen.c:183
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition: gs2.c:2462
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2501
void GS_v3mult(float *v1, float k)
Multiple vectors.
Definition: gs_util.c:229
void GS_v3mag(float *v1, float *mag)
Magnitude of vector.
Definition: gs_util.c:421
void GS_v3add(float *v1, float *v2)
Sum vectors.
Definition: gs_util.c:195
int GS_v3norm(float *v1)
Change v1 so that it is a unit vector (2D)
Definition: gs_util.c:246
void GS_v3eq(float *v1, float *v2)
Copy vector values.
Definition: gs_util.c:178
float GS_P2distance(float *from, float *to)
Calculate distance in plane.
Definition: gs_util.c:160
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
void GS_v3cross(float *v1, float *v2, float *v3)
Get the cross product v3 = v1 cross v2.
Definition: gs_util.c:406
int gsd_get_txtwidth(const char *s, int size)
Get text width.
Definition: gsd_fonts.c:36
int gsd_get_txtheight(int size)
Get text height.
Definition: gsd_fonts.c:53
float Ntop[]
Definition: gsd_fringe.c:36
void gsd_3dcursor(float *pt)
Draw 3d cursor.
Definition: gsd_objs.c:711
void gsd_diamond(float *center, unsigned long colr, float siz)
Draw diamond symbol.
Definition: gsd_objs.c:327
void primitive_cylinder(unsigned long col, int caps)
Primitives only called after transforms.
Definition: gsd_objs.c:1349
float Box[8][3]
Vertices for box.
Definition: gsd_objs.c:1421
void gsd_draw_box(float *center, unsigned long colr, float siz)
Draw box.
Definition: gsd_objs.c:506
#define UP_NORM
Definition: gsd_objs.c:90
float CubeNormals[3][3]
Definition: gsd_objs.c:71
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 CubeVertices[8][3]
Definition: gsd_objs.c:77
#define DOWN_NORM
Definition: gsd_objs.c:91
void gsd_line_onsurf(geosurf *gs, float *v1, float *v2)
Line on surface, fix z-values.
Definition: gsd_objs.c:189
int gsd_arrow(float *center, unsigned long colr, float siz, float *dir, float sz, geosurf *onsurf)
ADD.
Definition: gsd_objs.c:923
void gsd_x(geosurf *gs, float *center, int colr, float siz)
Draw X symbol.
Definition: gsd_objs.c:278
float Pi
Definition: gsd_objs.c:104
#define ORIGIN
Definition: gsd_objs.c:92
void gsd_drawsphere(float *center, unsigned long colr, float siz)
Draw sphere.
Definition: gsd_objs.c:565
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
float BoxN[6][3]
Definition: gsd_objs.c:1426
float ogverts[8][3]
vertices & normals for octagon in xy plane
Definition: gsd_objs.c:97
void gsd_cube(float *center, unsigned long colr, float siz)
Draw cube.
Definition: gsd_objs.c:429
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 gsd_diamond_lines(void)
Draw diamond lines.
Definition: gsd_objs.c:577
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
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
float OctoN[8][3]
normals for flat-shaded octahedron
Definition: gsd_objs.c:48
float ogvertsplus[8][3]
vertices for octagon in xy plane, z=1
Definition: gsd_objs.c:102
void primitive_cone(unsigned long col)
Primitives only called after transforms.
Definition: gsd_objs.c:1312
void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
ADD.
Definition: gsd_objs.c:755
float Octo[6][3]
vertices for octahedron
Definition: gsd_objs.c:34
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_asterisk(float *center, unsigned long colr, float siz)
Draw asterisk.
Definition: gsd_objs.c:604
#define ONORM
Definition: gsd_objs.c:43
void gsd_box(float *center, int colr, float *siz)
Draw box.
Definition: gsd_objs.c:1440
void gsd_draw_gyro(float *center, unsigned long colr, float siz)
Draw gyro.
Definition: gsd_objs.c:659
void gsd_plus(float *center, int colr, float siz)
ADD.
Definition: gsd_objs.c:152
float origin[3]
Definition: gsd_objs.c:88
void gsd_endlist(void)
End list.
Definition: gsd_prim.c:1143
void gsd_endtfan(void)
ADD.
Definition: gsd_prim.c:346
void gsd_endtmesh(void)
ADD.
Definition: gsd_prim.c:306
void gsd_swaptmesh(void)
ADD.
Definition: gsd_prim.c:356
void gsd_backface(int n)
ADD.
Definition: gsd_prim.c:253
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
void gsd_calllist(int listno)
ADD.
Definition: gsd_prim.c:1176
void gsd_vert_func(float *pt)
ADD.
Definition: gsd_prim.c:689
void gsd_bgnqstrip(void)
ADD.
Definition: gsd_prim.c:276
void gsd_litvert_func(float *norm, unsigned long col, float *pt)
Set the current normal vector & specify vertex.
Definition: gsd_prim.c:660
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:371
int gsd_getshademodel(void)
Get shaded model.
Definition: gsd_prim.c:437
void gsd_bgnlist(int listno, int do_draw)
ADD.
Definition: gsd_prim.c:1128
int gsd_makelist(void)
ADD.
Definition: gsd_prim.c:1096
void gsd_endqstrip(void)
ADD.
Definition: gsd_prim.c:286
void gsd_sphere(float *center, float siz)
ADD.
Definition: gsd_prim.c:206
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
void gsd_flush(void)
Mostly for flushing drawing commands across a network.
Definition: gsd_prim.c:83
void gsd_endline(void)
End line.
Definition: gsd_prim.c:406
void gsd_circ(float x, float y, float rad)
ADD.
Definition: gsd_prim.c:166
void gsd_bgntfan(void)
ADD.
Definition: gsd_prim.c:336
void gsd_rot(float angle, char axis)
ADD.
Definition: gsd_prim.c:609
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:396
void gsd_scale(float xs, float ys, float zs)
Multiply the current matrix by a general scaling matrix.
Definition: gsd_prim.c:524
void gsd_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:538
void gsd_bgntmesh(void)
ADD.
Definition: gsd_prim.c:296
void gsd_disc(float x, float y, float z, float rad)
ADD.
Definition: gsd_prim.c:186
void gsd_litvert_func2(float *norm, unsigned long col, float *pt)
ADD.
Definition: gsd_prim.c:676
void gsd_color_func(unsigned int col)
Set current color.
Definition: gsd_prim.c:701
void gsd_shademodel(int shade)
Set shaded model.
Definition: gsd_prim.c:418
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:386
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition: gsd_prim.c:266
void gsd_do_scale(int doexag)
Set current scale.
Definition: gsd_views.c:355
Point3 * gsdrape_get_segments(geosurf *gs, float *bgn, float *end, int *num)
ADD.
Definition: gsdrape.c:350
const char * G_database_unit_name(int plural)
Get units (localized) name for the current location.
Definition: proj3.c:53
struct list * list
Definition: read_list.c:24
#define X(j)
#define Y(j)