GRASS Programmer's Manual
6.4.2(2012)
|
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 ********************************/