MCPcopy Create free account
hub / github.com/GenericMappingTools/gmt / gmtplot_circle_pen_poly

Function gmtplot_circle_pen_poly

src/gmt_plot.c:4883–4927  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4881}
4882
4883GMT_LOCAL void gmtplot_circle_pen_poly (struct GMT_CTRL *GMT, double *A, double *B, bool longway, double rot, struct GMT_PEN *pen, struct GMT_SYMBOL *S, struct GMT_CIRCLE *C, double scale) {
4884 /* Given vectors A and B, return a small circle polygon path sampled every step that approximates a pen of given width
4885 * drawn on the map. Use small circle pole and its opening rot */
4886 uint64_t k, n, n2;
4887 double Ai[3], Ao[3], Px[3], X[3], R[3][3], R0[3][3], w, step;
4888 struct GMT_DATASEGMENT *L = NULL;
4889 gmt_M_unused(B);
4890
4891 gmt_cross3v (GMT, A, C->P, Px); /* Px is Pole to plane through A and P */
4892 gmt_normalize3v (GMT, Px); /* Rotation pole unit vector */
4893 /* Rotate A back/fore by rotation angle of +/- pen halfwidth about Px */
4894 w = 0.5 * scale * pen->width * GMT->session.u2u[GMT_PT][GMT_INCH] * S->v.scale; /* Half-width of pen in degrees */
4895 gmt_make_rot_matrix2 (GMT, Px, +w, R); /* Rotation of rot_v degrees about pole P */
4896 gmt_matrix_vect_mult (GMT, 3U, R, A, Ai); /* Get Ai = R * A */
4897 gmt_make_rot_matrix2 (GMT, Px, -w, R); /* Rotation of rot_v degrees about pole P */
4898 gmt_matrix_vect_mult (GMT, 3U, R, A, Ao); /* Get Ao = R * A */
4899 if (longway) rot = 360.0 - rot;
4900
4901 step = GMT->current.map.path_step; /* Use default map-step if given as 0 */
4902 n = lrint (ceil (fabs (rot) / step)) + 1; /* Number of segments needed for smooth curve from A to B inclusive */
4903 step = D2R * rot / (n - 1); /* Adjust step for exact fit, convert to radians */
4904 L = GMT_Alloc_Segment (GMT->parent, GMT_NO_STRINGS, 2*n+1, 2, NULL, NULL); /* Allocate polygon to draw filled path */
4905 n2 = 2*n-1;
4906 gmtlib_init_rot_matrix (R0, C->P); /* Get partial rotation matrix since no actual angle is applied yet */
4907 for (k = 0; k < n; k++) { /* March along the arc */
4908 w = k * step; /* Opening angle from A to this point X */
4909 gmt_M_memcpy (R, R0, 9U, double); /* Get a copy of the "0-angle" rotation matrix */
4910 gmtlib_load_rot_matrix (w, R, C->P); /* Build the actual rotation matrix for this angle */
4911 gmt_matrix_vect_mult (GMT, 3U, R, Ai, X); /* Rotate point Ai towards B and get X */
4912 gmt_cart_to_geo (GMT, &L->data[GMT_Y][k], &L->data[GMT_X][k], X, true); /* Get lon/lat of this point along arc */
4913 gmt_matrix_vect_mult (GMT, 3U, R, Ao, X); /* Rotate point Ai towards B and get X */
4914 gmt_cart_to_geo (GMT, &L->data[GMT_Y][n2-k], &L->data[GMT_X][n2-k], X, true); /* Get lon/lat of this point along arc */
4915 }
4916 L->data[GMT_X][2*n] = L->data[GMT_X][0]; /* Explicitly close the polygon */
4917 L->data[GMT_Y][2*n] = L->data[GMT_Y][0];
4918
4919 /* Plot pen as a closed filled polygon without outline */
4920 PSL_command (GMT->PSL, "V\n");
4921 gmt_setpen (GMT, pen); /* Set pen width just so later setpen's will work */
4922 PSL_setfill (GMT->PSL, pen->rgb, 0); /* Fill, no outline */
4923 gmt_geo_polygons (GMT, L); /* "Draw" the line */
4924 PSL_command (GMT->PSL, "U\n");
4925
4926 gmt_free_segment (GMT, &L);
4927}
4928
4929GMT_LOCAL void gmtplot_gcircle_sub (struct GMT_CTRL *GMT, double lon0, double lat0, double azimuth, double length, struct GMT_SYMBOL *S, struct GMT_CIRCLE *C) {
4930 /* We must determine points A and B, whose great-circle connector is the arc we seek to draw */

Callers 2

Calls 13

gmt_cross3vFunction · 0.85
gmt_normalize3vFunction · 0.85
gmt_make_rot_matrix2Function · 0.85
GMT_Alloc_SegmentFunction · 0.85
gmtlib_init_rot_matrixFunction · 0.85
gmtlib_load_rot_matrixFunction · 0.85
gmt_cart_to_geoFunction · 0.85
PSL_commandFunction · 0.85
gmt_setpenFunction · 0.85
PSL_setfillFunction · 0.85
gmt_geo_polygonsFunction · 0.85
gmt_free_segmentFunction · 0.85

Tested by

no test coverage detected