22 double deg_lat_bounds[2],
24 unsigned num_ref_cells);
28static void utest_lat_clipping_degenerate_cells(
void);
30static double utest_get_intersection(
31 enum yac_edge_type edge_type,
double points[2][2],
double lat) {
33 double intersection[3], intersection_lon, intersection_lat;
35 if (!utest_intersect(edge_type, points[0][0], points[0][1],
36 points[1][0], points[1][1],
38 points[1][0], lat, intersection))
40 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
41 return intersection_lon /
YAC_RAD;
65 utest_generate_cell_deg(
66 (
double[4]){-5,5,5,-5},
68 (
double[2]){10, 20}, NULL, 0);
72 utest_generate_cell_deg(
73 (
double[4]){-5,5,5,-5},
75 (
double[2]){10, 20}, NULL, 0);
79 utest_generate_cell_deg(
80 (
double[4]){-5,5,5,-5},
82 (
double[2]){10, 20}, NULL, 0);
86 utest_generate_cell_deg(
87 (
double[4]){-5,5,5,-5},
89 (
double[2]){10, 20}, NULL, 0);
93 utest_generate_cell_deg(
94 (
double[4]){-5,5,5,-5},
96 (
double[2]){10, 20}, NULL, 0);
100 utest_generate_cell_deg(
101 (
double[4]){-5,5,5,-5},
103 (
double[2]){80, 90}, NULL, 0);
107 utest_generate_cell_deg(
108 (
double[4]){-5,5,5,-5},
110 (
double[2]){0, 0}, NULL, 0);
114 utest_generate_cell_deg(
115 (
double[4]){-5,5,5,-5},
117 (
double[2]){0, 0}, NULL, 0);
121 utest_generate_cell_deg(
122 (
double[4]){-5,5,5,-5},
124 (
double[2]){0, 0}, NULL, 0);
128 utest_generate_cell_deg(
129 (
double[4]){-5,5,5,-5},
133 utest_generate_cell_deg(
134 (
double[4]){-5,5,5,-5},
139 utest_generate_cell_deg(
140 (
double[4]){40,45,45,40},
144 utest_generate_cell_deg(
145 (
double[4]){40,45,45,40},
150 utest_generate_cell_deg(
151 (
double[4]){40,45,45,40},
155 utest_generate_cell_deg(
156 (
double[4]){40,45,45,40},
161 utest_generate_cell_deg(
162 (
double[4]){40,45,45,40},
166 utest_generate_cell_deg(
167 (
double[4]){40,45,45,40},
172 utest_generate_cell_deg(
173 (
double[4]){40,45,45,40},
177 utest_generate_cell_deg(
178 (
double[4]){40,45,45,40},
183 utest_generate_cell_deg(
184 (
double[4]){40,45,45,40},
186 (
double[2]){90, 80}, NULL, 0);
190 utest_generate_cell_deg(
191 (
double[4]){40,45,45,40},
195 utest_generate_cell_deg(
196 (
double[4]){40,45,45,40},
201 utest_generate_cell_deg(
202 (
double[4]){40,45,45,40},
206 utest_generate_cell_deg(
207 (
double[4]){40,45,45,40},
212 utest_generate_cell_deg(
213 (
double[4]){40,45,45,40},
217 utest_generate_cell_deg(
218 (
double[4]){40,45,45,40},
223 utest_generate_cell_deg(
224 (
double[4]){40,45,45,40},
228 utest_generate_cell_deg(
229 (
double[4]){40,45,45,40},
234 utest_generate_cell_deg(
235 (
double[4]){40,45,45,40},
239 utest_generate_cell_deg(
240 (
double[4]){40,45,45,40},
245 utest_generate_cell_deg(
246 (
double[4]){40,45,45,40},
248 (
double[2]){-90, -80}, NULL, 0);
252 utest_generate_cell_deg(
253 (
double[4]){40,45,45,40},
255 (
double[2]){-90, -80},
257 utest_generate_cell_deg(
258 (
double[4]){40,45,45,40},
263 utest_generate_cell_deg(
264 (
double[4]){40,45,45,40},
266 (
double[2]){-90, -80},
268 utest_generate_cell_deg(
269 (
double[4]){40,45,45,40},
274 utest_generate_cell_deg(
275 (
double[4]){40,45,45,40},
277 (
double[2]){-90, -80},
279 utest_generate_cell_deg(
280 (
double[4]){40,45,45,40},
285 utest_generate_cell_deg(
286 (
double[4]){40,45,45,40},
288 (
double[2]){-90, -80},
290 utest_generate_cell_deg(
291 (
double[4]){40,45,45,40},
296 utest_generate_cell_deg(
297 (
double[4]){40,45,45,40},
299 (
double[2]){-90, -80},
301 utest_generate_cell_deg(
302 (
double[4]){40,45,45,40},
308 utest_generate_cell_deg(
309 (
double[4]){0,5,5,0},
311 (
double[2]){89.9, 80},
313 utest_generate_cell_deg(
314 (
double[4]){0,5,5,0},
319 utest_generate_cell_deg(
320 (
double[3]){10,20,15},
321 (
double[3]){30,30,40},
gc_edges, 3),
324 utest_generate_cell_deg(
326 utest_get_intersection(
328 (
double[2][2]){{15, 40}, {10, 30}}, 35),
329 utest_get_intersection(
331 (
double[2][2]){{15, 40}, {20, 30}}, 35)},
332 (
double[]){40,35,35},
338 utest_generate_cell_deg(
339 (
double[3]){10,20,15},
340 (
double[3]){30,30,40},
gc_edges, 3),
343 utest_generate_cell_deg(
345 utest_get_intersection(
347 (
double[2][2]){{15, 40}, {10, 30}}, 35),
348 utest_get_intersection(
350 (
double[2][2]){{15, 40}, {20, 30}}, 35)},
351 (
double[]){30,30,35,35},
357 utest_generate_cell_deg(
358 (
double[]){10,20,15},
362 utest_generate_cell_deg(
363 (
double[]){10,20,15},
364 (
double[]){30,30,40},
gc_edges, 3)}, 1);
368 utest_generate_cell_deg(
369 (
double[3]){10,20,15},
370 (
double[3]){30,30,40},
gc_edges, 3),
373 utest_generate_cell_deg(
374 (
double[]){utest_get_intersection(
376 (
double[2][2]){{15, 40}, {20, 30}}, 32),
377 utest_get_intersection(
379 (
double[2][2]){{15, 40}, {20, 30}}, 38),
380 utest_get_intersection(
382 (
double[2][2]){{15, 40}, {10, 30}}, 38),
383 utest_get_intersection(
385 (
double[2][2]){{15, 40}, {10, 30}}, 32)},
386 (
double[]){32,38,38,32},
392 utest_generate_cell_deg(
393 (
double[3]){-20,20,0},
394 (
double[3]){80,80,85},
gc_edges, 3),
395 (
double[2]){80.001, 89},
397 utest_generate_cell_deg(
399 utest_get_intersection(
401 (
double[2][2]){{0, 85}, {-20, 80}}, 80.001),
402 -fabs(utest_get_intersection(
404 (
double[2][2]){{-20, 80}, {20, 80}}, 80.001)),
405 fabs(utest_get_intersection(
407 (
double[2][2]){{-20, 80}, {20, 80}}, 80.001)),
408 utest_get_intersection(
410 (
double[2][2]){{0, 85}, {20, 80}}, 80.001),},
411 (
double[]){85,80.001,80.001,80.001,80.001},
418 utest_generate_cell_deg(
419 (
double[]){10,20,15},
423 utest_generate_cell_deg(
424 (
double[]){10,20,15},
425 (
double[]){82,82,88},
gc_edges, 3)}, 1);
429 utest_generate_cell_deg(
430 (
double[]){10,20,15},
431 (
double[]){-82,-82,-88},
gc_edges, 3),
432 (
double[2]){90, 80}, NULL, 0);
436 utest_generate_cell_deg(
437 (
double[]){10,20,15},
438 (
double[]){-82,-82,-88},
gc_edges, 3),
439 (
double[2]){-90, -80},
441 utest_generate_cell_deg(
442 (
double[]){10,20,15},
443 (
double[]){-82,-82,-88},
gc_edges, 3)}, 1);
447 utest_generate_cell_deg(
448 (
double[]){10,20,15},
450 (
double[2]){-90, -80}, NULL, 0);
454 utest_generate_cell_deg(
455 (
double[]){10,20,15},
457 (
double[2]){90, 90}, NULL, 0);
461 utest_generate_cell_deg(
462 (
double[]){10,20,15},
464 (
double[2]){-90, -90}, NULL, 0);
468 utest_generate_cell_deg(
469 (
double[]){0,120,240},
473 utest_generate_cell_deg(
474 (
double[]){0,120,240},
475 (
double[]){80,80,80},
gc_edges, 3)}, 1);
479 utest_generate_cell_deg(
480 (
double[]){0,120,240},
482 (
double[2]){60, 70}, NULL, 0);
490 utest_generate_cell_deg(
491 (
double[]){0,120,240},
495 utest_generate_cell_deg(
496 (
double[]){0,temp_lon[0],temp_lon[1]},
497 (
double[]){85,80,80},
506 temp_lon[1] = (temp_lon[1] < 0)?(temp_lon[1] + 360):(temp_lon[1]);
507 temp_lon[1] = (temp_lon[1] < 180)?(temp_lon[1]):(360 - temp_lon[1]);
508 temp_lon[2] = 360 - temp_lon[1];
512 utest_generate_cell_deg(
513 (
double[]){0,120,240},
517 utest_generate_cell_deg(
518 (
double[]){0,temp_lon[0],temp_lon[1],temp_lon[2],temp_lon[3]},
519 (
double[]){85,72,72,72,72},
530 utest_generate_cell_deg(
531 (
double[]){0,120,240},
535 utest_generate_cell_deg(
536 (
double[]){temp_lon[0],120,240,temp_lon[1]},
537 (
double[]){80,70,70,80},
552 utest_generate_cell_deg(
553 (
double[]){0,120,240},
557 utest_generate_cell_deg(
558 (
double[]){temp_lon[0],temp_lon[1],temp_lon[2],temp_lon[3]},
559 (
double[]){84,80,80,84},
571 temp_lon[2] = (temp_lon[2] < 0)?(temp_lon[2] + 360):(temp_lon[2]);
572 temp_lon[2] = (temp_lon[2] < 180)?(temp_lon[2]):(360 - temp_lon[2]);
573 temp_lon[3] = 360 - temp_lon[2];
579 utest_generate_cell_deg(
580 (
double[]){0,120,240},
584 utest_generate_cell_deg(
585 (
double[]){temp_lon[0],temp_lon[1],temp_lon[2],
586 temp_lon[3],temp_lon[4],temp_lon[5]},
587 (
double[]){80,72,72,72,72,80},
598 utest_generate_cell_deg(
599 (
double[]){0,120,240},
603 utest_generate_cell_deg(
604 (
double[]){0,temp_lon[0],temp_lon[1]},
605 (
double[]){90,85,85},
619 utest_generate_cell_deg(
622 (
double[2]){2.5, -2.5},
624 utest_generate_cell_deg(
625 (
double[]){0,temp_lon[0],temp_lon[1],temp_lon[2],temp_lon[3]},
626 (
double[]){0,2.5,2.5,-2.5,-2.5},
637 utest_generate_cell_deg(
639 (
double[]){90,70,70}, lonlat_pole_edges, 3),
642 utest_generate_cell_deg(
644 (
double[]){90,70,70}, lonlat_pole_edges, 3)}, 1);
648 utest_generate_cell_deg(
650 (
double[]){90,70,70}, lonlat_pole_edges, 3),
651 (
double[2]){30, 60}, NULL, 0);
656 utest_generate_cell_deg(
658 (
double[]){90,70,70}, lonlat_pole_edges, 3),
661 utest_generate_cell_deg(
663 (
double[]){90,75,75}, lonlat_pole_edges, 3)}, 1);
669 utest_generate_cell_deg(
671 (
double[]){90,70,70}, lonlat_pole_edges, 3),
674 utest_generate_cell_deg(
675 (
double[]){0,90,90,0},
684 utest_generate_cell_deg(
685 (
double[]){0,170,340},
686 (
double[]){45,45,45}, lat3_edges, 3),
689 utest_generate_cell_deg(
690 (
double[]){0,170,340},
691 (
double[]){45,45,45}, lat3_edges, 3)}, 1);
695 utest_generate_cell_deg(
698 (
double[2]){2.5, -2.5}, NULL, 0);
701 utest_lat_clipping_degenerate_cells();
712static void utest_lat_clipping_degenerate_cells(
void) {
724 utest_generate_cell_deg(
725 (
double[4]){-5,5,5,-5}, (
double[4]){-5,-5,5,5},
latlon_edges, 4),
726 utest_generate_cell_deg(
727 (
double[4]){5,15,15,5}, (
double[4]){-5,-5,5,5},
latlon_edges, 4)};
729 for (
int i = 0;
i < 2; ++
i) {
731 PUT_ERR(
"ERROR: test setup failed (expected a non-empty overlap)\n");
736 double dummy_coordinates_xyz[1][3];
740 for (
int i = 0;
i < 2; ++
i)
741 degenerate_cells[i] =
743 .edge_type = dummy_edge_type,
744 .num_corners = (size_t)i,
747 for (
int i = 0;
i < 2; ++
i)
749 PUT_ERR(
"ERROR: cell with too few corners does not result in an "
760 double const angle_tol = 1e-6;
769 for (
int order = -1; order <= 1; order += 2) {
770 for (
int start = 0; start < (int)(a.
num_corners); ++start) {
790 if (!differences)
return 0;
798 double deg_lat_bounds[2],
800 unsigned num_ref_cells) {
804 double rad_lat_bounds[2] =
809 double mem_dummy_[128][3] = {{0.0}};
814 .edge_type = edge_dummy,
819 for (
int pole = 0; pole < 2; ++pole) {
820 for (
int order = -1; order <= 1; order += 2) {
821 for (
int start = 0; start < (int)(cell.
num_corners); ++start) {
833 for (
int bound_tol_a = -1; bound_tol_a <= 1; ++bound_tol_a) {
834 for (
int bound_tol_b = -1; bound_tol_b <= 1; ++bound_tol_b) {
835 for (
int bound_order = 0; bound_order <= 1; ++bound_order) {
836 double test_rad_lat_bounds[2] = {
839 rad_lat_bounds[bound_order] +
843 rad_lat_bounds[bound_order^1] +
846 1, &test_cell,test_rad_lat_bounds, &overlap_cell);
847 if (num_ref_cells == 0) {
848 if ((overlap_cell.num_corners != 0) &&
850 PUT_ERR(
"ERROR: wrong clipping cell\n");
853 for (
int i = 0;
i < (int)num_ref_cells; ++
i)
854 match |= !utest_compare_cells(overlap_cell, ref_cells[i]);
856 PUT_ERR(
"ERROR: wrong clipping cell\n");
867 rad_lat_bounds[0] *= -1.0, rad_lat_bounds[1] *= -1.0;
868 for (
unsigned i = 0;
i < num_ref_cells; ++
i)
869 for (
int j = 0; j < (int)(ref_cells[i].num_corners); ++j)
870 ref_cells[i].coordinates_xyz[j][2] *= -1.0;
874 for (
unsigned i = 0;
i < num_ref_cells; ++
i)
double yac_grid_cell_area(struct yac_grid_cell cell)
Area calculation of a spherical cell.
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
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
#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
enum yac_edge_type * edge_type
double(* coordinates_xyz)[3]
static enum yac_edge_type gc_edges[]
static enum yac_edge_type latlon_edges[4]
static void XYZtoLL(double const p_in[], double *lon, double *lat)