YAC 3.15.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 {
77 double z;
78 } lat;
79 struct {
80 double vec[3];
81 } p;
83};
84
91int yac_point_in_cell (double point_coords[3], struct yac_grid_cell cell);
92
100int yac_point_in_cell2 (double point_coords[3], struct yac_grid_cell cell,
101 struct bounding_circle bnd_circle);
102
110static inline double get_angle (double a_lon, double b_lon) {
111 double diff = a_lon - b_lon;
112#if defined(CDO)
113 return diff - lround(diff / (2.0 * M_PI)) * (2.0 * M_PI);
114#else
115 return diff - round(diff / (2.0 * M_PI)) * (2.0 * M_PI);
116#endif
117}
118
126static inline double get_angle_deg (double a_lon, double b_lon) {
127 double diff = a_lon - b_lon;
128#if defined(CDO)
129 return diff - lround(diff / 360.0) * (360.0);
130#else
131 return diff - round(diff / 360.0) * (360.0);
132#endif
133}
134
158 enum yac_edge_type edge_type_a, double const a[3], double const b[3],
159 enum yac_edge_type edge_type_b, double const c[3], double const d[3],
160 double p[3], double q[3]);
161
168 struct bounding_circle * bnd_circle);
169
176int yac_extents_overlap(struct bounding_circle * extent_a,
177 struct bounding_circle * extent_b);
178
180static inline double sq_len_diff_vec(double const a[3], double const b[3]) {
181 double ab[3] = {a[0]-b[0], a[1]-b[1], a[2]-b[2]};
182 return ab[0] * ab[0] + ab[1] * ab[1] + ab[2] * ab[2];
183}
184
185static inline double compute_sq_crd(struct sin_cos_angle angle) {
186
187 double temp = 1.0 - angle.cos;
188 return temp * temp + angle.sin * angle.sin;
189}
190
198 double point_vector[3], struct bounding_circle * bnd_circle) {
199
200 if (bnd_circle->sq_crd == DBL_MAX)
201 bnd_circle->sq_crd = compute_sq_crd(bnd_circle->inc_angle);
202
203 return
204 bnd_circle->sq_crd >=
205 sq_len_diff_vec(bnd_circle->base_vector, point_vector);
206}
207
208static inline double clamp_abs_one(double val) {
209 return val > -1.0 ? (val < 1.0 ? val : 1.0) : -1.0;
210}
211
220static inline void compute_sin_cos(
221 double angle, double * sin_value, double * cos_value) {
222
223 double abs_angle = fabs(angle);
224 if (abs_angle < yac_angle_low_tol) {
225 *sin_value = 0.0;
226 *cos_value = 1.0;
227 } else if (fabs(abs_angle - M_PI) < yac_angle_low_tol) {
228 *sin_value = 0.0;
229 *cos_value = -1.0;
230 } else if (fabs(abs_angle - M_PI_2) < yac_angle_low_tol) {
231 *sin_value = copysign(1.0, angle);
232 *cos_value = 0.0;
233 } else {
234 *sin_value = clamp_abs_one(sin(angle));
235 *cos_value = clamp_abs_one(cos(angle));
236 }
237}
238
249static inline void LLtoXYZ(double lon, double lat, double p_out[]) {
250
251 while (lon < -M_PI) lon += 2.0 * M_PI;
252 while (lon >= M_PI) lon -= 2.0 * M_PI;
253
254 double sin_lon, cos_lon, sin_lat, cos_lat;
255 compute_sin_cos(lon, &sin_lon, &cos_lon);
256 compute_sin_cos(lat, &sin_lat, &cos_lat);
257
258 p_out[0] = cos_lat * cos_lon;
259 p_out[1] = cos_lat * sin_lon;
260 p_out[2] = sin_lat;
261}
262
269static inline void LLtoXYZ_deg(double lon, double lat, double p_out[]) {
270 LLtoXYZ(lon*YAC_RAD, lat*YAC_RAD, p_out);
271}
272
283static inline void XYZtoLL (double const p_in[], double * lon, double * lat) {
284
285 *lon = atan2(p_in[1] , p_in[0]);
286 *lat = M_PI_2 - acos(p_in[2]);
287}
288
300static inline void product_eft(
301 double a, double b, double * restrict product, double * restrict error) {
302 *product = a * b;
303 *error = fma(a, b, -*product);
304}
305
317static inline void sum_eft(
318 double a, double b, double * restrict sum, double * restrict error) {
319 *sum = a + b;
320 double temp = *sum - a;
321 *error = (a - (*sum - temp)) + (b - temp);
322}
323
334static inline void accu_eft(
335 double a, double * restrict accu, double * restrict error) {
336 double a_ = a - *error;
337 double temp = *accu + a_;
338 *error = (temp - *accu) - a_;
339 *accu = temp;
340}
341
357static inline void accu_product_eft(
358 double a, double b, double * restrict accu, double * restrict accu_error) {
359
360 // compute product with error
361 double product, product_error;
362 product_eft(a, b, &product, &product_error);
363
364 // compensated accumulation
365 accu_eft(product, accu, accu_error);
366 *accu_error += product_error;
367}
368
382static inline void det2_error(
383 double a, double b, double c, double d,
384 double * restrict det, double * restrict det_error) {
385
386 double ad, ad_err;
387 product_eft(a, d, &ad, &ad_err);
388
389 double bc, bc_err;
390 product_eft(b, -c, &bc, &bc_err);
391
392 double temp_err;
393 sum_eft(ad, bc, det, &temp_err);
394 *det_error = ad_err + (temp_err + bc_err);
395}
396
397// computation of the determinant of a 2x2 matrix using Kahan summation
398static inline double det2_kahan(double a, double b, double c, double d) {
399 double bc = b*c;
400 double e_bc = fma(b,c,-bc); // the rounding error of the multiplication
401 double det = fma(a,d,-bc);
402 return det + e_bc;
403}
404
405static inline void crossproduct_kahan (
406 double const a[], double const b[], double cross[]) {
407
408 /* crossproduct in Cartesian coordinates */
409
410 cross[0] = det2_kahan(a[1], a[2], b[1], b[2]);
411 cross[1] = det2_kahan(a[2], a[0], b[2], b[0]);
412 cross[2] = det2_kahan(a[0], a[1], b[0], b[1]);
413
414}
415
420static inline void crossproduct_d (
421 const double a[], const double b[], double cross[]) {
422
423/* crossproduct in Cartesian coordinates */
424
425 cross[0] = a[1] * b[2] - a[2] * b[1];
426 cross[1] = a[2] * b[0] - a[0] * b[2];
427 cross[2] = a[0] * b[1] - a[1] * b[0];
428}
429
448static inline double get_vector_angle(double const a[3], double const b[3]) {
449
450 double sub[3] = {a[0] - b[0], a[1] - b[1], a[2] - b[2]};
451 double add[3] = {a[0] + b[0], a[1] + b[1], a[2] + b[2]};
452 double sq_sub = sub[0] * sub[0] + sub[1] * sub[1] + sub[2] * sub[2];
453 double sq_add = add[0] * add[0] + add[1] * add[1] + add[2] * add[2];
454
455 // angle = 2 * atan(|a-b|/|a+b|)
456 return (fabs(sq_add) > 1e-12)?(2.0 * atan(sqrt(sq_sub/sq_add))):M_PI;
457}
458
459static inline struct sin_cos_angle sin_cos_angle_new(double sin, double cos) {
460
461 struct sin_cos_angle angle;
462
463 angle.sin = clamp_abs_one(sin);
464 angle.cos = clamp_abs_one(cos);
465
466 return angle;
467}
468
470 double const a[3], double const b[3]) {
471
472 double cross_ab[3];
473 crossproduct_kahan(a, b, cross_ab);
474
475 return sin_cos_angle_new(sqrt(cross_ab[0]*cross_ab[0] +
476 cross_ab[1]*cross_ab[1] +
477 cross_ab[2]*cross_ab[2]),
478 a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
479}
480
481// works for angles in the range [0;2*PI[
482static inline int compare_angles(
483 struct sin_cos_angle a, struct sin_cos_angle b) {
484
485 // there are 5 sections:
486 // 0: 0 <= angle < PI/4
487 // 1: PI/4 <= angle < 3*PI/4
488 // 2: 3*PI/4 <= angle < 5*PI/4
489 // 3: 5*PI/4 <= angle < 7*PI/4
490 // 4: 7*PI/4 <= angle < 2*PI
491 int t_a = fabs(a.cos) <= M_SQRT1_2;
492 int t_b = fabs(b.cos) <= M_SQRT1_2;
493 int a_section = t_a | ((((a.sin < 0.0) & t_a) |
494 ((a.cos < 0.0) & (fabs(a.sin) < M_SQRT1_2))) << 1);
495 int b_section = t_b | ((((b.sin < 0.0) & t_b) |
496 ((b.cos < 0.0) & (fabs(b.sin) < M_SQRT1_2))) << 1);
497 // if current section is 0, then it could be actually section 4
498 if (!a_section) a_section = (a.sin < 0.0) << 2;
499 if (!b_section) b_section = (b.sin < 0.0) << 2;
500
501 if (a_section != b_section)
502 return (a_section > b_section) - (a_section < b_section);
503
504 int ret;
505
506 switch (a_section) {
507 case(0):
508 case(4):
509 default:
510 ret = (b.sin < a.sin + yac_angle_low_tol) -
511 (a.sin < b.sin + yac_angle_low_tol);
512 if (ret) return ret;
513 else {
514 ret = (a.cos < b.cos + yac_angle_low_tol) -
515 (b.cos < a.cos + yac_angle_low_tol);
516 if (a.sin >= 0.0) return ret;
517 else return -ret;
518 }
519 case(1):
520 ret = (a.cos < b.cos + yac_angle_low_tol) -
521 (b.cos < a.cos + yac_angle_low_tol);
522 if (ret) return ret;
523 else {
524 ret = (b.sin < a.sin + yac_angle_low_tol) -
525 (a.sin < b.sin + yac_angle_low_tol);
526 if (a.cos >= 0.0) return ret;
527 else return -ret;
528 }
529 case(2):
530 ret = (a.sin < b.sin + yac_angle_low_tol) -
531 (b.sin < a.sin + yac_angle_low_tol);
532 if (ret) return ret;
533 else {
534 ret = (a.cos < b.cos + yac_angle_low_tol) -
535 (b.cos < a.cos + yac_angle_low_tol);
536 if (a.sin >= 0.0) return ret;
537 else return -ret;
538 }
539 case(3):
540 ret = (b.cos < a.cos + yac_angle_low_tol) -
541 (a.cos < b.cos + yac_angle_low_tol);
542 if (ret) return ret;
543 else {
544 ret = (a.sin < b.sin + yac_angle_low_tol) -
545 (b.sin < a.sin + yac_angle_low_tol);
546 if (a.cos <= 0.0) return ret;
547 else return -ret;
548 }
549 }
550}
551
559static inline double sin_cos_angle_to_dble(struct sin_cos_angle angle) {
560
561 int t = fabs(angle.cos) <= M_SQRT1_2;
562 int section = t | ((((angle.sin < 0.0) & t) |
563 ((angle.cos < 0.0) & (fabs(angle.sin) < M_SQRT1_2))) << 1);
564 if (!section) section = (angle.sin < 0.0) << 2;
565
566 switch (section) {
567 default:
568 case(0): return 0.0 * M_SQRT1_2 + angle.sin;
569 case(1): return 2.0 * M_SQRT1_2 - angle.cos;
570 case(2): return 4.0 * M_SQRT1_2 - angle.sin;
571 case(3): return 6.0 * M_SQRT1_2 + angle.cos;
572 case(4): return 8.0 * M_SQRT1_2 + angle.sin;
573 }
574}
575
579 struct sin_cos_angle a, struct sin_cos_angle b) {
580
581 return sin_cos_angle_new(a.sin * b.cos + a.cos * b.sin,
582 a.cos * b.cos - a.sin * b.sin);
583}
584
588static inline int sum_angles(
589 struct sin_cos_angle a, struct sin_cos_angle b,
590 struct sin_cos_angle * restrict sum) {
591
592 struct sin_cos_angle sum_ = sum_angles_no_check(a, b);
593
594 *sum = sum_;
595
596 // if a or b is smaller than the result
597 return (compare_angles(sum_, a) < 0) || (compare_angles(sum_, b) < 0);
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 sub_angles(
613 struct sin_cos_angle a, struct sin_cos_angle b,
614 struct sin_cos_angle * restrict sub) {
615
616 int compare_result = compare_angles(a, b);
617
618 // return sin=0.0 and cos=1.0 if the angles are equal to each other,
619 // i.e. compare_result == 0
620 *sub = compare_result ? sub_angles_no_check(a, b) : SIN_COS_ZERO;
621
622 return compare_result < 0;
623}
624
626static inline double compute_angle(struct sin_cos_angle angle) {
627
628 // the acos and asin are most accurate in the range [-M_SQRT1_2;M_SQRT1_2]
629 if (angle.cos > M_SQRT1_2) {
630
631 double angle_ = asin(angle.sin);
632
633 if (angle_ < 0.0) angle_ += 2.0 * M_PI;
634 return angle_;
635
636 } else if (angle.cos > - M_SQRT1_2) {
637
638 double angle_ = acos(angle.cos);
639
640 if (angle.sin > 0.0) return angle_;
641 else return 2.0 * M_PI - angle_;
642
643 } else {
644 return M_PI - asin(angle.sin);
645 }
646}
647
654static inline struct sin_cos_angle half_angle(struct sin_cos_angle angle) {
655
656 double x = (1.0 + fabs(angle.cos));
657
658 double scale = 1.0 / sqrt(x * x + angle.sin * angle.sin);
659
660 // first or fourth quadrant
661 if (angle.cos >= 0) {
662 scale = copysign(scale, angle.sin);
663 return sin_cos_angle_new(angle.sin * scale, x * scale);
664
665 // second and third quadrant
666 } else return sin_cos_angle_new(x * scale, angle.sin * scale);
667}
668
671static inline struct sin_cos_angle quarter_angle(struct sin_cos_angle angle) {
672
673 double tan = fabs(angle.sin / (1.0 + fabs(angle.cos)));
674 double one_plus_sq_tan = 1.0 + tan * tan;
675 double sqrt_one_plus_sq_tan = sqrt(one_plus_sq_tan);
676
677 double a = 1.0;
678 double b = tan;
679
680 // second and third quadrant
681 if (angle.cos < 0.0) {
682 a = tan;
683 b = 1.0;
684 }
685
686 double scale = M_SQRT1_2 / sqrt(one_plus_sq_tan + a * sqrt_one_plus_sq_tan);
687 double x = b * scale;
688 double y = (a + sqrt_one_plus_sq_tan) * scale;
689
690 // first and second quadrant
691 if (angle.sin >= 0.0) return sin_cos_angle_new(x, y);
692 // third and fourth quadrant
693 else return sin_cos_angle_new(y, x);
694}
695
702static inline int points_are_identically(double const * a, double const * b) {
703
704 // for small angles the Euclidean distance is nearly identical to
705 // great circle distance between vectors a and b
706 return sq_len_diff_vec(a, b) <= yac_sq_angle_tol;
707}
708
716static inline int compare_coords(double const * a, double const * b) {
717
718 // Check if points are identical using squared chord distance
719 if (points_are_identically(a, b)) return 0;
720
721 int ret;
722 if ((ret = (a[0] > b[0]) - (a[0] < b[0]))) return ret;
723 if ((ret = (a[1] > b[1]) - (a[1] < b[1]))) return ret;
724 return (a[2] > b[2]) - (a[2] < b[2]);
725}
726
728static inline void normalise_vector(double v[]) {
729
730 double norm = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
731
732 v[0] *= norm;
733 v[1] *= norm;
734 v[2] *= norm;
735}
736
743static inline void rotate_vector2(
744 double axis[], struct sin_cos_angle angle, double v_in[], double v_out[]) {
745
746 // using Rodrigues' rotation formula
747 // v_out = v_in * cos(angle) +
748 // (axis x v_in) * sin(angle) +
749 // axis * (axis * v_in) * (1 - cos(angle))
750
751 double cross_axis_v_in[3];
752 crossproduct_d(axis, v_in, cross_axis_v_in);
753
754 double dot_axis_v_in = axis[0]*v_in[0] + axis[1]*v_in[1] + axis[2]*v_in[2];
755 double temp = dot_axis_v_in * (1.0 - angle.cos);
756
757 v_out[0] =
758 v_in[0] * angle.cos + cross_axis_v_in[0] * angle.sin + axis[0] * temp;
759 v_out[1] =
760 v_in[1] * angle.cos + cross_axis_v_in[1] * angle.sin + axis[1] * temp;
761 v_out[2] =
762 v_in[2] * angle.cos + cross_axis_v_in[2] * angle.sin + axis[2] * temp;
763}
764
771static inline void rotate_vector(
772 double axis[], double angle, double v_in[], double v_out[]) {
773
774 double sin_angle = sin(angle);
775 double cos_angle = cos(angle);
777 axis, sin_cos_angle_new(sin_angle, cos_angle), v_in, v_out);
778}
779
794 struct yac_grid_cell cell, size_t start_corner, struct yac_grid_cell * triangles);
795
809 size_t const * corner_indices, size_t num_corners, size_t start_corner,
810 size_t (*triangle_indices)[3]);
811
823 double * vertices, size_t num_vertices, double triangle[][3],
824 size_t num_tests);
825
827 struct yac_circle a, struct yac_circle b, double p[3], double q[3]);
828
830 double p[3], double const a[3], double const b[3],
831 enum yac_circle_type circle_type);
832
833#endif // GEOMETRY_H
834
double scale
static struct sin_cos_angle get_vector_angle_2(double const a[3], double const b[3])
Definition geometry.h:469
static int compare_coords(double const *a, double const *b)
Definition geometry.h:716
static double compute_sq_crd(struct sin_cos_angle angle)
Definition geometry.h:185
static void product_eft(double a, double b, double *restrict product, double *restrict error)
Definition geometry.h:300
static const struct sin_cos_angle SIN_COS_LOW_TOL
Definition geometry.h:38
static double clamp_abs_one(double val)
Definition geometry.h:208
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:382
int yac_circle_intersect(struct yac_circle a, struct yac_circle b, double p[3], double q[3])
static double det2_kahan(double a, double b, double c, double d)
Definition geometry.h:398
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:702
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:220
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:317
static int yac_point_in_bounding_circle_vec(double point_vector[3], struct bounding_circle *bnd_circle)
Definition geometry.h:197
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:180
static void crossproduct_d(const double a[], const double b[], double cross[])
Definition geometry.h:420
static struct sin_cos_angle sum_angles_no_check(struct sin_cos_angle a, struct sin_cos_angle b)
Definition geometry.h:578
static double sin_cos_angle_to_dble(struct sin_cos_angle angle)
Definition geometry.h:559
static void crossproduct_kahan(double const a[], double const b[], double cross[])
Definition geometry.h:405
static void rotate_vector(double axis[], double angle, double v_in[], double v_out[])
Definition geometry.h:771
static struct sin_cos_angle quarter_angle(struct sin_cos_angle angle)
Definition geometry.h:671
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:743
#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:357
#define YAC_RAD
Definition geometry.h:22
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
Definition geometry.h:269
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:482
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:612
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:602
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:626
#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:728
static double get_angle(double a_lon, double b_lon)
Definition geometry.h:110
static void LLtoXYZ(double lon, double lat, double p_out[])
Definition geometry.h:249
static double get_vector_angle(double const a[3], double const b[3])
Definition geometry.h:448
static int sum_angles(struct sin_cos_angle a, struct sin_cos_angle b, struct sin_cos_angle *restrict sum)
Definition geometry.h:588
static double get_angle_deg(double a_lon, double b_lon)
Definition geometry.h:126
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:459
static void accu_eft(double a, double *restrict accu, double *restrict error)
Definition geometry.h:334
static struct sin_cos_angle half_angle(struct sin_cos_angle angle)
Definition geometry.h:654
static void XYZtoLL(double const p_in[], double *lon, double *lat)
Definition geometry.h:283
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
Definition geometry.h:77
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 vec[3]
Definition geometry.h:80
@ error
Definition test_cxc.c:17
double(* p)(double lon, double lat)
Definition toy_scrip.c:119