YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
geometry.h
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#ifndef GEOMETRY_H
6#define GEOMETRY_H
7
8#ifdef HAVE_CONFIG_H
9// We include 'config.h' in this header file (which is a bad practice)
10// because we need the definition of the 'restrict' keyword for the
11// inlined functions.
12#include "config.h"
13#endif
14
15#include <math.h>
16#include <float.h>
17
18#include "yac_types.h"
19#include "grids/grid_cell.h"
20#include "utils_core.h"
21
22#define YAC_RAD (0.01745329251994329576923690768489) // M_PI / 180
23
24// angle tolerance
25
26#define yac_angle_tol (1e-9)
27#define yac_sq_angle_tol (1e-9 * 1e-9)
28#define yac_cos_angle_tol (0.9999999999999999995)
29#define yac_angle_low_tol (1e-11)
30#define yac_cos_angle_low_tol (1.0)
31
33 double sin, cos;
34};
35
36static const struct sin_cos_angle SIN_COS_ZERO = {0.0, 1.0};
39
40static const struct sin_cos_angle SIN_COS_M_PI_2 = {1.0, 0.0}; /* PI/2 */
41static const struct sin_cos_angle SIN_COS_M_PI = {0.0, -1.0}; /* PI */
42static const struct sin_cos_angle SIN_COS_7_M_PI_4 = {-0.707106781186547524401, +0.707106781186547524401}; /* (7 * PI)/4 */
43
48
51 double base_vector[3];
56 double sq_crd; // sq_crd = (chord)^2
57};
58
65
66// each circle partitions the sphere into an inside and an outside part
67// (the point is the exception; everything except the point is outside)
68struct yac_circle {
70 union {
71 struct {
72 // the norm vector points into the inside direction
73 double norm_vector[3];
74 } gc, lon;
75 struct {
78 double z;
82 double r;
83 } lat;
84 struct {
85 double vec[3];
86 } p;
88};
89
97int yac_point_in_cell (double point_coords[3], struct yac_grid_cell cell);
98
107int yac_point_in_cell2 (double point_coords[3], struct yac_grid_cell cell,
108 struct bounding_circle bnd_circle);
109
117static inline double get_angle (double a_lon, double b_lon) {
118 double diff = a_lon - b_lon;
119#if defined(CDO)
120 return diff - lround(diff / (2.0 * M_PI)) * (2.0 * M_PI);
121#else
122 return diff - round(diff / (2.0 * M_PI)) * (2.0 * M_PI);
123#endif
124}
125
133static inline double get_angle_deg (double a_lon, double b_lon) {
134 double diff = a_lon - b_lon;
135#if defined(CDO)
136 return diff - lround(diff / 360.0) * (360.0);
137#else
138 return diff - round(diff / 360.0) * (360.0);
139#endif
140}
141
165 enum yac_edge_type edge_type_a, double const a[3], double const b[3],
166 enum yac_edge_type edge_type_b, double const c[3], double const d[3],
167 double p[3], double q[3]);
168
175 struct bounding_circle * bnd_circle);
176
184int yac_extents_overlap(struct bounding_circle * extent_a,
185 struct bounding_circle * extent_b);
186
188static inline double sq_len_diff_vec(double const a[3], double const b[3]) {
189 double ab[3] = {a[0]-b[0], a[1]-b[1], a[2]-b[2]};
190 return ab[0] * ab[0] + ab[1] * ab[1] + ab[2] * ab[2];
191}
192
193static inline double compute_sq_crd(struct sin_cos_angle angle) {
194
195 double temp = 1.0 - angle.cos;
196 return temp * temp + angle.sin * angle.sin;
197}
198
207 double point_vector[3], struct bounding_circle * bnd_circle) {
208
209 if (bnd_circle->sq_crd == DBL_MAX)
210 bnd_circle->sq_crd = compute_sq_crd(bnd_circle->inc_angle);
211
212 return
213 bnd_circle->sq_crd >=
214 sq_len_diff_vec(bnd_circle->base_vector, point_vector);
215}
216
217static inline double clamp_abs_one(double val) {
218 return val > -1.0 ? (val < 1.0 ? val : 1.0) : -1.0;
219}
220
229static inline void compute_sin_cos(
230 double angle, double * sin_value, double * cos_value) {
231
232 double abs_angle = fabs(angle);
233 if (abs_angle < yac_angle_low_tol) {
234 *sin_value = 0.0;
235 *cos_value = 1.0;
236 } else if (fabs(abs_angle - M_PI) < yac_angle_low_tol) {
237 *sin_value = 0.0;
238 *cos_value = -1.0;
239 } else if (fabs(abs_angle - M_PI_2) < yac_angle_low_tol) {
240 *sin_value = copysign(1.0, angle);
241 *cos_value = 0.0;
242 } else {
243 *sin_value = clamp_abs_one(sin(angle));
244 *cos_value = clamp_abs_one(cos(angle));
245 }
246}
247
258static inline void LLtoXYZ(double lon, double lat, double p_out[]) {
259
260 while (lon < -M_PI) lon += 2.0 * M_PI;
261 while (lon >= M_PI) lon -= 2.0 * M_PI;
262
263 double sin_lon, cos_lon, sin_lat, cos_lat;
264 compute_sin_cos(lon, &sin_lon, &cos_lon);
265 compute_sin_cos(lat, &sin_lat, &cos_lat);
266
267 p_out[0] = cos_lat * cos_lon;
268 p_out[1] = cos_lat * sin_lon;
269 p_out[2] = sin_lat;
270}
271
278static inline void LLtoXYZ_deg(double lon, double lat, double p_out[]) {
279 LLtoXYZ(lon*YAC_RAD, lat*YAC_RAD, p_out);
280}
281
292static inline void XYZtoLL (double const p_in[], double * lon, double * lat) {
293
294 *lon = atan2(p_in[1] , p_in[0]);
295 *lat = M_PI_2 - acos(p_in[2]);
296}
297
309static inline void product_eft(
310 double a, double b, double * restrict product, double * restrict error) {
311 *product = a * b;
312 *error = fma(a, b, -*product);
313}
314
326static inline void sum_eft(
327 double a, double b, double * restrict sum, double * restrict error) {
328 *sum = a + b;
329 double temp = *sum - a;
330 *error = (a - (*sum - temp)) + (b - temp);
331}
332
343static inline void accu_eft(
344 double a, double * restrict accu, double * restrict error) {
345 double a_ = a - *error;
346 double temp = *accu + a_;
347 *error = (temp - *accu) - a_;
348 *accu = temp;
349}
350
366static inline void accu_product_eft(
367 double a, double b, double * restrict accu, double * restrict accu_error) {
368
369 // compute product with error
370 double product, product_error;
371 product_eft(a, b, &product, &product_error);
372
373 // compensated accumulation
374 accu_eft(product, accu, accu_error);
375 *accu_error += product_error;
376}
377
391static inline void det2_error(
392 double a, double b, double c, double d,
393 double * restrict det, double * restrict det_error) {
394
395 double ad, ad_err;
396 product_eft(a, d, &ad, &ad_err);
397
398 double bc, bc_err;
399 product_eft(b, -c, &bc, &bc_err);
400
401 double temp_err;
402 sum_eft(ad, bc, det, &temp_err);
403 *det_error = ad_err + (temp_err + bc_err);
404}
405
406// computation of the determinant of a 2x2 matrix using Kahan summation
407static inline double det2_kahan(double a, double b, double c, double d) {
408 double bc = b*c;
409 double e_bc = fma(b,c,-bc); // the rounding error of the multiplication
410 double det = fma(a,d,-bc);
411 return det + e_bc;
412}
413
414static inline void crossproduct_kahan (
415 double const a[], double const b[], double cross[]) {
416
417 /* crossproduct in Cartesian coordinates */
418
419 cross[0] = det2_kahan(a[1], a[2], b[1], b[2]);
420 cross[1] = det2_kahan(a[2], a[0], b[2], b[0]);
421 cross[2] = det2_kahan(a[0], a[1], b[0], b[1]);
422
423}
424
429static inline void crossproduct_d (
430 const double a[], const double b[], double cross[]) {
431
432/* crossproduct in Cartesian coordinates */
433
434 cross[0] = a[1] * b[2] - a[2] * b[1];
435 cross[1] = a[2] * b[0] - a[0] * b[2];
436 cross[2] = a[0] * b[1] - a[1] * b[0];
437}
438
443static inline double dotproduct_eft(double const a[], double const b[]) {
444 double accu = 0.0, err = 0.0;
445 accu_product_eft(a[0], b[0], &accu, &err);
446 accu_product_eft(a[1], b[1], &accu, &err);
447 accu_product_eft(a[2], b[2], &accu, &err);
448
449 double result, result_err;
450 sum_eft(accu, -err, &result, &result_err);
451 return result + result_err;
452}
453
472static inline double get_vector_angle(double const a[3], double const b[3]) {
473
474 double sub[3] = {a[0] - b[0], a[1] - b[1], a[2] - b[2]};
475 double add[3] = {a[0] + b[0], a[1] + b[1], a[2] + b[2]};
476 double sq_sub = sub[0] * sub[0] + sub[1] * sub[1] + sub[2] * sub[2];
477 double sq_add = add[0] * add[0] + add[1] * add[1] + add[2] * add[2];
478
479 // angle = 2 * atan(|a-b|/|a+b|)
480 return (fabs(sq_add) > 1e-12)?(2.0 * atan(sqrt(sq_sub/sq_add))):M_PI;
481}
482
483static inline struct sin_cos_angle sin_cos_angle_new(double sin, double cos) {
484
485 struct sin_cos_angle angle;
486
487 angle.sin = clamp_abs_one(sin);
488 angle.cos = clamp_abs_one(cos);
489
490 return angle;
491}
492
494 double const a[3], double const b[3]) {
495
496 double cross_ab[3];
497 crossproduct_kahan(a, b, cross_ab);
498
499 return sin_cos_angle_new(sqrt(cross_ab[0]*cross_ab[0] +
500 cross_ab[1]*cross_ab[1] +
501 cross_ab[2]*cross_ab[2]),
502 a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
503}
504
505// works for angles in the range [0;2*PI[
506static inline int compare_angles(
507 struct sin_cos_angle a, struct sin_cos_angle b) {
508
509 // there are 5 sections:
510 // 0: 0 <= angle < PI/4
511 // 1: PI/4 <= angle < 3*PI/4
512 // 2: 3*PI/4 <= angle < 5*PI/4
513 // 3: 5*PI/4 <= angle < 7*PI/4
514 // 4: 7*PI/4 <= angle < 2*PI
515 int t_a = fabs(a.cos) <= M_SQRT1_2;
516 int t_b = fabs(b.cos) <= M_SQRT1_2;
517 int a_section = t_a | ((((a.sin < 0.0) & t_a) |
518 ((a.cos < 0.0) & (fabs(a.sin) < M_SQRT1_2))) << 1);
519 int b_section = t_b | ((((b.sin < 0.0) & t_b) |
520 ((b.cos < 0.0) & (fabs(b.sin) < M_SQRT1_2))) << 1);
521 // if current section is 0, then it could be actually section 4
522 if (!a_section) a_section = (a.sin < 0.0) << 2;
523 if (!b_section) b_section = (b.sin < 0.0) << 2;
524
525 if (a_section != b_section)
526 return (a_section > b_section) - (a_section < b_section);
527
528 int ret;
529
530 switch (a_section) {
531 case(0):
532 case(4):
533 default:
534 ret = (b.sin < a.sin + yac_angle_low_tol) -
535 (a.sin < b.sin + yac_angle_low_tol);
536 if (ret) return ret;
537 else {
538 ret = (a.cos < b.cos + yac_angle_low_tol) -
539 (b.cos < a.cos + yac_angle_low_tol);
540 if (a.sin >= 0.0) return ret;
541 else return -ret;
542 }
543 case(1):
544 ret = (a.cos < b.cos + yac_angle_low_tol) -
545 (b.cos < a.cos + yac_angle_low_tol);
546 if (ret) return ret;
547 else {
548 ret = (b.sin < a.sin + yac_angle_low_tol) -
549 (a.sin < b.sin + yac_angle_low_tol);
550 if (a.cos >= 0.0) return ret;
551 else return -ret;
552 }
553 case(2):
554 ret = (a.sin < b.sin + yac_angle_low_tol) -
555 (b.sin < a.sin + yac_angle_low_tol);
556 if (ret) return ret;
557 else {
558 ret = (a.cos < b.cos + yac_angle_low_tol) -
559 (b.cos < a.cos + yac_angle_low_tol);
560 if (a.sin >= 0.0) return ret;
561 else return -ret;
562 }
563 case(3):
564 ret = (b.cos < a.cos + yac_angle_low_tol) -
565 (a.cos < b.cos + yac_angle_low_tol);
566 if (ret) return ret;
567 else {
568 ret = (a.sin < b.sin + yac_angle_low_tol) -
569 (b.sin < a.sin + yac_angle_low_tol);
570 if (a.cos <= 0.0) return ret;
571 else return -ret;
572 }
573 }
574}
575
583static inline double sin_cos_angle_to_dble(struct sin_cos_angle angle) {
584
585 int t = fabs(angle.cos) <= M_SQRT1_2;
586 int section = t | ((((angle.sin < 0.0) & t) |
587 ((angle.cos < 0.0) & (fabs(angle.sin) < M_SQRT1_2))) << 1);
588 if (!section) section = (angle.sin < 0.0) << 2;
589
590 switch (section) {
591 default:
592 case(0): return 0.0 * M_SQRT1_2 + angle.sin;
593 case(1): return 2.0 * M_SQRT1_2 - angle.cos;
594 case(2): return 4.0 * M_SQRT1_2 - angle.sin;
595 case(3): return 6.0 * M_SQRT1_2 + angle.cos;
596 case(4): return 8.0 * M_SQRT1_2 + angle.sin;
597 }
598}
599
603 struct sin_cos_angle a, struct sin_cos_angle b) {
604
605 return sin_cos_angle_new(a.sin * b.cos + a.cos * b.sin,
606 a.cos * b.cos - a.sin * b.sin);
607}
608
612static inline int sum_angles(
613 struct sin_cos_angle a, struct sin_cos_angle b,
614 struct sin_cos_angle * restrict sum) {
615
616 struct sin_cos_angle sum_ = sum_angles_no_check(a, b);
617
618 *sum = sum_;
619
620 // if a or b is smaller than the result
621 return (compare_angles(sum_, a) < 0) || (compare_angles(sum_, b) < 0);
622}
623
627 struct sin_cos_angle a, struct sin_cos_angle b) {
628
629 return sin_cos_angle_new(a.sin * b.cos - a.cos * b.sin,
630 a.cos * b.cos + a.sin * b.sin);
631}
632
636static inline int sub_angles(
637 struct sin_cos_angle a, struct sin_cos_angle b,
638 struct sin_cos_angle * restrict sub) {
639
640 int compare_result = compare_angles(a, b);
641
642 // return sin=0.0 and cos=1.0 if the angles are equal to each other,
643 // i.e. compare_result == 0
644 *sub = compare_result ? sub_angles_no_check(a, b) : SIN_COS_ZERO;
645
646 return compare_result < 0;
647}
648
650static inline double compute_angle(struct sin_cos_angle angle) {
651
652 // the acos and asin are most accurate in the range [-M_SQRT1_2;M_SQRT1_2]
653 if (angle.cos > M_SQRT1_2) {
654
655 double angle_ = asin(angle.sin);
656
657 if (angle_ < 0.0) angle_ += 2.0 * M_PI;
658 return angle_;
659
660 } else if (angle.cos > - M_SQRT1_2) {
661
662 double angle_ = acos(angle.cos);
663
664 if (angle.sin > 0.0) return angle_;
665 else return 2.0 * M_PI - angle_;
666
667 } else {
668 return M_PI - asin(angle.sin);
669 }
670}
671
678static inline struct sin_cos_angle half_angle(struct sin_cos_angle angle) {
679
680 double x = (1.0 + fabs(angle.cos));
681
682 double scale = 1.0 / sqrt(x * x + angle.sin * angle.sin);
683
684 // first or fourth quadrant
685 if (angle.cos >= 0) {
686 scale = copysign(scale, angle.sin);
687 return sin_cos_angle_new(angle.sin * scale, x * scale);
688
689 // second and third quadrant
690 } else return sin_cos_angle_new(x * scale, angle.sin * scale);
691}
692
695static inline struct sin_cos_angle quarter_angle(struct sin_cos_angle angle) {
696
697 double tan = fabs(angle.sin / (1.0 + fabs(angle.cos)));
698 double one_plus_sq_tan = 1.0 + tan * tan;
699 double sqrt_one_plus_sq_tan = sqrt(one_plus_sq_tan);
700
701 double a = 1.0;
702 double b = tan;
703
704 // second and third quadrant
705 if (angle.cos < 0.0) {
706 a = tan;
707 b = 1.0;
708 }
709
710 double scale = M_SQRT1_2 / sqrt(one_plus_sq_tan + a * sqrt_one_plus_sq_tan);
711 double x = b * scale;
712 double y = (a + sqrt_one_plus_sq_tan) * scale;
713
714 // first and second quadrant
715 if (angle.sin >= 0.0) return sin_cos_angle_new(x, y);
716 // third and fourth quadrant
717 else return sin_cos_angle_new(y, x);
718}
719
727static inline int points_are_identically(double const * a, double const * b) {
728
729 // for small angles the Euclidean distance is nearly identical to
730 // great circle distance between vectors a and b
731 return sq_len_diff_vec(a, b) <= yac_sq_angle_tol;
732}
733
742static inline int compare_coords(double const * a, double const * b) {
743
744 // Check if points are identical using squared chord distance
745 if (points_are_identically(a, b)) return 0;
746
747 int ret;
748 if ((ret = (a[0] > b[0]) - (a[0] < b[0]))) return ret;
749 if ((ret = (a[1] > b[1]) - (a[1] < b[1]))) return ret;
750 return (a[2] > b[2]) - (a[2] < b[2]);
751}
752
754static inline void normalise_vector(double v[]) {
755
756 double norm = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
757
758 v[0] *= norm;
759 v[1] *= norm;
760 v[2] *= norm;
761}
762
769static inline void rotate_vector2(
770 double axis[], struct sin_cos_angle angle, double v_in[], double v_out[]) {
771
772 // using Rodrigues' rotation formula
773 // v_out = v_in * cos(angle) +
774 // (axis x v_in) * sin(angle) +
775 // axis * (axis * v_in) * (1 - cos(angle))
776
777 double cross_axis_v_in[3];
778 crossproduct_d(axis, v_in, cross_axis_v_in);
779
780 double dot_axis_v_in = axis[0]*v_in[0] + axis[1]*v_in[1] + axis[2]*v_in[2];
781 double temp = dot_axis_v_in * (1.0 - angle.cos);
782
783 v_out[0] =
784 v_in[0] * angle.cos + cross_axis_v_in[0] * angle.sin + axis[0] * temp;
785 v_out[1] =
786 v_in[1] * angle.cos + cross_axis_v_in[1] * angle.sin + axis[1] * temp;
787 v_out[2] =
788 v_in[2] * angle.cos + cross_axis_v_in[2] * angle.sin + axis[2] * temp;
789}
790
797static inline void rotate_vector(
798 double axis[], double angle, double v_in[], double v_out[]) {
799
800 double sin_angle = sin(angle);
801 double cos_angle = cos(angle);
803 axis, sin_cos_angle_new(sin_angle, cos_angle), v_in, v_out);
804}
805
820 struct yac_grid_cell cell, size_t start_corner, struct yac_grid_cell * triangles);
821
835 size_t const * corner_indices, size_t num_corners, size_t start_corner,
836 size_t (*triangle_indices)[3]);
837
849 double * vertices, size_t num_vertices, double triangle[][3],
850 size_t num_tests);
851
853 struct yac_circle a, struct yac_circle b, double p[3], double q[3]);
854
856 double p[3], double const a[3], double const b[3],
857 enum yac_circle_type circle_type);
858
859#endif // GEOMETRY_H
860
static struct sin_cos_angle get_vector_angle_2(double const a[3], double const b[3])
Definition geometry.h:493
static int compare_coords(double const *a, double const *b)
Definition geometry.h:742
static double compute_sq_crd(struct sin_cos_angle angle)
Definition geometry.h:193
static void product_eft(double a, double b, double *restrict product, double *restrict error)
Definition geometry.h:309
static const struct sin_cos_angle SIN_COS_LOW_TOL
Definition geometry.h:38
static double clamp_abs_one(double val)
Definition geometry.h:217
static const struct sin_cos_angle SIN_COS_7_M_PI_4
Definition geometry.h:42
static const struct sin_cos_angle SIN_COS_ZERO
Definition geometry.h:36
static void det2_error(double a, double b, double c, double d, double *restrict det, double *restrict det_error)
Definition geometry.h:391
int yac_circle_intersect(struct yac_circle a, struct yac_circle b, double p[3], double q[3])
static double dotproduct_eft(double const a[], double const b[])
Definition geometry.h:443
static double det2_kahan(double a, double b, double c, double d)
Definition geometry.h:407
void yac_triangulate_cell_indices(size_t const *corner_indices, size_t num_corners, size_t start_corner, size_t(*triangle_indices)[3])
Definition grid_cell.c:144
static int points_are_identically(double const *a, double const *b)
Definition geometry.h:727
static const struct sin_cos_angle SIN_COS_M_PI
Definition geometry.h:41
static void compute_sin_cos(double angle, double *sin_value, double *cos_value)
Definition geometry.h:229
void yac_compute_bnd_triangle(double *vertices, size_t num_vertices, double triangle[][3], size_t num_tests)
static void sum_eft(double a, double b, double *restrict sum, double *restrict error)
Definition geometry.h:326
static int yac_point_in_bounding_circle_vec(double point_vector[3], struct bounding_circle *bnd_circle)
Definition geometry.h:206
static double sq_len_diff_vec(double const a[3], double const b[3])
computes square of the lenght of the vector ab
Definition geometry.h:188
static void crossproduct_d(const double a[], const double b[], double cross[])
Definition geometry.h:429
static struct sin_cos_angle sum_angles_no_check(struct sin_cos_angle a, struct sin_cos_angle b)
Definition geometry.h:602
static double sin_cos_angle_to_dble(struct sin_cos_angle angle)
Definition geometry.h:583
static void crossproduct_kahan(double const a[], double const b[], double cross[])
Definition geometry.h:414
static void rotate_vector(double axis[], double angle, double v_in[], double v_out[])
Definition geometry.h:797
static struct sin_cos_angle quarter_angle(struct sin_cos_angle angle)
Definition geometry.h:695
static const struct sin_cos_angle SIN_COS_TOL
Definition geometry.h:37
static const struct sin_cos_angle SIN_COS_M_PI_2
Definition geometry.h:40
#define yac_sq_angle_tol
Definition geometry.h:27
#define yac_cos_angle_low_tol
Definition geometry.h:30
int yac_point_in_cell(double point_coords[3], struct yac_grid_cell cell)
static void rotate_vector2(double axis[], struct sin_cos_angle angle, double v_in[], double v_out[])
Definition geometry.h:769
#define yac_cos_angle_tol
Definition geometry.h:28
void yac_triangulate_cell(struct yac_grid_cell cell, size_t start_corner, struct yac_grid_cell *triangles)
Definition grid_cell.c:66
static void accu_product_eft(double a, double b, double *restrict accu, double *restrict accu_error)
Definition geometry.h:366
#define YAC_RAD
Definition geometry.h:22
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
Definition geometry.h:278
int yac_point_in_cell2(double point_coords[3], struct yac_grid_cell cell, struct bounding_circle bnd_circle)
static int compare_angles(struct sin_cos_angle a, struct sin_cos_angle b)
Definition geometry.h:506
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])
static int sub_angles(struct sin_cos_angle a, struct sin_cos_angle b, struct sin_cos_angle *restrict sub)
Definition geometry.h:636
int yac_point_on_edge(double p[3], double const a[3], double const b[3], enum yac_circle_type circle_type)
static struct sin_cos_angle sub_angles_no_check(struct sin_cos_angle a, struct sin_cos_angle b)
Definition geometry.h:626
void yac_get_cell_bounding_circle(struct yac_grid_cell cell, struct bounding_circle *bnd_circle)
Definition bnd_circle.c:422
int yac_extents_overlap(struct bounding_circle *extent_a, struct bounding_circle *extent_b)
Definition bnd_circle.c:533
static double compute_angle(struct sin_cos_angle angle)
return angles in the range of [0;2PI[
Definition geometry.h:650
#define yac_angle_low_tol
Definition geometry.h:29
#define yac_angle_tol
Definition geometry.h:26
static void normalise_vector(double v[])
Definition geometry.h:754
static double get_angle(double a_lon, double b_lon)
Definition geometry.h:117
static void LLtoXYZ(double lon, double lat, double p_out[])
Definition geometry.h:258
static double get_vector_angle(double const a[3], double const b[3])
Definition geometry.h:472
static int sum_angles(struct sin_cos_angle a, struct sin_cos_angle b, struct sin_cos_angle *restrict sum)
Definition geometry.h:612
static double get_angle_deg(double a_lon, double b_lon)
Definition geometry.h:133
yac_circle_type
Definition geometry.h:59
@ POINT
Definition geometry.h:63
@ LAT_CIRCLE
Definition geometry.h:61
@ GREAT_CIRCLE
Definition geometry.h:60
@ LON_CIRCLE
Definition geometry.h:62
static struct sin_cos_angle sin_cos_angle_new(double sin, double cos)
Definition geometry.h:483
static void accu_eft(double a, double *restrict accu, double *restrict error)
Definition geometry.h:343
static struct sin_cos_angle half_angle(struct sin_cos_angle angle)
Definition geometry.h:678
static void XYZtoLL(double const p_in[], double *lon, double *lat)
Definition geometry.h:292
yac_edge_type
Definition grid_cell.h:12
@ YAC_GREAT_CIRCLE_EDGE
great circle
Definition grid_cell.h:13
@ YAC_LAT_CIRCLE_EDGE
latitude circle
Definition grid_cell.h:14
@ YAC_LON_CIRCLE_EDGE
longitude circle
Definition grid_cell.h:15
struct sin_cos_angle inc_angle
angle between the middle point and the boundary of the spherical cap
Definition geometry.h:53
double base_vector[3]
Definition geometry.h:51
double sq_crd
Definition geometry.h:56
double sin
Definition geometry.h:33
double cos
Definition geometry.h:33
struct yac_circle::@8::@10 lat
struct yac_circle::@8::@11 p
double z
z-coordinate of the latitude circle (sin(latitude))
Definition geometry.h:78
enum yac_circle_type type
Definition geometry.h:69
struct yac_circle::@8::@9 gc
union yac_circle::@8 data
struct yac_circle::@8::@9 lon
int north_is_out
Definition geometry.h:76
double norm_vector[3]
Definition geometry.h:73
double r
Definition geometry.h:82
double vec[3]
Definition geometry.h:85
@ error
Definition test_cxc.c:17
double(* p)(double lon, double lat)
Definition toy_scrip.c:119