YAC 3.7.1
Yet Another Coupler
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 "basic_grid.h"
19#include "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
289// computation of the determinant of a 2x2 matrix using Kahan summation
290static inline double det2_kahan(double a, double b, double c, double d) {
291 double bc = b*c;
292 double e_bc = fma(b,c,-bc); // the rounding error of the multiplication
293 double det = fma(a,d,-bc);
294 return det + e_bc;
295}
296
297static inline void crossproduct_kahan (
298 double const a[], double const b[], double cross[]) {
299
300 /* crossproduct in Cartesian coordinates */
301
302 cross[0] = det2_kahan(a[1], a[2], b[1], b[2]);
303 cross[1] = det2_kahan(a[2], a[0], b[2], b[0]);
304 cross[2] = det2_kahan(a[0], a[1], b[0], b[1]);
305
306}
307
312static inline void crossproduct_d (
313 const double a[], const double b[], double cross[]) {
314
315/* crossproduct in Cartesian coordinates */
316
317 cross[0] = a[1] * b[2] - a[2] * b[1];
318 cross[1] = a[2] * b[0] - a[0] * b[2];
319 cross[2] = a[0] * b[1] - a[1] * b[0];
320}
321
329static inline double get_vector_angle(double const a[3], double const b[3]) {
330
331 double dot_product = a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
332
333 // the acos most accurate in the range [-M_SQRT1_2;M_SQRT1_2]
334 if (fabs(dot_product) > M_SQRT1_2) {
335
336 double cross_ab[3];
337
338 crossproduct_kahan(a, b, cross_ab);
339
340 double asin_tmp = asin(sqrt(cross_ab[0]*cross_ab[0]+
341 cross_ab[1]*cross_ab[1]+
342 cross_ab[2]*cross_ab[2]));
343
344 if (dot_product > 0.0) // if the angle is smaller than (PI / 2)
345 return MAX(asin_tmp,0.0);
346 else
347 return MIN(M_PI - asin_tmp, M_PI);
348
349 } else {
350
351 return acos(dot_product);
352 }
353
354 /*
355 // this solution is simpler, but has a much worse performance
356 double cross[3], dot, cross_abs;
357
358 crossproduct_kahan(a, b, cross);
359 dot = a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
360 cross_abs = sqrt(cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]);
361
362 return fabs(atan2(cross_abs, dot));
363 */
364}
365
366static inline struct sin_cos_angle sin_cos_angle_new(double sin, double cos) {
367
368 struct sin_cos_angle angle;
369
370 angle.sin = clamp_abs_one(sin);
371 angle.cos = clamp_abs_one(cos);
372
373 return angle;
374}
375
377 double const a[3], double const b[3]) {
378
379 double cross_ab[3];
380 crossproduct_kahan(a, b, cross_ab);
381
382 return sin_cos_angle_new(sqrt(cross_ab[0]*cross_ab[0] +
383 cross_ab[1]*cross_ab[1] +
384 cross_ab[2]*cross_ab[2]),
385 a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
386}
387
388// works for angles in the range [0;2*PI[
389static inline int compare_angles(
390 struct sin_cos_angle a, struct sin_cos_angle b) {
391
392 // there are 5 sections:
393 // 0: 0 <= angle < PI/4
394 // 1: PI/4 <= angle < 3*PI/4
395 // 2: 3*PI/4 <= angle < 5*PI/4
396 // 3: 5*PI/4 <= angle < 7*PI/4
397 // 4: 7*PI/4 <= angle < 2*PI
398 int t_a = fabs(a.cos) <= M_SQRT1_2;
399 int t_b = fabs(b.cos) <= M_SQRT1_2;
400 int a_section = t_a | ((((a.sin < 0.0) & t_a) |
401 ((a.cos < 0.0) & (fabs(a.sin) < M_SQRT1_2))) << 1);
402 int b_section = t_b | ((((b.sin < 0.0) & t_b) |
403 ((b.cos < 0.0) & (fabs(b.sin) < M_SQRT1_2))) << 1);
404 // if current section is 0, then it could be actually section 4
405 if (!a_section) a_section = (a.sin < 0.0) << 2;
406 if (!b_section) b_section = (b.sin < 0.0) << 2;
407
408 if (a_section != b_section)
409 return (a_section > b_section) - (a_section < b_section);
410
411 int ret;
412
413 switch (a_section) {
414 case(0):
415 case(4):
416 default:
417 ret = (b.sin < a.sin + yac_angle_low_tol) -
418 (a.sin < b.sin + yac_angle_low_tol);
419 if (ret) return ret;
420 else {
421 ret = (a.cos < b.cos + yac_angle_low_tol) -
422 (b.cos < a.cos + yac_angle_low_tol);
423 if (a.sin >= 0.0) return ret;
424 else return -ret;
425 }
426 case(1):
427 ret = (a.cos < b.cos + yac_angle_low_tol) -
428 (b.cos < a.cos + yac_angle_low_tol);
429 if (ret) return ret;
430 else {
431 ret = (b.sin < a.sin + yac_angle_low_tol) -
432 (a.sin < b.sin + yac_angle_low_tol);
433 if (a.cos >= 0.0) return ret;
434 else return -ret;
435 }
436 case(2):
437 ret = (a.sin < b.sin + yac_angle_low_tol) -
438 (b.sin < a.sin + yac_angle_low_tol);
439 if (ret) return ret;
440 else {
441 ret = (a.cos < b.cos + yac_angle_low_tol) -
442 (b.cos < a.cos + yac_angle_low_tol);
443 if (a.sin >= 0.0) return ret;
444 else return -ret;
445 }
446 case(3):
447 ret = (b.cos < a.cos + yac_angle_low_tol) -
448 (a.cos < b.cos + yac_angle_low_tol);
449 if (ret) return ret;
450 else {
451 ret = (a.sin < b.sin + yac_angle_low_tol) -
452 (b.sin < a.sin + yac_angle_low_tol);
453 if (a.cos <= 0.0) return ret;
454 else return -ret;
455 }
456 }
457}
458
466static inline double sin_cos_angle_to_dble(struct sin_cos_angle angle) {
467
468 int t = fabs(angle.cos) <= M_SQRT1_2;
469 int section = t | ((((angle.sin < 0.0) & t) |
470 ((angle.cos < 0.0) & (fabs(angle.sin) < M_SQRT1_2))) << 1);
471 if (!section) section = (angle.sin < 0.0) << 2;
472
473 switch (section) {
474 default:
475 case(0): return 0.0 * M_SQRT1_2 + angle.sin;
476 case(1): return 2.0 * M_SQRT1_2 - angle.cos;
477 case(2): return 4.0 * M_SQRT1_2 - angle.sin;
478 case(3): return 6.0 * M_SQRT1_2 + angle.cos;
479 case(4): return 8.0 * M_SQRT1_2 + angle.sin;
480 }
481}
482
486 struct sin_cos_angle a, struct sin_cos_angle b) {
487
488 return sin_cos_angle_new(a.sin * b.cos + a.cos * b.sin,
489 a.cos * b.cos - a.sin * b.sin);
490}
491
495static inline int sum_angles(
496 struct sin_cos_angle a, struct sin_cos_angle b,
497 struct sin_cos_angle * restrict sum) {
498
499 struct sin_cos_angle sum_ = sum_angles_no_check(a, b);
500
501 *sum = sum_;
502
503 // if a or b is smaller than the result
504 return (compare_angles(sum_, a) < 0) || (compare_angles(sum_, b) < 0);
505}
506
510 struct sin_cos_angle a, struct sin_cos_angle b) {
511
512 return sin_cos_angle_new(a.sin * b.cos - a.cos * b.sin,
513 a.cos * b.cos + a.sin * b.sin);
514}
515
519static inline int sub_angles(
520 struct sin_cos_angle a, struct sin_cos_angle b,
521 struct sin_cos_angle * restrict sub) {
522
523 int compare_result = compare_angles(a, b);
524
525 // return sin=0.0 and cos=1.0 if the angles are equal to each other,
526 // i.e. compare_result == 0
527 *sub = compare_result ? sub_angles_no_check(a, b) : SIN_COS_ZERO;
528
529 return compare_result < 0;
530}
531
533static inline double compute_angle(struct sin_cos_angle angle) {
534
535 // the acos and asin are most accurate in the range [-M_SQRT1_2;M_SQRT1_2]
536 if (angle.cos > M_SQRT1_2) {
537
538 double angle_ = asin(angle.sin);
539
540 if (angle_ < 0.0) angle_ += 2.0 * M_PI;
541 return angle_;
542
543 } else if (angle.cos > - M_SQRT1_2) {
544
545 double angle_ = acos(angle.cos);
546
547 if (angle.sin > 0.0) return angle_;
548 else return 2.0 * M_PI - angle_;
549
550 } else {
551 return M_PI - asin(angle.sin);
552 }
553}
554
561static inline struct sin_cos_angle half_angle(struct sin_cos_angle angle) {
562
563 double x = (1.0 + fabs(angle.cos));
564
565 double scale = 1.0 / sqrt(x * x + angle.sin * angle.sin);
566
567 // first or fourth quadrant
568 if (angle.cos >= 0) {
569 scale = copysign(scale, angle.sin);
570 return sin_cos_angle_new(angle.sin * scale, x * scale);
571
572 // second and third quadrant
573 } else return sin_cos_angle_new(x * scale, angle.sin * scale);
574}
575
578static inline struct sin_cos_angle quarter_angle(struct sin_cos_angle angle) {
579
580 double tan = fabs(angle.sin / (1.0 + fabs(angle.cos)));
581 double one_plus_sq_tan = 1.0 + tan * tan;
582 double sqrt_one_plus_sq_tan = sqrt(one_plus_sq_tan);
583
584 double a = 1.0;
585 double b = tan;
586
587 // second and third quadrant
588 if (angle.cos < 0.0) {
589 a = tan;
590 b = 1.0;
591 }
592
593 double scale = M_SQRT1_2 / sqrt(one_plus_sq_tan + a * sqrt_one_plus_sq_tan);
594 double x = b * scale;
595 double y = (a + sqrt_one_plus_sq_tan) * scale;
596
597 // first and second quadrant
598 if (angle.sin >= 0.0) return sin_cos_angle_new(x, y);
599 // third and fourth quadrant
600 else return sin_cos_angle_new(y, x);
601}
602
609static inline int points_are_identically(double const * a, double const * b) {
610
611 // for small angles the Euclidean distance is nearly identical to
612 // great circle distance between vectors a and b
613 return sq_len_diff_vec(a, b) <= yac_sq_angle_tol;
614}
615
623static inline int compare_coords(double const * a, double const * b) {
624
625 double dot_product = a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
626
627 // if the angle is smaller than ~0.81 degree
628 // (in this range the acos is still rather accurate)
629 if (dot_product > 0.9999) { // (acos(0.9999) = ~0.81 degree)
630
631 // both points are close to each other -> use cross product for higher
632 // accuracy
633
634 double cross_ab[3];
635 crossproduct_kahan(a, b, cross_ab);
636
637 // for very small angles: asin(alpha) = ~alpha (alpha in rad)
638 if (sqrt(cross_ab[0]*cross_ab[0] +
639 cross_ab[1]*cross_ab[1] +
640 cross_ab[2]*cross_ab[2]) < yac_angle_tol) return 0;
641 }
642
643 int ret;
644 if ((ret = (a[0] > b[0]) - (a[0] < b[0]))) return ret;
645 if ((ret = (a[1] > b[1]) - (a[1] < b[1]))) return ret;
646 return (a[2] > b[2]) - (a[2] < b[2]);
647}
648
650static inline void normalise_vector(double v[]) {
651
652 double norm = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
653
654 v[0] *= norm;
655 v[1] *= norm;
656 v[2] *= norm;
657}
658
665static inline void rotate_vector2(
666 double axis[], struct sin_cos_angle angle, double v_in[], double v_out[]) {
667
668 // using Rodrigues' rotation formula
669 // v_out = v_in * cos(angle) +
670 // (axis x v_in) * sin(angle) +
671 // axis * (axis * v_in) * (1 - cos(angle))
672
673 double cross_axis_v_in[3];
674 crossproduct_d(axis, v_in, cross_axis_v_in);
675
676 double dot_axis_v_in = axis[0]*v_in[0] + axis[1]*v_in[1] + axis[2]*v_in[2];
677 double temp = dot_axis_v_in * (1.0 - angle.cos);
678
679 v_out[0] =
680 v_in[0] * angle.cos + cross_axis_v_in[0] * angle.sin + axis[0] * temp;
681 v_out[1] =
682 v_in[1] * angle.cos + cross_axis_v_in[1] * angle.sin + axis[1] * temp;
683 v_out[2] =
684 v_in[2] * angle.cos + cross_axis_v_in[2] * angle.sin + axis[2] * temp;
685}
686
693static inline void rotate_vector(
694 double axis[], double angle, double v_in[], double v_out[]) {
695
696 double sin_angle = sin(angle);
697 double cos_angle = cos(angle);
699 axis, sin_cos_angle_new(sin_angle, cos_angle), v_in, v_out);
700}
701
716 struct yac_grid_cell cell, size_t start_corner, struct yac_grid_cell * triangles);
717
731 size_t const * corner_indices, size_t num_corners, size_t start_corner,
732 size_t (*triangle_indices)[3]);
733
745 double * vertices, size_t num_vertices, double triangle[][3],
746 size_t num_tests);
747
749 struct yac_circle a, struct yac_circle b, double p[3], double q[3]);
750
752 double p[3], double const a[3], double const b[3],
753 enum yac_circle_type circle_type);
754
755#endif // GEOMETRY_H
756
static struct sin_cos_angle get_vector_angle_2(double const a[3], double const b[3])
Definition geometry.h:376
static int compare_coords(double const *a, double const *b)
Definition geometry.h:623
static double compute_sq_crd(struct sin_cos_angle angle)
Definition geometry.h:185
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
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:290
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:609
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 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:312
static struct sin_cos_angle sum_angles_no_check(struct sin_cos_angle a, struct sin_cos_angle b)
Definition geometry.h:485
static double sin_cos_angle_to_dble(struct sin_cos_angle angle)
Definition geometry.h:466
static void crossproduct_kahan(double const a[], double const b[], double cross[])
Definition geometry.h:297
static void rotate_vector(double axis[], double angle, double v_in[], double v_out[])
Definition geometry.h:693
static struct sin_cos_angle quarter_angle(struct sin_cos_angle angle)
Definition geometry.h:578
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:665
#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
#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:389
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:519
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:509
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:533
#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:650
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:329
static int sum_angles(struct sin_cos_angle a, struct sin_cos_angle b, struct sin_cos_angle *restrict sum)
Definition geometry.h:495
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:366
static struct sin_cos_angle half_angle(struct sin_cos_angle angle)
Definition geometry.h:561
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
double z
Definition geometry.h:77
struct yac_circle::@9::@12 p
enum yac_circle_type type
Definition geometry.h:69
struct yac_circle::@9::@10 gc
struct yac_circle::@9::@11 lat
union yac_circle::@9 data
int north_is_out
Definition geometry.h:76
double norm_vector[3]
Definition geometry.h:73
struct yac_circle::@9::@10 lon
double vec[3]
Definition geometry.h:80
#define MIN(a, b)
Definition toy_common.h:29
double(* p)(double lon, double lat)
Definition toy_scrip.c:119
#define MAX(a, b)