| 9877 | } |
| 9878 | |
| 9879 | GMT_LOCAL void gmtplot_geo_spider (struct GMT_CTRL *GMT, double xlon, double xlat, double radius_i, double radius_o, double dr, double az_start, double az_stop, double da, unsigned int wmode) { |
| 9880 | /* gmtplot_geo_spider takes the location, radius_i (in unit), radius_o, dr, and start/stop azimuths of an geo-wedge and da |
| 9881 | and draws an approximate circular spider-web using N-sided polygon. |
| 9882 | mode & 1: Just draw arc(s) |
| 9883 | mode & 2: Just draw radii(s) |
| 9884 | */ |
| 9885 | |
| 9886 | int n_arc, k, ko, n_seg; |
| 9887 | uint64_t n_new; |
| 9888 | bool windshield = (radius_i > 0.0); /* Windshield web */ |
| 9889 | enum GMT_enum_wedgetype mode = wmode; |
| 9890 | double qlon, qlat, az, rot_start, E[3], P_o[3], P_i[3], Q[3], R[3][3]; |
| 9891 | struct GMT_DATASEGMENT *S = NULL; |
| 9892 | |
| 9893 | radius_i = gmtlib_conv_distance (GMT, radius_i, 'k', 'd'); /* Convert inner radius from km to degrees */ |
| 9894 | radius_o = gmtlib_conv_distance (GMT, radius_o, 'k', 'd'); /* Convert outer radius from km to degrees */ |
| 9895 | dr = gmtlib_conv_distance (GMT, dr, 'k', 'd'); /* Convert radial increments from km to degrees */ |
| 9896 | |
| 9897 | gmt_geo_to_cart (GMT, xlat, xlon, E, true); /* Euler rotation pole at point location */ |
| 9898 | |
| 9899 | /* Get a point P_o that is radius_o degrees away along the meridian through our point X */ |
| 9900 | gmtplot_get_far_point (GMT, xlon, xlat, radius_o, P_o); |
| 9901 | if (windshield) /* Get a point P_i that is radius_i degrees away along the meridian through our point X */ |
| 9902 | gmtplot_get_far_point (GMT, xlon, xlat, radius_i, P_i); |
| 9903 | |
| 9904 | PSL_comment (GMT->PSL, "Placing Spider Web\n"); |
| 9905 | PSL_command (GMT->PSL, "V PSL_spiderpen\n"); /* Place spider under gsave/grestore and change to spiderpen */ |
| 9906 | if (mode == GMT_WEDGE_RADII || mode == GMT_WEDGE_SPIDER) { /* Need to draw radial start and end points */ |
| 9907 | double *azim = NULL; |
| 9908 | if (da > 0.0) /* Must draw several radial lines */ |
| 9909 | n_seg = gmtlib_linear_array (GMT, az_start, az_stop, da, 0.0, &azim); |
| 9910 | else { /* Two radial lines only */ |
| 9911 | azim = gmt_M_memory (GMT, NULL, n_seg = 2, double); |
| 9912 | azim[0] = az_start; azim[1] = az_stop; |
| 9913 | } |
| 9914 | PSL_comment (GMT->PSL, "Drawing Spider Radials\n"); |
| 9915 | for (k = 0; k < n_seg; k++) { /* For each radial line */ |
| 9916 | S = GMT_Alloc_Segment (GMT->parent, GMT_NO_STRINGS, 2, 2, NULL, NULL); /* Segment with two rows */ |
| 9917 | gmt_make_rot_matrix2 (GMT, E, -azim[k], R); /* Since we have a right-handed rotation but gave azimuths */ |
| 9918 | if (windshield) { /* Start at inner arc point */ |
| 9919 | gmt_matrix_vect_mult (GMT, 3U, R, P_i, Q); |
| 9920 | gmt_cart_to_geo (GMT, &S->data[GMT_Y][0], &S->data[GMT_X][0], Q, true); /* Rotated inner point */ |
| 9921 | } |
| 9922 | else { /* Start at origin */ |
| 9923 | S->data[GMT_X][0] = xlon; S->data[GMT_Y][0] = xlat; |
| 9924 | } |
| 9925 | gmt_matrix_vect_mult (GMT, 3U, R, P_o, Q); |
| 9926 | gmt_cart_to_geo (GMT, &S->data[GMT_Y][1], &S->data[GMT_X][1], Q, true); /* Rotated outer point */ |
| 9927 | if ((n_new = gmt_fix_up_path (GMT, &S->data[GMT_X], &S->data[GMT_Y], S->n_rows, 0.0, 0)) == 0) { |
| 9928 | gmt_free_segment (GMT, &S); |
| 9929 | continue; |
| 9930 | } |
| 9931 | S->n_rows = n_new; |
| 9932 | if ((GMT->current.plot.n = gmt_geo_to_xy_line (GMT, S->data[GMT_X], S->data[GMT_Y], S->n_rows)) == 0) continue; |
| 9933 | gmt_plot_line (GMT, GMT->current.plot.x, GMT->current.plot.y, GMT->current.plot.pen, GMT->current.plot.n, PSL_LINEAR); |
| 9934 | gmt_free_segment (GMT, &S); |
| 9935 | } |
| 9936 | gmt_M_free (GMT, azim); |
no test coverage detected