22 double deg_lat_bounds[2],
24 unsigned num_ref_cells);
28static double utest_get_intersection(
31 double intersection[3], intersection_lon, intersection_lat;
36 points[1][0], lat, intersection))
38 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
39 return intersection_lon /
YAC_RAD;
57 (
double[4]){-5,5,5,-5},
59 (
double[2]){10, 20}, NULL, 0);
64 (
double[4]){-5,5,5,-5},
66 (
double[2]){10, 20}, NULL, 0);
71 (
double[4]){-5,5,5,-5},
73 (
double[2]){10, 20}, NULL, 0);
78 (
double[4]){-5,5,5,-5},
80 (
double[2]){10, 20}, NULL, 0);
85 (
double[4]){-5,5,5,-5},
87 (
double[2]){10, 20}, NULL, 0);
92 (
double[4]){-5,5,5,-5},
94 (
double[2]){80, 90}, NULL, 0);
99 (
double[4]){-5,5,5,-5},
101 (
double[2]){0, 0}, NULL, 0);
106 (
double[4]){-5,5,5,-5},
108 (
double[2]){0, 0}, NULL, 0);
113 (
double[4]){-5,5,5,-5},
115 (
double[2]){0, 0}, NULL, 0);
120 (
double[4]){-5,5,5,-5},
125 (
double[4]){-5,5,5,-5},
131 (
double[4]){40,45,45,40},
136 (
double[4]){40,45,45,40},
142 (
double[4]){40,45,45,40},
147 (
double[4]){40,45,45,40},
153 (
double[4]){40,45,45,40},
158 (
double[4]){40,45,45,40},
164 (
double[4]){40,45,45,40},
169 (
double[4]){40,45,45,40},
175 (
double[4]){40,45,45,40},
177 (
double[2]){90, 80}, NULL, 0);
182 (
double[4]){40,45,45,40},
187 (
double[4]){40,45,45,40},
193 (
double[4]){40,45,45,40},
198 (
double[4]){40,45,45,40},
204 (
double[4]){40,45,45,40},
209 (
double[4]){40,45,45,40},
215 (
double[4]){40,45,45,40},
220 (
double[4]){40,45,45,40},
226 (
double[4]){40,45,45,40},
231 (
double[4]){40,45,45,40},
237 (
double[4]){40,45,45,40},
239 (
double[2]){-90, -80}, NULL, 0);
244 (
double[4]){40,45,45,40},
246 (
double[2]){-90, -80},
249 (
double[4]){40,45,45,40},
255 (
double[4]){40,45,45,40},
257 (
double[2]){-90, -80},
260 (
double[4]){40,45,45,40},
266 (
double[4]){40,45,45,40},
268 (
double[2]){-90, -80},
271 (
double[4]){40,45,45,40},
277 (
double[4]){40,45,45,40},
279 (
double[2]){-90, -80},
282 (
double[4]){40,45,45,40},
288 (
double[4]){40,45,45,40},
290 (
double[2]){-90, -80},
293 (
double[4]){40,45,45,40},
300 (
double[4]){0,5,5,0},
302 (
double[2]){89.9, 80},
305 (
double[4]){0,5,5,0},
311 (
double[3]){10,20,15},
312 (
double[3]){30,30,40},
gc_edges, 3),
317 utest_get_intersection(
319 (
double[2][2]){{15, 40}, {10, 30}}, 35),
320 utest_get_intersection(
322 (
double[2][2]){{15, 40}, {20, 30}}, 35)},
323 (
double[]){40,35,35},
330 (
double[3]){10,20,15},
331 (
double[3]){30,30,40},
gc_edges, 3),
336 utest_get_intersection(
338 (
double[2][2]){{15, 40}, {10, 30}}, 35),
339 utest_get_intersection(
341 (
double[2][2]){{15, 40}, {20, 30}}, 35)},
342 (
double[]){30,30,35,35},
349 (
double[]){10,20,15},
354 (
double[]){10,20,15},
355 (
double[]){30,30,40},
gc_edges, 3)}, 1);
360 (
double[3]){10,20,15},
361 (
double[3]){30,30,40},
gc_edges, 3),
365 (
double[]){utest_get_intersection(
367 (
double[2][2]){{15, 40}, {20, 30}}, 32),
368 utest_get_intersection(
370 (
double[2][2]){{15, 40}, {20, 30}}, 38),
371 utest_get_intersection(
373 (
double[2][2]){{15, 40}, {10, 30}}, 38),
374 utest_get_intersection(
376 (
double[2][2]){{15, 40}, {10, 30}}, 32)},
377 (
double[]){32,38,38,32},
384 (
double[3]){-20,20,0},
385 (
double[3]){80,80,85},
gc_edges, 3),
386 (
double[2]){80.001, 89},
390 utest_get_intersection(
392 (
double[2][2]){{0, 85}, {-20, 80}}, 80.001),
393 -fabs(utest_get_intersection(
395 (
double[2][2]){{-20, 80}, {20, 80}}, 80.001)),
396 fabs(utest_get_intersection(
398 (
double[2][2]){{-20, 80}, {20, 80}}, 80.001)),
399 utest_get_intersection(
401 (
double[2][2]){{0, 85}, {20, 80}}, 80.001),},
402 (
double[]){85,80.001,80.001,80.001,80.001},
410 (
double[]){10,20,15},
415 (
double[]){10,20,15},
416 (
double[]){82,82,88},
gc_edges, 3)}, 1);
421 (
double[]){10,20,15},
422 (
double[]){-82,-82,-88},
gc_edges, 3),
423 (
double[2]){90, 80}, NULL, 0);
428 (
double[]){10,20,15},
429 (
double[]){-82,-82,-88},
gc_edges, 3),
430 (
double[2]){-90, -80},
433 (
double[]){10,20,15},
434 (
double[]){-82,-82,-88},
gc_edges, 3)}, 1);
439 (
double[]){10,20,15},
441 (
double[2]){-90, -80}, NULL, 0);
446 (
double[]){10,20,15},
448 (
double[2]){90, 90}, NULL, 0);
453 (
double[]){10,20,15},
455 (
double[2]){-90, -90}, NULL, 0);
460 (
double[]){0,120,240},
465 (
double[]){0,120,240},
466 (
double[]){80,80,80},
gc_edges, 3)}, 1);
471 (
double[]){0,120,240},
473 (
double[2]){60, 70}, NULL, 0);
482 (
double[]){0,120,240},
487 (
double[]){0,temp_lon[0],temp_lon[1]},
488 (
double[]){85,80,80},
497 temp_lon[1] = (temp_lon[1] < 0)?(temp_lon[1] + 360):(temp_lon[1]);
498 temp_lon[1] = (temp_lon[1] < 180)?(temp_lon[1]):(360 - temp_lon[1]);
499 temp_lon[2] = 360 - temp_lon[1];
504 (
double[]){0,120,240},
509 (
double[]){0,temp_lon[0],temp_lon[1],temp_lon[2],temp_lon[3]},
510 (
double[]){85,72,72,72,72},
522 (
double[]){0,120,240},
527 (
double[]){temp_lon[0],120,240,temp_lon[1]},
528 (
double[]){80,70,70,80},
544 (
double[]){0,120,240},
549 (
double[]){temp_lon[0],temp_lon[1],temp_lon[2],temp_lon[3]},
550 (
double[]){84,80,80,84},
562 temp_lon[2] = (temp_lon[2] < 0)?(temp_lon[2] + 360):(temp_lon[2]);
563 temp_lon[2] = (temp_lon[2] < 180)?(temp_lon[2]):(360 - temp_lon[2]);
564 temp_lon[3] = 360 - temp_lon[2];
571 (
double[]){0,120,240},
576 (
double[]){temp_lon[0],temp_lon[1],temp_lon[2],
577 temp_lon[3],temp_lon[4],temp_lon[5]},
578 (
double[]){80,72,72,72,72,80},
590 (
double[]){0,120,240},
595 (
double[]){0,temp_lon[0],temp_lon[1]},
596 (
double[]){90,85,85},
613 (
double[2]){2.5, -2.5},
616 (
double[]){0,temp_lon[0],temp_lon[1],temp_lon[2],temp_lon[3]},
617 (
double[]){0,2.5,2.5,-2.5,-2.5},
627 (
double[2]){2.5, -2.5}, NULL, 0);
637 double const angle_tol = 1e-6;
646 for (
int order = -1; order <= 1; order += 2) {
647 for (
int start = 0; start < (int)(a.
num_corners); ++start) {
667 if (!differences)
return 0;
675 double deg_lat_bounds[2],
677 unsigned num_ref_cells) {
681 double rad_lat_bounds[2] =
684 double mem_dummy_[128][3];
689 .edge_type = edge_dummy,
694 for (
int pole = 0; pole < 2; ++pole) {
695 for (
int order = -1; order <= 1; order += 2) {
696 for (
int start = 0; start < (int)(cell.
num_corners); ++start) {
708 for (
int bound_tol_a = -1; bound_tol_a <= 1; ++bound_tol_a) {
709 for (
int bound_tol_b = -1; bound_tol_b <= 1; ++bound_tol_b) {
710 for (
int bound_order = 0; bound_order <= 1; ++bound_order) {
711 double test_rad_lat_bounds[2] = {
714 rad_lat_bounds[bound_order] +
718 rad_lat_bounds[bound_order^1] +
721 1, &test_cell,test_rad_lat_bounds, &overlap_cell);
722 if (num_ref_cells == 0) {
723 if ((overlap_cell.num_corners != 0) &&
725 PUT_ERR(
"ERROR: wrong clipping cell\n");
728 for (
int i = 0;
i < (int)num_ref_cells; ++
i)
731 PUT_ERR(
"ERROR: wrong clipping cell\n");
742 rad_lat_bounds[0] *= -1.0, rad_lat_bounds[1] *= -1.0;
743 for (
unsigned i = 0;
i < num_ref_cells; ++
i)
744 for (
int j = 0; j < (int)(ref_cells[i].num_corners); ++j)
745 ref_cells[i].coordinates_xyz[j][2] *= -1.0;
749 for (
unsigned i = 0;
i < num_ref_cells; ++
i)
double yac_huiliers_area(struct yac_grid_cell cell)
Area calculation on a unit sphere taken from ESMF based on L'Huilier's Theorem.
Structs and interfaces for area calculations.
void yac_cell_lat_clipping(size_t N, struct yac_grid_cell *cells, double lat_bounds[2], struct yac_grid_cell *overlap_buffer)
cell clipping to get the cells describing the intersections
#define yac_angle_low_tol
static double get_vector_angle(double const a[3], double const b[3])
void yac_init_grid_cell(struct yac_grid_cell *cell)
void yac_free_grid_cell(struct yac_grid_cell *cell)
@ YAC_GREAT_CIRCLE_EDGE
great circle
@ YAC_LAT_CIRCLE_EDGE
latitude circle
@ YAC_LON_CIRCLE_EDGE
longitude circle
static void XYZtoLL(double const p_in[], double *lon, double *lat)
enum yac_edge_type * edge_type
double(* coordinates_xyz)[3]
struct yac_grid_cell generate_cell_deg(double *lon, double *lat, enum yac_edge_type *edge_type, size_t num_corners)
int intersect(enum yac_edge_type edge_type_a, double lon_a, double lat_a, double lon_b, double lat_b, enum yac_edge_type edge_type_b, double lon_c, double lat_c, double lon_d, double lat_d, double *intersection)
static enum yac_edge_type gc_edges[]
static enum yac_edge_type latlon_edges[4]
static int compare_cells(struct yac_grid_cell a, struct yac_grid_cell b)
static struct user_input_data_points ** points