| 5136 | } |
| 5137 | |
| 5138 | GMT_LOCAL unsigned int gmtplot_geo_vector_smallcircle (struct GMT_CTRL *GMT, double lon0, double lat0, double angle_1, double angle_2, struct GMT_PEN *ppen, struct GMT_SYMBOL *S) { |
| 5139 | /* Draws a small-circle vector around an oblique pole, with or without heads, etc. There are some complications to consider: |
| 5140 | * When there are no heads it is simple. If +n is active we may shrink the line thickness. |
| 5141 | * With heads there are these cases: |
| 5142 | * Head length is longer than 90% of the vector length. We then skip the head and return 1 |
| 5143 | * +n<norm> is in effect. We shrink vector pen and head length. Still, the shrunk head |
| 5144 | * may be longer than 90% of the vector length. We then shrink head (not pen) further and return 2 |
| 5145 | * Note: Angle_1|2 may be degrees or km, depending on modifier +q. |
| 5146 | */ |
| 5147 | |
| 5148 | uint64_t n1, n2, n, add; |
| 5149 | int heads, side[2], outline = 0; |
| 5150 | unsigned int warn = 0; |
| 5151 | size_t n_alloc; |
| 5152 | bool perspective, pure; |
| 5153 | double P[3], Pa[3], Ax[3], Bx[3], Ax2[3], Bx2[3], R[3][3], h_length_limit; |
| 5154 | double dr[2] = {0.0, 0.0}, az[2] = {0.0, 0.0}, oaz[2] = {0.0, 0.0}, scl[2]; |
| 5155 | double da = 0.0, dshift[2] = {0.0, 0.0}, s = 1.0, s1 = 1.0, s2 = 1.0, olon[2], olat[2], head_length, arc_width, n_az, arc; |
| 5156 | double rot[2] = {0.0, 0.0}, rot_v[2] = {0.0, 0.0}; |
| 5157 | double *xp = NULL, *yp = NULL, *xp2 = NULL, *yp2 = NULL; |
| 5158 | double *rgb = S->v.fill.rgb; |
| 5159 | struct GMT_CIRCLE C; |
| 5160 | |
| 5161 | #if 0 |
| 5162 | /* We must determine points A and B, whose great-circle connector is the arc we seek to draw */ |
| 5163 | justify = PSL_vec_justify (S->v.status); /* Return justification as 0-3 */ |
| 5164 | #endif |
| 5165 | |
| 5166 | gmtplot_scircle_sub (GMT, lon0, lat0, angle_1, angle_2, S, &C); |
| 5167 | perspective = gmt_M_is_perspective (GMT); |
| 5168 | |
| 5169 | /* Here we have the endpoints A and B of the great (or small) circle arc */ |
| 5170 | |
| 5171 | /* If shrink-option (+n) is active we may have to scale down head attributes and pen width */ |
| 5172 | /* If shrink-option (+n) is active we may have to scale down head attributes and pen width */ |
| 5173 | heads = PSL_vec_head (S->v.status); /* Return head selection as 0-3 */ |
| 5174 | pure = (S->v.v_norm == -1.0f); /* True if no shrinking has been specified */ |
| 5175 | h_length_limit = C.r0; /* Max length of arrow in degrees to ensure the stem is still showing */ |
| 5176 | if (heads == 3) h_length_limit *= 0.5; /* Split this length between the two heads */ |
| 5177 | if (heads && !pure) { /* Need to determine head length in degrees */ |
| 5178 | double max_length; |
| 5179 | az[0] = gmtplot_smallcircle_az (GMT, C.A, S); /* Compute the azimuth from A to B at A along small circle */ |
| 5180 | scl[0] = (perspective) ? S->v.scale : gmtplot_get_local_scale (GMT, C.lon[0], C.lat[0], 0.001 * C.r, az[0]); /* Get local deg/inch scale at A in az[0] direction */ |
| 5181 | dr[0] = scl[0] * S->size_x; /* This is arrow head length in degrees, approximately */ |
| 5182 | az[1] = -gmtplot_smallcircle_az (GMT, C.B, S); /* Compute the azimuth from B to A at B along small circle */ |
| 5183 | scl[1] = (perspective) ? S->v.scale : gmtplot_get_local_scale (GMT, C.lon[1], C.lat[1], 0.01 * C.r, az[1]); /* Get local deg/inch scale */ |
| 5184 | dr[1] = scl[1] * S->size_x; /* This is arrow head length in degrees, approximately, adjusted for ~pen thickness to ensure no gap between head and line */ |
| 5185 | max_length = MAX (dr[0], dr[1]); |
| 5186 | if (max_length > h_length_limit) { |
| 5187 | s2 = h_length_limit / max_length; |
| 5188 | if (s2 < S->v.v_norm_limit) s2 = S->v.v_norm_limit; |
| 5189 | warn = 2; |
| 5190 | } |
| 5191 | } |
| 5192 | |
| 5193 | /* Might have to shrink things */ |
| 5194 | s1 = gmt_get_vector_shrinking (GMT, &(S->v), S->v.value, C.r0); /* Vector attribute shrinking factor or 1 */ |
| 5195 |
no test coverage detected