| 4982 | } |
| 4983 | |
| 4984 | GMT_LOCAL void gmtplot_scircle_sub (struct GMT_CTRL *GMT, double lon0, double lat0, double angle_1, double angle_2, struct GMT_SYMBOL *S, struct GMT_CIRCLE *C) { |
| 4985 | /* We must determine points A and B, whose small-circle connector about pole P is the arc we seek to draw */ |
| 4986 | |
| 4987 | int justify = PSL_vec_justify (S->v.status); /* Return justification as 0-3 */ |
| 4988 | double R[3][3], M[3]; |
| 4989 | gmt_M_memset (C, 1, struct GMT_CIRCLE); /* Set all to zero */ |
| 4990 | /* Requires the rotation matrix for pole S->v.pole */ |
| 4991 | |
| 4992 | /* Here angle_1, angle_2 are not necessarily that, depending on S->v.status: |
| 4993 | * S->v.pole & PSL_VEC_ANGLES : angle_1 is opening angle1 and angle_2 is opening angle2 about the pole. |
| 4994 | * Otherwise: angle_2 is the length of the arc in km */ |
| 4995 | gmt_geo_to_cart (GMT, lat0, lon0, M, true); /* Given input point */ |
| 4996 | gmt_geo_to_cart (GMT, S->v.pole[GMT_Y], S->v.pole[GMT_X], C->P, true); |
| 4997 | C->colat = d_acosd (gmt_dot3v (GMT, M, C->P)); /* Colatitude of input point relative to pole, in degrees */ |
| 4998 | |
| 4999 | if (S->v.status & PSL_VEC_ANGLES) { |
| 5000 | /* Was given the two opening angles; compute A and B accordingly */ |
| 5001 | gmt_make_rot_matrix (GMT, S->v.pole[GMT_X], S->v.pole[GMT_Y], angle_1, R); |
| 5002 | gmt_matrix_vect_mult (GMT, 3U, R, M, C->A); /* Get A */ |
| 5003 | gmt_cart_to_geo (GMT, &C->lat[0], &C->lon[0], C->A, true); |
| 5004 | gmt_make_rot_matrix (GMT, S->v.pole[GMT_X], S->v.pole[GMT_Y], angle_2, R); |
| 5005 | gmt_matrix_vect_mult (GMT, 3U, R, M, C->B); /* Get B */ |
| 5006 | gmt_cart_to_geo (GMT, &C->lat[1], &C->lon[1], C->B, true); |
| 5007 | C->rot = C->r0 = C->r = angle_2 - angle_1; |
| 5008 | } |
| 5009 | else { |
| 5010 | /* Here A, B, or midpoint was given, + the arc length via angle_2 */ |
| 5011 | /* Determine co-latitude for this point */ |
| 5012 | C->rot = C->r0 = C->r = (angle_1 / GMT->current.proj.DIST_KM_PR_DEG) / sind (C->colat); /* Opening angle in spherical degrees */ |
| 5013 | switch (justify) { /* A and B depends on chosen justification */ |
| 5014 | case 0: /* Was given coordinates of A; determine B */ |
| 5015 | gmt_M_memcpy (C->A, M, 3, double); |
| 5016 | C->lon[0] = lon0; C->lat[0] = lat0; |
| 5017 | if (C->r > 180.0) {C->longway = true; C->r -= 180.0;} /* Temporarily adjust if arcs > 180 degrees are chosen */ |
| 5018 | /* Rotate A by C->r0 degrees about P to get B */ |
| 5019 | gmt_make_rot_matrix (GMT, S->v.pole[GMT_X], S->v.pole[GMT_Y], C->r0, R); |
| 5020 | gmt_matrix_vect_mult (GMT, 3U, R, C->A, C->B); /* Get B */ |
| 5021 | gmt_cart_to_geo (GMT, &C->lat[1], &C->lon[1], C->B, true); |
| 5022 | break; |
| 5023 | case 1: /* Was given coordinates of halfway point; determine A and B */ |
| 5024 | if (C->r > 180.0) C->longway = true; /* Temporarily adjust if arcs > 180 degrees are chosen */ |
| 5025 | /* Rotate M by -C->r0/2 degrees about P to get A */ |
| 5026 | gmt_make_rot_matrix (GMT, S->v.pole[GMT_X], S->v.pole[GMT_Y], -0.5 * C->r0, R); |
| 5027 | gmt_matrix_vect_mult (GMT, 3U, R, M, C->A); /* Get A */ |
| 5028 | gmt_cart_to_geo (GMT, &C->lat[0], &C->lon[0], C->A, true); |
| 5029 | /* Rotate M by +C->r0/2 degrees about P to get B */ |
| 5030 | gmt_make_rot_matrix (GMT, S->v.pole[GMT_X], S->v.pole[GMT_Y], +0.5 * C->r0, R); |
| 5031 | gmt_matrix_vect_mult (GMT, 3U, R, M, C->B); /* Get B */ |
| 5032 | gmt_cart_to_geo (GMT, &C->lat[1], &C->lon[1], C->B, true); |
| 5033 | break; |
| 5034 | case 2: /* Was given coordinates of B point; determine A */ |
| 5035 | gmt_M_memcpy (C->B, M, 3, double); |
| 5036 | C->lon[1] = lon0; C->lat[1] = lat0; |
| 5037 | if (C->r > 180.0) {C->longway = true; C->r -= 180.0;} /* Temporarily adjust if arcs > 180 degrees are chosen */ |
| 5038 | /* Rotate B by -C->r0 degrees about P to get A */ |
| 5039 | gmt_make_rot_matrix (GMT, S->v.pole[GMT_X], S->v.pole[GMT_Y], -C->r0, R); |
| 5040 | gmt_matrix_vect_mult (GMT, 3U, R, C->B, C->A); /* Get A */ |
| 5041 | gmt_cart_to_geo (GMT, &C->lat[0], &C->lon[0], C->A, true); |
no test coverage detected