13static double const tol = 1.0e-12;
40 double const norm_vector_a[3],
double const norm_vector_b[3],
41 double p[3],
double q[3]) {
50 double sq_sin_plane_angle =
51 temp_p[0] * temp_p[0] + temp_p[1] * temp_p[1] + temp_p[2] * temp_p[2];
56 double scale = 1.0 / sqrt(sq_sin_plane_angle);
57 p[0] = (temp_p[0] * scale);
58 p[1] = (temp_p[1] * scale);
59 p[2] = (temp_p[2] * scale);
60 q[0] = -
p[0], q[1] = -
p[1], q[2] = -
p[2];
65#if defined __INTEL_COMPILER
66#pragma intel optimization_level 0
72 double const gc_norm_vector[3],
double const z,
73 double p[3],
double q[3]) {
80 double b = sqrt(
MAX(1.0 - sq_z,0.0));
81 double b_n0 = b * gc_norm_vector[0];
82 double b_n1 = b * gc_norm_vector[1];
95 double const gc_norm_vector[3],
double const z,
96 double p[3],
double q[3]) {
133 double sq_n[3] = {gc_norm_vector[0] * gc_norm_vector[0],
134 gc_norm_vector[1] * gc_norm_vector[1],
135 gc_norm_vector[2] * gc_norm_vector[2]};
138 double max_sq_gc_z = sq_n[0] + sq_n[1];
147 int num_intersections =
148 ((max_sq_gc_z > (sq_z -
tol)) - (max_sq_gc_z < (sq_z +
tol))) + 1;
150 switch (num_intersections) {
159 double a = -(gc_norm_vector[2] * z) / max_sq_gc_z;
161 p[0] = ((q[0] = gc_norm_vector[0] * a));
162 p[1] = ((q[1] = gc_norm_vector[1] * a));
170 double a = -(gc_norm_vector[2] * z) / max_sq_gc_z;
171 double b = sqrt(max_sq_gc_z - sq_z)/max_sq_gc_z;
172 double a_n0 = a * gc_norm_vector[0];
173 double a_n1 = a * gc_norm_vector[1];
174 double b_n0 = b * gc_norm_vector[0];
175 double b_n1 = b * gc_norm_vector[1];
187 return num_intersections;
195 double const norm_vector_a[3],
double const norm_vector_b[3],
196 double p[3],
double q[3]) {
198 double sq_plane_diff =
199 MIN((norm_vector_a[0] - norm_vector_b[0]) *
200 (norm_vector_a[0] - norm_vector_b[0]) +
201 (norm_vector_a[1] - norm_vector_b[1]) *
202 (norm_vector_a[1] - norm_vector_b[1]),
203 (norm_vector_a[0] + norm_vector_b[0]) *
204 (norm_vector_a[0] + norm_vector_b[0]) +
205 (norm_vector_a[1] + norm_vector_b[1]) *
206 (norm_vector_a[1] + norm_vector_b[1]));
212 p[0] = 0,
p[1] = 0;
p[2] = 1;
213 q[0] = 0, q[1] = 0; q[2] = -1;
219 double const vec[3],
double const norm_vector[3],
double p[3],
double q[3]) {
223 double dot = vec[0] * norm_vector[0];
224 double err = fma(vec[0], norm_vector[0], -dot);
225 dot = fma(vec[1], norm_vector[1], dot);
226 err += fma(vec[1], norm_vector[1], -vec[1]*norm_vector[1]);
227 dot = fma(vec[2], norm_vector[2], dot);
228 err += fma(vec[2], norm_vector[2], -vec[2]*norm_vector[2]);
234 q[0] = -((
p[0] = vec[0]));
235 q[1] = -((
p[1] = vec[1]));
236 q[2] = -((
p[2] = vec[2]));
241 double const vec[3],
double z,
double p[3],
double q[3]) {
244 if (fabs(vec[2] - z) >
tol)
return 0;
246 q[0] = -((
p[0] = vec[0]));
247 q[1] = -((
p[1] = vec[1]));
248 q[2] = ((
p[2] = vec[2]));
253 double const vec_a[3],
double const vec_b[3],
double p[3],
double q[3]) {
257 q[0] = -((
p[0] = vec_a[0]));
258 q[1] = -((
p[1] = vec_a[1]));
259 q[2] = -((
p[2] = vec_a[2]));
278 "ERROR(yac_circle_intersect): unknown circle type.")
316 double const a[],
double const b[],
double const p[],
317 double sq_len_diff_ab) {
329 return sq_len_diff_ab +
tol >= sq_len_diff_vec_ap + sq_len_diff_vec_bp;
333 double const a[],
double const b[],
double const p[]) {
343 if (fabs(fabs(a[2]) - 1.0) <
tol)
return 1;
345 double fabs_a[2] = {fabs(a[0]), fabs(a[1])};
346 int flag = fabs_a[0] > fabs_a[1];
347 double a_0 = a[
flag], a_1 = a[
flag^1];
348 double b_0 = b[
flag], b_1 = b[
flag^1];
351 double temp = b_0 - (b_1 * a_0) / a_1;
354 if (fabs(temp) <
tol)
355 return (fabs(a_0 - p_0) <
tol) && (fabs(a_1 - p_1) <
tol);
357 double beta = (p_0 - (p_1 * a_0) / a_1) / temp;
359 if (beta < -
tol)
return 0;
361 double alpha = (p_1 - b_1 * beta) / a_1;
367 enum yac_edge_type edge_type,
double const a[3],
double const b[3],
374 "ERROR(compute_edge_middle_point_vec): invalide edge_type")
377 middle[0] = a[0]+b[0], middle[1] = a[1]+b[1], middle[2] = a[2];
378 double temp = middle[0]*middle[0] + middle[1]*middle[1];
379 double scale = sqrt((1.0 - middle[2] * middle[2])/temp);
383 middle[0] = a[0]+b[0], middle[1] = a[1]+b[1], middle[2] = a[2]+b[2];
389 enum yac_edge_type edge_type,
double const a[3],
double const b[3],
390 double const c[3],
double const d[3],
double p[3],
double q[3],
391 int intersection_type) {
409 switch (intersection_type) {
425 p[0] = a[0],
p[1] = a[1],
p[2] = a[2];
426 q[0] = b[0], q[1] = b[1], q[2] = b[2];
433 p[0] = c[0],
p[1] = c[1],
p[2] = c[2];
434 q[0] = d[0], q[1] = d[1], q[2] = d[2];
439 p[0] = a[0],
p[1] = a[1],
p[2] = a[2];
440 q[0] = c[0], q[1] = c[1], q[2] = c[2];
443 p[0] = a[0],
p[1] = a[1],
p[2] = a[2];
444 q[0] = d[0], q[1] = d[1], q[2] = d[2];
447 p[0] = b[0],
p[1] = b[1],
p[2] = b[2];
448 q[0] = c[0], q[1] = c[1], q[2] = c[2];
451 p[0] = b[0],
p[1] = b[1],
p[2] = b[2];
452 q[0] = d[0], q[1] = d[1], q[2] = d[2];
461 double const a[3],
double const b[3],
double const c[3],
double const d[3],
462 double p[3],
double q[3]) {
478 double const a[3],
double const b[3],
double const c[3],
double const d[3],
479 double const p[3],
double const q[3]) {
492 double const a[3],
double const b[3],
double norm_vector[3]) {
494 norm_vector[0] = a[1] * b[2] - a[2] * b[1];
495 norm_vector[1] = a[2] * b[0] - a[0] * b[2];
496 norm_vector[2] = a[0] * b[1] - a[1] * b[0];
498 double scale = 1.0 / sqrt(norm_vector[0] * norm_vector[0] +
499 norm_vector[1] * norm_vector[1] +
500 norm_vector[2] * norm_vector[2]);
501 norm_vector[0] *= scale;
502 norm_vector[1] *= scale;
503 norm_vector[2] *= scale;
525 double const a[3],
double const b[3],
double const c[3],
double const d[3],
526 double p[3],
double q[3]) {
528 double norm_vector_ab[3], norm_vector_cd[3];
533 switch (
gcxgc(norm_vector_ab, norm_vector_cd,
p, q)) {
557 double const a[3],
double const b[3],
double const c[3],
double const d[3],
558 double p[3],
double q[3]) {
561 if (fabs(a[2] - c[2]) >
tol)
return -1;
573 double const a[3],
double const b[3],
double norm_vector[3]) {
575 norm_vector[0] = a[1] * b[2] - a[2] * b[1];
576 norm_vector[1] = a[2] * b[0] - a[0] * b[2];
577 norm_vector[2] = 0.0;
579 double scale = 1.0 / sqrt(norm_vector[0] * norm_vector[0] +
580 norm_vector[1] * norm_vector[1]);
581 norm_vector[0] *= scale;
582 norm_vector[1] *= scale;
600 double const a[3],
double const b[3],
double const c[3],
double const d[3],
601 double p[3],
double q[3]) {
603 double norm_vector_ab[3], norm_vector_cd[3];
607 switch(
loncxlonc(norm_vector_ab, norm_vector_cd,
p, q)) {
619 double const a[3],
double const b[3],
double const c[3],
double const d[3],
620 double const p[3],
double const q[3]) {
647 double const a[3],
double const b[3],
double const c[3],
double const d[3],
648 double p[3],
double q[3]) {
650 double norm_vector_ab[3];
653 int num_intersections =
loncxlatc(norm_vector_ab, c[2],
p, q);
654 YAC_ASSERT(num_intersections == 2,
"ERROR(yac_loncxlatc_vec): internal error")
679#if defined __INTEL_COMPILER
680#pragma intel optimization_level 0
686 double const a[3],
double const b[3],
double const c[3],
double const d[3],
687 double p[3],
double q[3]) {
689 double norm_vector_ab[3];
692 int num_intersections =
gcxlatc(norm_vector_ab, c[2],
p, q);
694 switch (num_intersections) {
711 double const a[3],
double const b[3],
double p[3],
double q[3]) {
717 double const point[3],
double const a[3],
double const b[3],
718 double p[3],
double q[3]) {
725 if (
pxgc(point, norm_ab,
p, q)) {
741 double const point[3],
double const a[3],
double const b[3],
742 double p[3],
double q[3]) {
744 if (
pxlatc(point, a[2],
p, q)) {
758 return (ret_value & (~(1 + 2 + 4 + 8))) +
759 ((ret_value & (1 + 2)) << 2) +
760 ((ret_value & (4 + 8)) >> 2);
764 enum yac_edge_type edge_type_a,
double const a[3],
double const b[3],
765 enum yac_edge_type edge_type_b,
double const c[3],
double const d[3],
766 double p[3],
double q[3]) {
780 if (edge_a_is_point && edge_b_is_point) {
785 }
else if (edge_a_is_point || edge_b_is_point) {
787 enum yac_edge_type edge_type[2] = {edge_type_a, edge_type_b};
788 double const * edge[2][2] = {{a,b}, {c,d}};
789 double const * point[2] = {c,a};
792 switch (edge_type[edge_a_is_point]) {
796 point[edge_a_is_point],
797 edge[edge_a_is_point][0], edge[edge_a_is_point][1],
p, q);
804 point[edge_a_is_point],
805 edge[edge_a_is_point][0], edge[edge_a_is_point][1],
p, q);
809 if (edge_a_is_point)
return ret_value;
861 double p[3],
double const a[3],
double const b[3],
868 (circle_type ==
POINT),
869 "ERROR(yac_point_on_edge): unknown edge type.")
873 "ERROR(yac_point_on_edge): "
874 "LAT_CIRCLE but edge vertices do not have the same latitude");
876 switch (circle_type) {
#define YAC_ASSERT(exp, msg)
static int points_are_identically(double const *a, double const *b)
static double sq_len_diff_vec(double const a[3], double const b[3])
computes square of the lenght of the vector ab
static void crossproduct_kahan(double const a[], double const b[], double cross[])
#define yac_angle_low_tol
static void normalise_vector(double v[])
@ YAC_GREAT_CIRCLE_EDGE
great circle
@ YAC_LAT_CIRCLE_EDGE
latitude circle
@ YAC_LON_CIRCLE_EDGE
longitude circle
static int yac_pxlat_vec(double const point[3], double const a[3], double const b[3], double p[3], double q[3])
static int yac_check_pq_gcxlatc(double const a[3], double const b[3], double const c[3], double const d[3], double const p[3], double const q[3])
static int yac_latcxlatc_vec(double const a[3], double const b[3], double const c[3], double const d[3], double p[3], double q[3])
compute the intersection point two circles of latitude
static int gcxgc(double const norm_vector_a[3], double const norm_vector_b[3], double p[3], double q[3])
int yac_circle_intersect(struct yac_circle a, struct yac_circle b, double p[3], double q[3])
static int yac_identical_gcxgc_vec(double const a[3], double const b[3], double const c[3], double const d[3], double p[3], double q[3])
static int vector_is_between(double const a[], double const b[], double const p[], double sq_len_diff_ab)
static int yac_pxgc_vec(double const point[3], double const a[3], double const b[3], double p[3], double q[3])
static void compute_edge_middle_point_vec(enum yac_edge_type edge_type, double const a[3], double const b[3], double middle[3])
static int gcxlatc(double const gc_norm_vector[3], double const z, double p[3], double q[3])
static int vector_is_between_lat(double const a[], double const b[], double const p[])
static int yac_check_pq_gcxgc(double const a[3], double const b[3], double const c[3], double const d[3], double const p[3], double const q[3])
static int pxgc(double const vec[3], double const norm_vector[3], double p[3], double q[3])
static int adjust_ret_value(int ret_value)
static void compute_norm_vector(double const a[3], double const b[3], double norm_vector[3])
static int yac_gcxgc_vec(double const a[3], double const b[3], double const c[3], double const d[3], double p[3], double q[3])
static int loncxlonc(double const norm_vector_a[3], double const norm_vector_b[3], double p[3], double q[3])
static int yac_loncxlatc_vec(double const a[3], double const b[3], double const c[3], double const d[3], double p[3], double q[3])
compute the intersection point of a meridian and a parallel
int yac_intersect_vec(enum yac_edge_type edge_type_a, double const a[3], double const b[3], enum yac_edge_type edge_type_b, double const c[3], double const d[3], double p[3], double q[3])
int yac_point_on_edge(double p[3], double const a[3], double const b[3], enum yac_circle_type circle_type)
static int pxlatc(double const vec[3], double z, double p[3], double q[3])
static int yac_gcxlatc_vec(double const a[3], double const b[3], double const c[3], double const d[3], double p[3], double q[3])
compute the intersection of a great circle with the parallel
static int yac_pxp_vec(double const a[3], double const b[3], double p[3], double q[3])
static int yac_loncxlonc_vec(double const a[3], double const b[3], double const c[3], double const d[3], double p[3], double q[3])
compute the intersection point two circles of longitude
static int yac_identical_circles_vec(enum yac_edge_type edge_type, double const a[3], double const b[3], double const c[3], double const d[3], double p[3], double q[3], int intersection_type)
static void compute_lon_norm_vector(double const a[3], double const b[3], double norm_vector[3])
static int loncxlatc(double const gc_norm_vector[3], double const z, double p[3], double q[3])
static int pxp(double const vec_a[3], double const vec_b[3], double p[3], double q[3])
struct yac_circle::@9::@12 p
enum yac_circle_type type
struct yac_circle::@9::@10 gc
struct yac_circle::@9::@11 lat
union yac_circle::@9 data
struct yac_circle::@9::@10 lon
double(* p)(double lon, double lat)