GRASS Programmer's Manual  6.4.2(2012)
gsd_objs.c
Go to the documentation of this file.
00001 
00019 #include <stdlib.h>
00020 #include <string.h>
00021 
00022 #include <grass/gis.h>
00023 #include <grass/ogsf_proto.h>
00024 #include <grass/gstypes.h>
00025 
00026 #include "gsget.h"
00027 #include "math.h"
00028 #include "rowcol.h"
00029 
00030 static void init_stuff(void);
00031 
00035 float Octo[6][3] = {
00036     {1.0, 0.0, 0.0},
00037     {0.0, 1.0, 0.0},
00038     {0.0, 0.0, 1.0},
00039     {-1.0, 0.0, 0.0},
00040     {0.0, -1.0, 0.0},
00041     {0.0, 0.0, -1.0}
00042 };
00043 
00044 #define ONORM .57445626
00045 
00049 float OctoN[8][3] = {
00050     {ONORM, ONORM, ONORM},
00051     {-ONORM, ONORM, ONORM},
00052     {ONORM, -ONORM, ONORM},
00053     {-ONORM, -ONORM, ONORM},
00054     {ONORM, ONORM, -ONORM},
00055     {-ONORM, ONORM, -ONORM},
00056     {ONORM, -ONORM, -ONORM},
00057     {-ONORM, -ONORM, -ONORM},
00058 };
00059 
00072 float CubeNormals[3][3] = {
00073     {0, -ONORM, 0},
00074     {0, 0, ONORM},
00075     {ONORM, 0, 0}
00076 };
00077 
00078 float CubeVertices[8][3] = {
00079     {-1.0, -1.0, -1.0},
00080     {1.0, -1.0, -1.0},
00081     {1.0, 1.0, -1.0},
00082     {-1.0, 1.0, -1.0},
00083     {-1.0, -1.0, 1.0},
00084     {1.0, -1.0, 1.0},
00085     {1.0, 1.0, 1.0},
00086     {-1.0, 1.0, 1.0}
00087 };
00088 
00089 float origin[3] = { 0.0, 0.0, 0.0 };
00090 
00091 #define UP_NORM Octo[2]
00092 #define DOWN_NORM Octo[5]
00093 #define ORIGIN origin
00094 
00098 float ogverts[8][3];
00099 
00103 float ogvertsplus[8][3];
00104 
00105 float Pi;
00106 
00107 static void init_stuff(void)
00108 {
00109     float cos45;
00110     int i;
00111     static int first = 1;
00112 
00113     if (first) {
00114         first = 0;
00115 
00116         cos45 = cos(atan(1.0));
00117 
00118         for (i = 0; i < 8; i++) {
00119             ogverts[i][Z] = 0.0;
00120             ogvertsplus[i][Z] = 1.0;
00121         }
00122 
00123         ogverts[0][X] = ogvertsplus[0][X] = 1.0;
00124         ogverts[0][Y] = ogvertsplus[0][Y] = 0.0;
00125         ogverts[1][X] = ogvertsplus[1][X] = cos45;
00126         ogverts[1][Y] = ogvertsplus[1][Y] = cos45;
00127         ogverts[2][X] = ogvertsplus[2][X] = 0.0;
00128         ogverts[2][Y] = ogvertsplus[2][Y] = 1.0;
00129         ogverts[3][X] = ogvertsplus[3][X] = -cos45;
00130         ogverts[3][Y] = ogvertsplus[3][Y] = cos45;
00131         ogverts[4][X] = ogvertsplus[4][X] = -1.0;
00132         ogverts[4][Y] = ogvertsplus[4][Y] = 0.0;
00133         ogverts[5][X] = ogvertsplus[5][X] = -cos45;
00134         ogverts[5][Y] = ogvertsplus[5][Y] = -cos45;
00135         ogverts[6][X] = ogvertsplus[6][X] = 0.0;
00136         ogverts[6][Y] = ogvertsplus[6][Y] = -1.0;
00137         ogverts[7][X] = ogvertsplus[7][X] = cos45;
00138         ogverts[7][Y] = ogvertsplus[7][Y] = -cos45;
00139 
00140         Pi = 4.0 * atan(1.0);
00141     }
00142 
00143     return;
00144 }
00145 
00153 void gsd_plus(float *center, int colr, float siz)
00154 {
00155     float v1[3], v2[3];
00156 
00157     gsd_color_func(colr);
00158     siz *= .5;
00159 
00160     v1[Z] = v2[Z] = center[Z];
00161 
00162     v1[X] = v2[X] = center[X];
00163     v1[Y] = center[Y] - siz;
00164     v2[Y] = center[Y] + siz;
00165     gsd_bgnline();
00166     gsd_vert_func(v1);
00167     gsd_vert_func(v2);
00168     gsd_endline();
00169 
00170     v1[Y] = v2[Y] = center[Y];
00171     v1[X] = center[X] - siz;
00172     v2[X] = center[X] + siz;
00173     gsd_bgnline();
00174     gsd_vert_func(v1);
00175     gsd_vert_func(v2);
00176     gsd_endline();
00177 
00178     return;
00179 }
00180 
00190 void gsd_line_onsurf(geosurf * gs, float *v1, float *v2)
00191 {
00192     int i, np;
00193     Point3 *pts;
00194     float fudge;
00195 
00196     pts = gsdrape_get_segments(gs, v1, v2, &np);
00197     if (pts) {
00198         fudge = FUDGE(gs);
00199         gsd_bgnline();
00200 
00201         for (i = 0; i < np; i++) {
00202             /* ACS */
00203             /* reverting back, as it broke displaying X symbol and query line */
00204             pts[i][Z] += fudge;
00205             /*pts[i][Z] *= fudge;*/
00206             gsd_vert_func(pts[i]);
00207         }
00208 
00209         gsd_endline();
00210 
00211         /* fix Z values? */
00212         v1[Z] = pts[0][Z];
00213         v2[Z] = pts[np - 1][Z];
00214     }
00215 
00216     return;
00217 }
00218 
00236 int gsd_nline_onsurf(geosurf * gs, float *v1, float *v2, float *pt, int n)
00237 {
00238     int i, np, pdraw;
00239     Point3 *pts;
00240     float fudge;
00241 
00242     pts = gsdrape_get_segments(gs, v1, v2, &np);
00243 
00244     if (pts) {
00245         pdraw = n < np ? n : np;
00246         fudge = FUDGE(gs);
00247         gsd_bgnline();
00248 
00249         for (i = 0; i < pdraw; i++) {
00250             pts[i][Z] += fudge;
00251             gsd_vert_func(pts[i]);
00252         }
00253 
00254         gsd_endline();
00255 
00256         pt[X] = pts[i - 1][X];
00257         pt[Y] = pts[i - 1][Y];
00258 
00259         /* fix Z values? */
00260         v1[Z] = pts[0][Z];
00261         v2[Z] = pts[np - 1][Z];
00262 
00263         return (i);
00264     }
00265 
00266     return (0);
00267 }
00268 
00279 void gsd_x(geosurf * gs, float *center, int colr, float siz)
00280 {
00281     float v1[3], v2[3];
00282 
00283     gsd_color_func(colr);
00284     siz *= .5;
00285 
00286     v1[Z] = v2[Z] = center[Z];
00287 
00288     v1[X] = center[X] - siz;
00289     v2[X] = center[X] + siz;
00290     v1[Y] = center[Y] - siz;
00291     v2[Y] = center[Y] + siz;
00292 
00293     if (gs) {
00294         gsd_line_onsurf(gs, v1, v2);
00295     }
00296     else {
00297         gsd_bgnline();
00298         gsd_vert_func(v1);
00299         gsd_vert_func(v2);
00300         gsd_endline();
00301     }
00302 
00303     v1[X] = center[X] - siz;
00304     v2[X] = center[X] + siz;
00305     v1[Y] = center[Y] + siz;
00306     v2[Y] = center[Y] - siz;
00307 
00308     if (gs) {
00309         gsd_line_onsurf(gs, v1, v2);
00310     }
00311     else {
00312         gsd_bgnline();
00313         gsd_vert_func(v1);
00314         gsd_vert_func(v2);
00315         gsd_endline();
00316     }
00317 
00318     return;
00319 }
00320 
00328 void gsd_diamond(float *center, unsigned long colr, float siz)
00329 {
00330     int preshade;
00331 
00332     /* seems right, but isn't
00333        siz *= .5;
00334      */
00335 
00336     gsd_pushmatrix();
00337     gsd_translate(center[X], center[Y], center[Z]);
00338     gsd_scale(siz, siz, siz);
00339     preshade = gsd_getshademodel();
00340     gsd_shademodel(0);          /* want flat shading */
00341 
00342     gsd_bgnpolygon();
00343     gsd_litvert_func(OctoN[0], colr, Octo[0]);
00344     gsd_litvert_func(OctoN[0], colr, Octo[1]);
00345     gsd_litvert_func(OctoN[0], colr, Octo[2]);
00346     gsd_endpolygon();
00347 
00348     gsd_bgnpolygon();
00349     gsd_litvert_func(OctoN[1], colr, Octo[2]);
00350     gsd_litvert_func(OctoN[1], colr, Octo[1]);
00351     gsd_litvert_func(OctoN[1], colr, Octo[3]);
00352     gsd_endpolygon();
00353 
00354     gsd_bgnpolygon();
00355     gsd_litvert_func(OctoN[2], colr, Octo[2]);
00356     gsd_litvert_func(OctoN[2], colr, Octo[4]);
00357     gsd_litvert_func(OctoN[2], colr, Octo[0]);
00358     gsd_endpolygon();
00359 
00360     gsd_bgnpolygon();
00361     gsd_litvert_func(OctoN[3], colr, Octo[2]);
00362     gsd_litvert_func(OctoN[3], colr, Octo[3]);
00363     gsd_litvert_func(OctoN[3], colr, Octo[4]);
00364     gsd_endpolygon();
00365 
00366     gsd_bgnpolygon();
00367     gsd_litvert_func(OctoN[4], colr, Octo[0]);
00368     gsd_litvert_func(OctoN[4], colr, Octo[5]);
00369     gsd_litvert_func(OctoN[4], colr, Octo[1]);
00370     gsd_endpolygon();
00371 
00372     gsd_bgnpolygon();
00373     gsd_litvert_func(OctoN[5], colr, Octo[1]);
00374     gsd_litvert_func(OctoN[5], colr, Octo[5]);
00375     gsd_litvert_func(OctoN[5], colr, Octo[3]);
00376     gsd_endpolygon();
00377 
00378     gsd_bgnpolygon();
00379     gsd_litvert_func(OctoN[6], colr, Octo[5]);
00380     gsd_litvert_func(OctoN[6], colr, Octo[0]);
00381     gsd_litvert_func(OctoN[6], colr, Octo[4]);
00382     gsd_endpolygon();
00383 
00384     gsd_bgnpolygon();
00385     gsd_litvert_func(OctoN[7], colr, Octo[5]);
00386     gsd_litvert_func(OctoN[7], colr, Octo[4]);
00387     gsd_litvert_func(OctoN[7], colr, Octo[3]);
00388     gsd_endpolygon();
00389 
00390 #ifdef OCT_SHADED
00391     {
00392         gsd_bgntmesh();
00393         gsd_litvert_func(Octo[0], colr, Octo[0]);
00394         gsd_litvert_func(Octo[1], colr, Octo[1]);
00395         gsd_swaptmesh();
00396         gsd_litvert_func(Octo[2], colr, Octo[2]);
00397         gsd_swaptmesh();
00398         gsd_litvert_func(Octo[4], colr, Octo[4]);
00399         gsd_swaptmesh();
00400         gsd_litvert_func(Octo[5], colr, Octo[5]);
00401         gsd_swaptmesh();
00402         gsd_litvert_func(Octo[1], colr, Octo[1]);
00403         gsd_litvert_func(Octo[3], colr, Octo[3]);
00404         gsd_litvert_func(Octo[2], colr, Octo[2]);
00405         gsd_swaptmesh();
00406         gsd_litvert_func(Octo[4], colr, Octo[4]);
00407         gsd_swaptmesh();
00408         gsd_litvert_func(Octo[5], colr, Octo[5]);
00409         gsd_swaptmesh();
00410         gsd_litvert_func(Octo[1], colr, Octo[1]);
00411         gsd_endtmesh();
00412     }
00413 #endif
00414 
00415     gsd_popmatrix();
00416     gsd_shademodel(preshade);
00417 
00418     return;
00419 }
00420 
00430 void gsd_cube(float *center, unsigned long colr, float siz)
00431 {
00432     int preshade;
00433 
00434     /* see gsd_diamond() "seems right, but isn't" */
00435     siz *= .5;
00436 
00437     gsd_pushmatrix();
00438     gsd_translate(center[X], center[Y], center[Z]);
00439     gsd_scale(siz, siz, siz);
00440     preshade = gsd_getshademodel();
00441     gsd_shademodel(0);          /* want flat shading */
00442 
00443 
00444     /* N wall: */
00445     gsd_bgnpolygon();
00446     gsd_litvert_func(CubeNormals[0], colr, CubeVertices[2]);
00447     gsd_litvert_func(CubeNormals[0], colr, CubeVertices[3]);
00448     gsd_litvert_func(CubeNormals[0], colr, CubeVertices[7]);
00449     gsd_litvert_func(CubeNormals[0], colr, CubeVertices[6]);
00450     gsd_endpolygon();
00451 
00452     /* S wall: */
00453     gsd_bgnpolygon();
00454     gsd_litvert_func(CubeNormals[0], colr, CubeVertices[1]);
00455     gsd_litvert_func(CubeNormals[0], colr, CubeVertices[5]);
00456     gsd_litvert_func(CubeNormals[0], colr, CubeVertices[4]);
00457     gsd_litvert_func(CubeNormals[0], colr, CubeVertices[0]);
00458     gsd_endpolygon();
00459 
00460     /* E wall: */
00461     gsd_bgnpolygon();
00462     gsd_litvert_func(CubeNormals[1], colr, CubeVertices[2]);
00463     gsd_litvert_func(CubeNormals[1], colr, CubeVertices[6]);
00464     gsd_litvert_func(CubeNormals[1], colr, CubeVertices[5]);
00465     gsd_litvert_func(CubeNormals[1], colr, CubeVertices[1]);
00466     gsd_endpolygon();
00467 
00468     /* W wall: */
00469     gsd_bgnpolygon();
00470     gsd_litvert_func(CubeNormals[1], colr, CubeVertices[0]);
00471     gsd_litvert_func(CubeNormals[1], colr, CubeVertices[4]);
00472     gsd_litvert_func(CubeNormals[1], colr, CubeVertices[7]);
00473     gsd_litvert_func(CubeNormals[1], colr, CubeVertices[3]);
00474     gsd_endpolygon();
00475 
00476     /* lower wall: */
00477     gsd_bgnpolygon();
00478     gsd_litvert_func(CubeNormals[2], colr, CubeVertices[0]);
00479     gsd_litvert_func(CubeNormals[2], colr, CubeVertices[1]);
00480     gsd_litvert_func(CubeNormals[2], colr, CubeVertices[2]);
00481     gsd_litvert_func(CubeNormals[2], colr, CubeVertices[3]);
00482     gsd_endpolygon();
00483 
00484     /* top wall: */
00485     gsd_bgnpolygon();
00486     gsd_litvert_func(CubeNormals[2], colr, CubeVertices[4]);
00487     gsd_litvert_func(CubeNormals[2], colr, CubeVertices[5]);
00488     gsd_litvert_func(CubeNormals[2], colr, CubeVertices[6]);
00489     gsd_litvert_func(CubeNormals[2], colr, CubeVertices[7]);
00490     gsd_endpolygon();
00491 
00492     gsd_popmatrix();
00493     gsd_shademodel(preshade);
00494 
00495     return;
00496 }
00497 
00507 void gsd_draw_box(float *center, unsigned long colr, float siz)
00508 {
00509 
00510     /* see gsd_diamond() "seems right, but isn't" */
00511     siz *= .5;
00512 
00513     gsd_pushmatrix();
00514     gsd_translate(center[X], center[Y], center[Z]);
00515     gsd_scale(siz, siz, siz);
00516     gsd_color_func(colr);
00517 
00518     gsd_bgnline();              /* N wall */
00519     gsd_vert_func(CubeVertices[2]);
00520     gsd_vert_func(CubeVertices[3]);
00521     gsd_vert_func(CubeVertices[7]);
00522     gsd_vert_func(CubeVertices[6]);
00523     gsd_vert_func(CubeVertices[2]);
00524     gsd_endline();
00525 
00526     gsd_bgnline();              /* S wall */
00527     gsd_vert_func(CubeVertices[1]);
00528     gsd_vert_func(CubeVertices[5]);
00529     gsd_vert_func(CubeVertices[4]);
00530     gsd_vert_func(CubeVertices[0]);
00531     gsd_vert_func(CubeVertices[1]);
00532     gsd_endline();
00533 
00534     gsd_bgnline();
00535     gsd_vert_func(CubeVertices[1]);
00536     gsd_vert_func(CubeVertices[2]);
00537     gsd_endline();
00538 
00539     gsd_bgnline();
00540     gsd_vert_func(CubeVertices[3]);
00541     gsd_vert_func(CubeVertices[0]);
00542     gsd_endline();
00543 
00544     gsd_bgnline();
00545     gsd_vert_func(CubeVertices[5]);
00546     gsd_vert_func(CubeVertices[6]);
00547     gsd_endline();
00548 
00549     gsd_bgnline();
00550     gsd_vert_func(CubeVertices[4]);
00551     gsd_vert_func(CubeVertices[7]);
00552     gsd_endline();
00553 
00554     gsd_popmatrix();
00555 
00556     return;
00557 }
00558 
00566 void gsd_drawsphere(float *center, unsigned long colr, float siz)
00567 {
00568     siz *= .5;                  /* siz is diameter, gsd_sphere uses radius */
00569     gsd_color_func(colr);
00570     gsd_sphere(center, siz);
00571 
00572     return;
00573 }
00574 
00578 void gsd_diamond_lines(void)
00579 {
00580     gsd_bgnline();
00581     gsd_vert_func(Octo[0]);
00582     gsd_vert_func(Octo[3]);
00583     gsd_endline();
00584 
00585     gsd_bgnline();
00586     gsd_vert_func(Octo[1]);
00587     gsd_vert_func(Octo[4]);
00588     gsd_endline();
00589 
00590     gsd_bgnline();
00591     gsd_vert_func(Octo[2]);
00592     gsd_vert_func(Octo[5]);
00593     gsd_endline();
00594 
00595     return;
00596 }
00597 
00605 void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
00606 {
00607     float angle;
00608 
00609     angle = 45.;                /* degrees */
00610 
00611     gsd_pushmatrix();
00612     gsd_translate(center[X], center[Y], center[Z]);
00613     gsd_scale(siz, siz, siz);
00614     gsd_color_func(colr);
00615 
00616     gsd_diamond_lines();
00617 
00618     gsd_pushmatrix();
00619     gsd_rot(angle, 'x');
00620     gsd_diamond_lines();
00621     gsd_popmatrix();
00622 
00623     gsd_pushmatrix();
00624     gsd_rot(-angle, 'x');
00625     gsd_diamond_lines();
00626     gsd_popmatrix();
00627 
00628     gsd_pushmatrix();
00629     gsd_rot(angle, 'y');
00630     gsd_diamond_lines();
00631     gsd_popmatrix();
00632 
00633     gsd_pushmatrix();
00634     gsd_rot(-angle, 'y');
00635     gsd_diamond_lines();
00636     gsd_popmatrix();
00637 
00638     gsd_pushmatrix();
00639     gsd_rot(angle, 'z');
00640     gsd_diamond_lines();
00641     gsd_popmatrix();
00642 
00643     gsd_pushmatrix();
00644     gsd_rot(-angle, 'z');
00645     gsd_diamond_lines();
00646     gsd_popmatrix();
00647 
00648     gsd_popmatrix();
00649 
00650     return;
00651 }
00652 
00660 void gsd_draw_gyro(float *center, unsigned long colr, float siz)
00661 {
00662     int i;
00663 
00664     gsd_pushmatrix();
00665     gsd_translate(center[X], center[Y], center[Z]);
00666     gsd_scale(siz, siz, siz);
00667     gsd_color_func(colr);
00668 
00669     /* vert axis */
00670     gsd_bgnline();
00671     gsd_vert_func(Octo[2]);
00672     gsd_vert_func(Octo[5]);
00673     gsd_endline();
00674 
00675     /* spokes */
00676     gsd_pushmatrix();
00677 
00678     for (i = 0; i < 6; i++) {
00679         gsd_rot(30., 'z');
00680         gsd_bgnline();
00681         gsd_vert_func(Octo[0]);
00682         gsd_vert_func(Octo[3]);
00683         gsd_endline();
00684     }
00685 
00686     gsd_popmatrix();
00687 
00688     gsd_color_func(colr);
00689 
00690     gsd_circ(0., 0., 1.);
00691 
00692     gsd_pushmatrix();
00693     gsd_rot(90., 'x');
00694     gsd_circ(0., 0., 1.);
00695     gsd_popmatrix();
00696 
00697     gsd_pushmatrix();
00698     gsd_rot(90., 'y');
00699     gsd_circ(0., 0., 1.);
00700     gsd_popmatrix();
00701 
00702     gsd_popmatrix();
00703 
00704     return;
00705 }
00706 
00712 void gsd_3dcursor(float *pt)
00713 {
00714     float big, vert[3];
00715 
00716     big = 10000.;
00717 
00718     gsd_bgnline();
00719     vert[X] = pt[X];
00720     vert[Y] = pt[Y];
00721     vert[Z] = big;
00722     gsd_vert_func(vert);
00723     vert[Z] = -big;
00724     gsd_vert_func(vert);
00725     gsd_endline();
00726 
00727     gsd_bgnline();
00728     vert[X] = pt[X];
00729     vert[Z] = pt[Z];
00730     vert[Y] = big;
00731     gsd_vert_func(vert);
00732     vert[Y] = -big;
00733     gsd_vert_func(vert);
00734     gsd_endline();
00735 
00736     gsd_bgnline();
00737     vert[Y] = pt[Y];
00738     vert[Z] = pt[Z];
00739     vert[X] = big;
00740     gsd_vert_func(vert);
00741     vert[X] = -big;
00742     gsd_vert_func(vert);
00743     gsd_endline();
00744 
00745     return;
00746 }
00747 
00756 void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
00757 {
00758     float dx, dy, dz;
00759     float costheta, theta, adjacent;
00760 
00761     dx = dir[X];
00762     dy = dir[Y];
00763     dz = dir[Z];
00764 
00765     /* project vector <dx,dy,dz> onto plane of constant z containing
00766      * final value should be 0.0 to 3600.0 */
00767     if (dx == 0 && dy == 0) {
00768         *aspect = 0.;
00769     }
00770     else {
00771         if (dx == 0) {
00772             theta = 90.0;
00773         }
00774         else {
00775             costheta = dx / sqrt(dx * dx + dy * dy);
00776             theta = acos(costheta);
00777         }
00778 
00779         if (dy < 0) {
00780             theta = (2 * Pi) - theta;
00781         }
00782 
00783         *aspect = theta;
00784     }
00785 
00786     /* project vector <dx,dy,dz> onto plane of constant y containing
00787      * final value should be -900.0 (looking up) to 900.0 (looking down) */
00788     if (dz == 0) {
00789         theta = 0.0;
00790     }
00791     else if (dx == 0 && dy == 0) {
00792         theta = Pi / 2.;
00793     }
00794     else {
00795         adjacent = sqrt(dx * dx + dy * dy);
00796         costheta = adjacent / sqrt(adjacent * adjacent + dz * dz);
00797         theta = acos(costheta);
00798     }
00799 
00800     if (dz > 0) {
00801         theta = -theta;
00802     }
00803 
00804     *slope = theta;
00805 
00806     if (degrees) {
00807         *aspect = *aspect * (180. / Pi);
00808         *slope = *slope * (180. / Pi);
00809     }
00810 
00811     return;
00812 }
00813 
00814 
00826 int gsd_north_arrow(float *pos2, float len, GLuint fontbase,
00827                     unsigned long arw_clr, unsigned long text_clr)
00828 {
00829     const char *txt;
00830     float v[4][3];
00831     float base[3][3];
00832     float Ntop[] = { 0.0, 0.0, 1.0 };
00833 
00834     base[0][Z] = base[1][Z] = base[2][Z] = pos2[Z];
00835     v[0][Z] = v[1][Z] = v[2][Z] = v[3][Z] = pos2[Z];
00836 
00837     base[0][X] = pos2[X] - len / 16.;
00838     base[1][X] = pos2[X] + len / 16.;
00839     base[0][Y] = base[1][Y] = pos2[Y] - len / 2.;
00840     base[2][X] = pos2[X];
00841     base[2][Y] = pos2[Y] + .45 * len;
00842 
00843     v[0][X] = v[2][X] = pos2[X];
00844     v[1][X] = pos2[X] + len / 8.;
00845     v[3][X] = pos2[X] - len / 8.;
00846     v[0][Y] = pos2[Y] + .2 * len;
00847     v[1][Y] = v[3][Y] = pos2[Y] + .1 * len;
00848     v[2][Y] = pos2[Y] + .5 * len;
00849 
00850     /* make sure we are drawing in front buffer */
00851     GS_set_draw(GSD_FRONT);
00852 
00853     gsd_pushmatrix();
00854     gsd_do_scale(1);
00855 
00856     glNormal3fv(Ntop);
00857     gsd_color_func(arw_clr);
00858 
00859     gsd_bgnpolygon();
00860     glVertex3fv(base[0]);
00861     glVertex3fv(base[1]);
00862     glVertex3fv(base[2]);
00863     gsd_endpolygon();
00864 
00865     gsd_bgnpolygon();
00866     glVertex3fv(v[0]);
00867     glVertex3fv(v[1]);
00868     glVertex3fv(v[2]);
00869     glVertex3fv(v[0]);
00870     gsd_endpolygon();
00871 
00872     gsd_bgnpolygon();
00873     glVertex3fv(v[0]);
00874     glVertex3fv(v[2]);
00875     glVertex3fv(v[3]);
00876     glVertex3fv(v[0]);
00877     gsd_endpolygon();
00878 
00879     /* draw N for North */
00880     /* Need to pick a nice generic font */
00881     /* TODO -- project text position off arrow
00882      * bottom along azimuth
00883      */
00884 
00885     gsd_color_func(text_clr);
00886     txt = "North";
00887     /* adjust position of N text */
00888     base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
00889     base[0][Y] -= gsd_get_txtheight(18) - 20.;
00890 
00891     glRasterPos3fv(base[0]);
00892     glListBase(fontbase);
00893     glCallLists(strlen(txt), GL_UNSIGNED_BYTE, (const GLvoid *)txt);
00894     GS_done_draw();
00895 
00896     gsd_popmatrix();
00897     gsd_flush();
00898 
00899     return (1);
00900 
00901 }
00902 
00922 int gsd_arrow(float *center, unsigned long colr, float siz, float *dir,
00923               float sz, geosurf * onsurf)
00924 {
00925     float slope, aspect;
00926     float tmp[3];
00927     static int first = 1;
00928 
00929     if (first) {
00930         init_stuff();
00931         first = 0;
00932     }
00933 
00934     dir[Z] /= sz;
00935 
00936     GS_v3norm(dir);
00937 
00938     if (NULL != onsurf) {
00939         float base[3], tip[3], len;
00940 
00941         base[X] = center[X];
00942         base[Y] = center[Y];
00943 
00944         /* project dir to surface, after zexag */
00945         len = GS_P2distance(ORIGIN, dir);       /* in case dir isn't normalized */
00946         tip[X] = center[X] + dir[X] * len * siz;
00947         tip[Y] = center[Y] + dir[Y] * len * siz;
00948 
00949         return gsd_arrow_onsurf(base, tip, colr, 2, onsurf);
00950     }
00951 
00952     dir_to_slope_aspect(dir, &slope, &aspect, 1);
00953 
00954     gsd_pushmatrix();
00955     gsd_translate(center[X], center[Y], center[Z]);
00956     gsd_scale(1.0, 1.0, 1.0 / sz);
00957     gsd_rot(aspect + 90, 'z');
00958     gsd_rot(slope + 90., 'x');
00959     gsd_scale(siz, siz, siz);
00960     gsd_color_func(colr);
00961 
00962     tmp[X] = 0.2;
00963     tmp[Y] = 0.0;
00964     tmp[Z] = 0.65;
00965 
00966     gsd_bgnline();
00967     gsd_vert_func(ORIGIN);
00968     gsd_vert_func(UP_NORM);
00969     gsd_endline();
00970 
00971     gsd_bgnline();
00972     gsd_vert_func(tmp);
00973     gsd_vert_func(UP_NORM);
00974     tmp[X] = -0.2;
00975     gsd_vert_func(tmp);
00976     gsd_endline();
00977 
00978     gsd_popmatrix();
00979 
00980     return (1);
00981 }
00982 
00994 int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid,
00995                      geosurf * gs)
00996 {
00997     static int first = 1;
00998 
00999     if (first) {
01000         init_stuff();
01001         first = 0;
01002     }
01003 
01004     gsd_linewidth(wid);
01005     gsd_color_func(colr);
01006 
01007     G_debug(3, "gsd_arrow_onsurf");
01008     G_debug(3, "  %f %f -> %f %f", base[X], base[Y], tip[X], tip[Y]);
01009 
01010     gsd_line_onsurf(gs, base, tip);
01011 
01012 #ifdef DO_SPHERE_BASE
01013     {
01014         GS_v3dir(tip, base, dir0);
01015         GS_v3mag(dir0, &len);
01016         gsd_disc(base[X], base[Y], len / 10.);
01017     }
01018 #endif
01019 
01020 #ifdef ARROW_READY
01021     {
01022         base[Z] = tip[Z] = 0.0;
01023         GS_v3dir(tip, base, dir0);
01024 
01025         G_debug(3, "  dir0: %f %f %f", dir0[X], dir0[Y], dir0[Z]);
01026 
01027         /* rotate this direction 90 degrees */
01028         GS_v3cross(dir0, UP_NORM, dir2);
01029         GS_v3mag(dir0, &len);
01030         GS_v3eq(dir1, dir0);
01031 
01032         G_debug(3, "  len: %f", len);
01033         G_debug(3, "  a-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
01034         G_debug(3, "  a-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
01035 
01036         dim1 = len * .7;
01037         dim2 = len * .2;
01038         GS_v3mult(dir1, dim1);
01039         GS_v3mult(dir2, dim2);
01040 
01041         G_debug(3, "  b-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
01042         G_debug(3, "  b-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
01043 
01044         GS_v3eq(tmp, base);
01045         GS_v3add(tmp, dir1);
01046         GS_v3add(tmp, dir2);
01047 
01048         G_debug(3, "  %f %f -> ", tmp[X], tmp[Y]);
01049 
01050         gsd_line_onsurf(gs, tmp, tip);
01051 
01052         GS_v3cross(dir0, DOWN_NORM, dir2);
01053         GS_v3mult(dir2, dim2);
01054         GS_v3eq(tmp, base);
01055 
01056         G_debug(3, "  dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
01057         G_debug(3, "  dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
01058 
01059         GS_v3add(tmp, dir1);
01060         GS_v3add(tmp, dir2);
01061 
01062         G_debug(3, "  %f %f", tmp[X], tmp[Y]);
01063 
01064         gsd_line_onsurf(gs, tip, tmp);
01065     }
01066 #endif
01067 
01068     return (0);
01069 }
01070 
01081 void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2,
01082                  float *dir, float sz)
01083 {
01084     float slope, aspect;
01085     int preshade;
01086     static int first = 1;
01087     static int list;
01088     static int debugint = 1;
01089 
01090     dir[Z] /= sz;
01091 
01092     GS_v3norm(dir);
01093     dir_to_slope_aspect(dir, &slope, &aspect, 1);
01094 
01095     if (debugint > 100) {
01096         G_debug(3, "gsd_3darrow()");
01097         G_debug(3, "  pt: %f,%f,%f dir: %f,%f,%f slope: %f aspect: %f",
01098                 center[X], center[Y], center[Z], dir[X], dir[Y], dir[Z],
01099                 slope, aspect);
01100         debugint = 1;
01101     }
01102     debugint++;
01103 
01104     preshade = gsd_getshademodel();
01105 
01106     /* 
01107        gsd_shademodel(0);  
01108        want flat shading? */
01109     gsd_pushmatrix();
01110     gsd_translate(center[X], center[Y], center[Z]);
01111     gsd_scale(1.0, 1.0, 1.0 / sz);
01112     gsd_rot(aspect + 90, 'z');
01113     gsd_rot(slope + 90., 'x');
01114     gsd_scale(siz2, siz2, siz1);
01115     gsd_color_func(colr);
01116 
01117     if (first) {
01118         /* combine these into an object */
01119         first = 0;
01120         list = gsd_makelist();
01121         gsd_bgnlist(list, 1);
01122         gsd_backface(1);
01123 
01124         gsd_pushmatrix();
01125         gsd_scale(.10, .10, .75);       /* narrow cyl */
01126         primitive_cylinder(colr, 0);
01127         gsd_popmatrix();
01128 
01129         gsd_pushmatrix();
01130         gsd_translate(0.0, 0.0, .60);
01131         gsd_scale(0.3, 0.3, 0.4);       /* cone */
01132         primitive_cone(colr);
01133         gsd_popmatrix();
01134 
01135         gsd_backface(0);
01136         gsd_endlist();
01137     }
01138     else {
01139         gsd_calllist(list);
01140     }
01141 
01142     gsd_popmatrix();
01143     gsd_shademodel(preshade);
01144 
01145     return;
01146 }
01147 
01160 int gsd_scalebar(float *pos2, float len, GLuint fontbase,
01161                  unsigned long bar_clr, unsigned long text_clr)
01162 {
01163     char txt[100];
01164     float base[4][3];
01165     float Ntop[] = { 0.0, 0.0, 1.0 };
01166 
01167 
01168     base[0][Z] = base[1][Z] = base[2][Z] = base[3][Z] = pos2[Z];
01169 
01170     /* simple 1:8 rectangle *//* bump to X/20. for a 1:10 narrower bar? */
01171     base[0][X] = base[1][X] = pos2[X] - len / 2.;
01172     base[2][X] = base[3][X] = pos2[X] + len / 2.;
01173 
01174     base[0][Y] = base[3][Y] = pos2[Y] - len / 16.;
01175     base[1][Y] = base[2][Y] = pos2[Y] + len / 16.;
01176 
01177     /* make sure we are drawing in front buffer */
01178     GS_set_draw(GSD_FRONT);
01179 
01180     gsd_pushmatrix();
01181     gsd_do_scale(1);            /* get map scale factor */
01182 
01183     glNormal3fv(Ntop);
01184 
01185     gsd_color_func(bar_clr);
01186 
01187     gsd_bgnpolygon();
01188     glVertex3fv(base[0]);
01189     glVertex3fv(base[1]);
01190     glVertex3fv(base[2]);
01191     glVertex3fv(base[3]);
01192     glVertex3fv(base[0]);
01193     gsd_endpolygon();
01194 
01195     /* draw units */
01196     /* Need to pick a nice generic font */
01197     /* TODO -- project text position off bar bottom along azimuth */
01198 
01199     gsd_color_func(text_clr);
01200 
01201     /* format text in a nice way */
01202     if (strcmp("meters", G_database_unit_name(TRUE)) == 0) {
01203         if (len > 2500)
01204             sprintf(txt, "%g km", len / 1000);
01205         else
01206             sprintf(txt, "%g meters", len);
01207     }
01208     else if (strcmp("feet", G_database_unit_name(TRUE)) == 0) {
01209         if (len > 5280)
01210             sprintf(txt, "%g miles", len / 5280);
01211         else if (len == 5280)
01212             sprintf(txt, "1 mile");
01213         else
01214             sprintf(txt, "%g feet", len);
01215     }
01216     else {
01217         sprintf(txt, "%g %s", len, G_database_unit_name(TRUE));
01218     }
01219 
01220     /* adjust position of text (In map units?!) */
01221     base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
01222     base[0][Y] -= gsd_get_txtheight(18) - 20.;
01223 
01224 
01225     glRasterPos3fv(base[0]);
01226     glListBase(fontbase);
01227     glCallLists(strlen(txt), GL_BYTE, (GLubyte *) txt);
01228     GS_done_draw();
01229 
01230     gsd_popmatrix();
01231     gsd_flush();
01232 
01233     return (1);
01234 }
01235 
01243 void primitive_cone(unsigned long col)
01244 {
01245     float tip[3];
01246     static int first = 1;
01247 
01248     if (first) {
01249         init_stuff();
01250         first = 0;
01251     }
01252 
01253     tip[X] = tip[Y] = 0.0;
01254     tip[Z] = 1.0;
01255 
01256     gsd_bgntfan();
01257     gsd_litvert_func2(UP_NORM, col, tip);
01258     gsd_litvert_func2(ogverts[0], col, ogverts[0]);
01259     gsd_litvert_func2(ogverts[1], col, ogverts[1]);
01260     gsd_litvert_func2(ogverts[2], col, ogverts[2]);
01261     gsd_litvert_func2(ogverts[3], col, ogverts[3]);
01262     gsd_litvert_func2(ogverts[4], col, ogverts[4]);
01263     gsd_litvert_func2(ogverts[5], col, ogverts[5]);
01264     gsd_litvert_func2(ogverts[6], col, ogverts[6]);
01265     gsd_litvert_func2(ogverts[7], col, ogverts[7]);
01266     gsd_litvert_func2(ogverts[0], col, ogverts[0]);
01267     gsd_endtfan();
01268 
01269     return;
01270 }
01271 
01280 void primitive_cylinder(unsigned long col, int caps)
01281 {
01282     static int first = 1;
01283 
01284     if (first) {
01285         init_stuff();
01286         first = 0;
01287     }
01288 
01289     gsd_bgnqstrip();
01290     gsd_litvert_func2(ogverts[0], col, ogvertsplus[0]);
01291     gsd_litvert_func2(ogverts[0], col, ogverts[0]);
01292     gsd_litvert_func2(ogverts[1], col, ogvertsplus[1]);
01293     gsd_litvert_func2(ogverts[1], col, ogverts[1]);
01294     gsd_litvert_func2(ogverts[2], col, ogvertsplus[2]);
01295     gsd_litvert_func2(ogverts[2], col, ogverts[2]);
01296     gsd_litvert_func2(ogverts[3], col, ogvertsplus[3]);
01297     gsd_litvert_func2(ogverts[3], col, ogverts[3]);
01298     gsd_litvert_func2(ogverts[4], col, ogvertsplus[4]);
01299     gsd_litvert_func2(ogverts[4], col, ogverts[4]);
01300     gsd_litvert_func2(ogverts[5], col, ogvertsplus[5]);
01301     gsd_litvert_func2(ogverts[5], col, ogverts[5]);
01302     gsd_litvert_func2(ogverts[6], col, ogvertsplus[6]);
01303     gsd_litvert_func2(ogverts[6], col, ogverts[6]);
01304     gsd_litvert_func2(ogverts[7], col, ogvertsplus[7]);
01305     gsd_litvert_func2(ogverts[7], col, ogverts[7]);
01306     gsd_litvert_func2(ogverts[0], col, ogvertsplus[0]);
01307     gsd_litvert_func2(ogverts[0], col, ogverts[0]);
01308     gsd_endqstrip();
01309 
01310     if (caps) {
01311         /* draw top */
01312         gsd_bgntfan();
01313         gsd_litvert_func2(UP_NORM, col, UP_NORM);
01314         gsd_litvert_func2(UP_NORM, col, ogvertsplus[0]);
01315         gsd_litvert_func2(UP_NORM, col, ogvertsplus[1]);
01316         gsd_litvert_func2(UP_NORM, col, ogvertsplus[2]);
01317         gsd_litvert_func2(UP_NORM, col, ogvertsplus[3]);
01318         gsd_litvert_func2(UP_NORM, col, ogvertsplus[4]);
01319         gsd_litvert_func2(UP_NORM, col, ogvertsplus[5]);
01320         gsd_litvert_func2(UP_NORM, col, ogvertsplus[6]);
01321         gsd_litvert_func2(UP_NORM, col, ogvertsplus[7]);
01322         gsd_litvert_func2(UP_NORM, col, ogvertsplus[0]);
01323         gsd_endtfan();
01324 
01325         /* draw bottom */
01326         gsd_bgntfan();
01327         gsd_litvert_func2(DOWN_NORM, col, ORIGIN);
01328         gsd_litvert_func2(DOWN_NORM, col, ogverts[0]);
01329         gsd_litvert_func2(DOWN_NORM, col, ogverts[1]);
01330         gsd_litvert_func2(DOWN_NORM, col, ogverts[2]);
01331         gsd_litvert_func2(DOWN_NORM, col, ogverts[3]);
01332         gsd_litvert_func2(DOWN_NORM, col, ogverts[4]);
01333         gsd_litvert_func2(DOWN_NORM, col, ogverts[5]);
01334         gsd_litvert_func2(DOWN_NORM, col, ogverts[6]);
01335         gsd_litvert_func2(DOWN_NORM, col, ogverts[7]);
01336         gsd_litvert_func2(DOWN_NORM, col, ogverts[0]);
01337         gsd_endtfan();
01338     }
01339 
01340     return;
01341 }
01342 
01343 /*** ACS_MODIFY_BEGIN - sites_attribute management ********************************/
01344 /*
01345    Draws boxes that are used for histograms by gpd_obj function in gpd.c
01346    for site_attribute management
01347  */
01348 
01352 float Box[8][3] =
01353     { {1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0}, {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0},
01354 {1.0, -1.0, -1.0}, {-1.0, -1.0, -1.0}, {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}
01355 };
01356 
01357 float BoxN[6][3] =
01358     { {0, 0, -ONORM}, {0, 0, ONORM}, {0, ONORM, 0}, {0, -ONORM, 0}, {ONORM, 0,
01359                                                                      0},
01360 {-ONORM, 0, 0}
01361 };
01362 
01372 void gsd_box(float *center, int colr, float *siz)
01373 {
01374     int preshade;
01375 
01376     gsd_pushmatrix();
01377     gsd_translate(center[X], center[Y], center[Z] + siz[2]);
01378     gsd_scale(siz[0], siz[1], siz[2]);
01379     preshade = gsd_getshademodel();
01380     gsd_shademodel(0);          /* want flat shading */
01381 
01382     /* Top */
01383     gsd_bgnpolygon();
01384     gsd_litvert_func(BoxN[2], colr, Box[0]);
01385     gsd_litvert_func(BoxN[2], colr, Box[1]);
01386     gsd_litvert_func(BoxN[2], colr, Box[2]);
01387     gsd_litvert_func(BoxN[2], colr, Box[3]);
01388     gsd_endpolygon();
01389 
01390     /* Bottom */
01391     gsd_bgnpolygon();
01392     gsd_litvert_func(BoxN[3], colr, Box[7]);
01393     gsd_litvert_func(BoxN[3], colr, Box[6]);
01394     gsd_litvert_func(BoxN[3], colr, Box[5]);
01395     gsd_litvert_func(BoxN[3], colr, Box[4]);
01396     gsd_endpolygon();
01397 
01398     /* Right */
01399     gsd_bgnpolygon();
01400     gsd_litvert_func(BoxN[4], colr, Box[0]);
01401     gsd_litvert_func(BoxN[4], colr, Box[3]);
01402     gsd_litvert_func(BoxN[4], colr, Box[7]);
01403     gsd_litvert_func(BoxN[4], colr, Box[4]);
01404     gsd_endpolygon();
01405 
01406     /* Left */
01407     gsd_bgnpolygon();
01408     gsd_litvert_func(BoxN[5], colr, Box[1]);
01409     gsd_litvert_func(BoxN[5], colr, Box[5]);
01410     gsd_litvert_func(BoxN[5], colr, Box[6]);
01411     gsd_litvert_func(BoxN[5], colr, Box[2]);
01412     gsd_endpolygon();
01413 
01414     /* Front */
01415     gsd_bgnpolygon();
01416     gsd_litvert_func(BoxN[0], colr, Box[0]);
01417     gsd_litvert_func(BoxN[0], colr, Box[4]);
01418     gsd_litvert_func(BoxN[0], colr, Box[5]);
01419     gsd_litvert_func(BoxN[0], colr, Box[1]);
01420     gsd_endpolygon();
01421 
01422     /* Back */
01423     gsd_bgnpolygon();
01424     gsd_litvert_func(BoxN[1], colr, Box[3]);
01425     gsd_litvert_func(BoxN[1], colr, Box[2]);
01426     gsd_litvert_func(BoxN[1], colr, Box[6]);
01427     gsd_litvert_func(BoxN[1], colr, Box[7]);
01428     gsd_endpolygon();
01429 
01430     gsd_popmatrix();
01431     gsd_shademodel(preshade);
01432     return;
01433 }
01434 
01435 /*** ACS_MODIFY_END - sites_attribute management ********************************/
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines