20static void utest_check_compare_circles(
27 struct point_2d {
double lon, lat;};
35 int contains_north_pole;
37 {{.a = {.lon = 45.0, .lat = 0.0},
38 .b = {.lon = -45.0, .lat = 0.0},
42 .contains_north_pole = 1},
43 {.a = {.lon = -45.0, .lat = 0.0},
44 .b = {.lon = 45.0, .lat = 0.0},
48 .contains_north_pole = 1},
49 {.a = {.lon = 45.0, .lat = 0.0},
50 .b = {.lon = -45.0, .lat = 0.0},
54 .contains_north_pole = 0},
55 {.a = {.lon = -45.0, .lat = 0.0},
56 .b = {.lon = 45.0, .lat = 0.0},
60 .contains_north_pole = 0},
61 {.a = {.lon = 0.0, .lat = 88.0},
62 .b = {.lon = 180.0, .lat = 88.0},
66 .contains_north_pole = 0},
67 {.a = {.lon = 180.0, .lat = 88.0},
68 .b = {.lon = 0.0, .lat = 88.0},
72 .contains_north_pole = 0},
73 {.a = {.lon = 0.0, .lat = -1.0},
74 .b = {.lon = 0.0, .lat = 1.0},
78 .contains_north_pole = 0},
79 {.a = {.lon = 10.0, .lat = 10.0},
80 .b = {.lon = 10.0, .lat = 20.0},
84 .contains_north_pole = 0},
85 {.a = {.lon = 10.0, .lat = 10.0},
86 .b = {.lon = 10.0, .lat = 20.0},
90 .contains_north_pole = 0},
91 {.a = {.lon = 45.0, .lat = 89.0},
92 .b = {.lon = 45.0+180.0, .lat = 85.0},
96 .contains_north_pole = 0},
97 {.a = {.lon = 45.0, .lat = 89.0},
98 .b = {.lon = 45.0+180.0, .lat = 85.0},
102 .contains_north_pole = 0},
103 {.a = {.lon = 10.0, .lat = 70.0},
104 .b = {.lon = 20.0, .lat = 70.0},
108 .contains_north_pole = 1},
109 {.a = {.lon = 10.0, .lat = 70.0},
110 .b = {.lon = 20.0, .lat = 70.0},
114 .contains_north_pole = 0},
115 {.a = {.lon = -5.0, .lat = 15.0},
116 .b = {.lon = 5.0, .lat = 15.0},
120 .contains_north_pole = 1}};
121 enum {
NUM_TESTS =
sizeof(test_data) /
sizeof(test_data[0])};
127 LLtoXYZ_deg(test_data[i].a.lon, test_data[i].a.lat, a);
128 LLtoXYZ_deg(test_data[i].b.lon, test_data[i].b.lat, b);
130 a, b, test_data[i].edge_type, test_data[i].edge_ordering,
135 test_data[i].contains_north_pole)
136 PUT_ERR(
"error in yac_circle_contains_north_pole");
138 utest_check_compare_circles(
141 test_data[i].circle_idx == test_data[j].circle_idx);
148 struct point_2d a, b, point;
153 {{.a = {.lon = -45.0, .lat = 0.0},
154 .b = {.lon = 45.0, .lat = 0.0},
155 .point = {.lon = 0.0, .lat = 90.0},
159 {.a = {.lon = -45.0, .lat = 0.0},
160 .b = {.lon = 45.0, .lat = 0.0},
161 .point = {.lon = 0.0, .lat = 90.0},
165 {.a = {.lon = -45.0, .lat = 0.0},
166 .b = {.lon = 45.0, .lat = 0.0},
167 .point = {.lon = 0.0, .lat = 0.0},
171 {.a = {.lon = -45.0, .lat = 0.0},
172 .b = {.lon = 45.0, .lat = 0.0},
173 .point = {.lon = 1.0, .lat = 1.0},
177 {.a = {.lon = 15.0, .lat = 25.0},
178 .b = {.lon = 15.0, .lat = 30.0},
179 .point = {.lon = 10.0, .lat = 10.0},
183 {.a = {.lon = 15.0, .lat = 25.0},
184 .b = {.lon = 15.0, .lat = 30.0},
185 .point = {.lon = 10.0, .lat = 10.0},
189 {.a = {.lon = 15.0, .lat = 25.0},
190 .b = {.lon = 15.0, .lat = 30.0},
191 .point = {.lon = 10.0, .lat = 90.0},
195 {.a = {.lon = 15.0, .lat = 25.0},
196 .b = {.lon = 15.0, .lat = 30.0},
197 .point = {.lon = 15.0, .lat = 60.0},
201 {.a = {.lon = 75.0, .lat = 75.0},
202 .b = {.lon = 80.0, .lat = 75.0},
203 .point = {.lon = 15.0, .lat = 80.0},
207 {.a = {.lon = 75.0, .lat = 75.0},
208 .b = {.lon = 80.0, .lat = 75.0},
209 .point = {.lon = 15.0, .lat = 90.0},
213 {.a = {.lon = 75.0, .lat = 75.0},
214 .b = {.lon = 80.0, .lat = 75.0},
215 .point = {.lon = 15.0, .lat = 80.0},
219 {.a = {.lon = 75.0, .lat = 75.0},
220 .b = {.lon = 80.0, .lat = 75.0},
221 .point = {.lon = 15.0, .lat = 90.0},
225 {.a = {.lon = 75.0, .lat = 75.0},
226 .b = {.lon = 80.0, .lat = 75.0},
227 .point = {.lon = 15.0, .lat = 75.0},
231 enum {
NUM_TESTS =
sizeof(test_data) /
sizeof(test_data[0])};
236 test_data[i].point.lat, point);
239 LLtoXYZ_deg(test_data[i].a.lon, test_data[i].a.lat, a);
240 LLtoXYZ_deg(test_data[i].b.lon, test_data[i].b.lat, b);
242 a, b, test_data[i].edge_type, test_data[i].edge_ordering,
245 test_data[i].is_inside)
246 PUT_ERR(
"error in yac_circle_point_is_inside");
252 struct point_2d a, b, point_a, point_b;
256 {{.a = {.lon = -1.0, .lat = -1.0},
257 .b = {.lon = 1.0, .lat = 1.0},
258 .point_a = {.lon = -1.0, .lat = 1.0},
259 .point_b = {.lon = -2.0, .lat = 2.0},
262 {.a = {.lon = -1.0, .lat = -1.0},
263 .b = {.lon = 1.0, .lat = 1.0},
264 .point_a = {.lon = -2.0, .lat = 2.0},
265 .point_b = {.lon = -1.0, .lat = 1.0},
268 {.a = {.lon = -1.0, .lat = -1.0},
269 .b = {.lon = 1.0, .lat = 1.0},
270 .point_a = {.lon = -2.0, .lat = 2.0},
271 .point_b = {.lon = 2.0, .lat = -2.0},
274 {.a = {.lon = -1.0, .lat = -1.0},
275 .b = {.lon = 1.0, .lat = 1.0},
276 .point_a = {.lon = 0.0, .lat = 0.0},
277 .point_b = {.lon = 2.0, .lat = -2.0},
280 {.a = {.lon = -1.0, .lat = -1.0},
281 .b = {.lon = 1.0, .lat = 1.0},
282 .point_a = {.lon = 2.0, .lat = -2.0},
283 .point_b = {.lon = 0.0, .lat = 0.0},
286 {.a = {.lon = 2.0, .lat = -1.0},
287 .b = {.lon = 2.0, .lat = 1.0},
288 .point_a = {.lon = 1.0, .lat = 1.0},
289 .point_b = {.lon = 4.0, .lat = -1.0},
292 {.a = {.lon = 2.0, .lat = -1.0},
293 .b = {.lon = 2.0, .lat = 1.0},
294 .point_a = {.lon = 4.0, .lat = -1.0},
295 .point_b = {.lon = 1.0, .lat = 1.0},
298 {.a = {.lon = 2.0, .lat = -1.0},
299 .b = {.lon = 2.0, .lat = 1.0},
300 .point_a = {.lon = 3.0, .lat = -1.0},
301 .point_b = {.lon = 1.0, .lat = 1.0},
304 {.a = {.lon = -1.0, .lat = 60.0},
305 .b = {.lon = 1.0, .lat = 60.0},
306 .point_a = {.lon = 7.0, .lat = 59.0},
307 .point_b = {.lon = -13.0, .lat = 62.0},
310 {.a = {.lon = -1.0, .lat = 60.0},
311 .b = {.lon = 1.0, .lat = 60.0},
312 .point_a = {.lon = -13.0, .lat = 62.0},
313 .point_b = {.lon = 7.0, .lat = 59.0},
316 {.a = {.lon = -1.0, .lat = 60.0},
317 .b = {.lon = 1.0, .lat = 60.0},
318 .point_a = {.lon = 7.0, .lat = 59.0},
319 .point_b = {.lon = -13.0, .lat = 61.0},
322 {.a = {.lon = 45.0, .lat = 45.0},
323 .b = {.lon = 45.0, .lat = 45.0},
324 .point_a = {.lon = 46.0, .lat = 46.0},
325 .point_b = {.lon = 47.0, .lat = 47.0},
328 {.a = {.lon = 45.0, .lat = 45.0},
329 .b = {.lon = 45.0, .lat = 45.0},
330 .point_a = {.lon = 47.0, .lat = 47.0},
331 .point_b = {.lon = 46.0, .lat = 46.0},
334 {.a = {.lon = 45.0, .lat = 45.0},
335 .b = {.lon = 45.0, .lat = 45.0},
336 .point_a = {.lon = 40.0, .lat = 40.0},
337 .point_b = {.lon = -45.0, .lat = -45.0},
340 {.a = {.lon = 45.0, .lat = 45.0},
341 .b = {.lon = 45.0, .lat = 45.0},
342 .point_a = {.lon = -45.0, .lat = -45.0},
343 .point_b = {.lon = 40.0, .lat = 40.0},
346 {.a = {.lon = 45.0, .lat = 45.0},
347 .b = {.lon = 45.0, .lat = 45.0},
348 .point_a = {.lon = 45.0, .lat = 90.0},
349 .point_b = {.lon = 45.0, .lat = 0.0},
352 enum {
NUM_TESTS =
sizeof(test_data) /
sizeof(test_data[0])};
355 double point_a[3], point_b[3];
357 test_data[i].point_a.lat, point_a);
359 test_data[i].point_b.lat, point_b);
362 LLtoXYZ_deg(test_data[i].a.lon, test_data[i].a.lat, a);
363 LLtoXYZ_deg(test_data[i].b.lon, test_data[i].b.lat, b);
365 a, b, test_data[i].edge_type, 1, &test_circle);
367 test_data[i].compare)
368 PUT_ERR(
"error in yac_circle_compare_distances");
375 struct point_2d
points[2];
378 struct point_2d
p, q;
381 {{.circles = {{.points = {{.lon = -1.0, .lat = -1.0},
382 {.lon = 1.0, .lat = 1.0}},
384 {.points = {{.lon = -1.0, .lat = 1.0},
385 {.lon = 1.0, .lat = -1.0}},
387 .p = {.lon = 0.0, .lat = 0.0},
388 .q = {.lon = 180.0, .lat = 0.0},
390 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
391 {.lon = 0.0, .lat = 1.0}},
393 {.points = {{.lon = 180.0, .lat = -2.0},
394 {.lon = 180.0, .lat = 2.0}},
396 .p = {.lon = 0.0, .lat = 0.0},
397 .q = {.lon = 0.0, .lat = 0.0},
399 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
400 {.lon = 0.0, .lat = 1.0}},
402 {.points = {{.lon = 6.0, .lat = 45.0},
403 {.lon = 9.0, .lat = 45.0}},
405 .p = {.lon = 0.0, .lat = 45.0},
406 .q = {.lon = 180.0, .lat = 45.0},
408 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
409 {.lon = 0.0, .lat = 1.0}},
411 {.points = {{.lon = 6.0, .lat = 90.0},
412 {.lon = 9.0, .lat = 90.0}},
414 .p = {.lon = 0.0, .lat = 90.0},
415 .q = {.lon = 180.0, .lat = -90.0},
417 {.circles = {{.points = {{.lon = 1.0, .lat = 0.0},
418 {.lon = 2.0, .lat = 0.0}},
420 {.points = {{.lon = 6.0, .lat = 45.0},
421 {.lon = 9.0, .lat = 45.0}},
423 .p = {.lon = 0.0, .lat = 0.0},
424 .q = {.lon = 0.0, .lat = 0.0},
426 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
427 {.lon = 0.0, .lat = 1.0}},
429 {.points = {{.lon = 17.0, .lat = -1.0},
430 {.lon = 17.0, .lat = 1.0}},
432 .p = {.lon = 0.0, .lat = 90.0},
433 .q = {.lon = 0.0, .lat = -90.0},
435 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
436 {.lon = 0.0, .lat = 1.0}},
438 {.points = {{.lon = 0.0, .lat = 45.0},
439 {.lon = 0.0, .lat = 50.0}},
441 .p = {.lon = 0.0, .lat = 90.0},
442 .q = {.lon = 0.0, .lat = -90.0},
444 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
445 {.lon = 0.0, .lat = 1.0}},
447 {.points = {{.lon = -1.0, .lat = 45.0},
448 {.lon = 1.0, .lat = 45.0}},
450 .p = {.lon = 0.0, .lat = 45.0},
451 .q = {.lon = 180.0, .lat = 45.0},
453 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
454 {.lon = 0.0, .lat = 1.0}},
456 {.points = {{.lon = -1.0, .lat = -90.0},
457 {.lon = 1.0, .lat = -90.0}},
459 .p = {.lon = 0.0, .lat = -90.0},
460 .q = {.lon = 180.0, .lat = 90.0},
462 {.circles = {{.points = {{.lon = 0.0, .lat = 0.0},
463 {.lon = 0.0, .lat = 0.0}},
465 {.points = {{.lon = -1.0, .lat = 0.0},
466 {.lon = 1.0, .lat = 0.0}},
468 .p = {.lon = 0.0, .lat = 0.0},
469 .q = {.lon = 180.0, .lat = 0.0},
471 {.circles = {{.points = {{.lon = 0.0, .lat = 1.0},
472 {.lon = 0.0, .lat = 1.0}},
474 {.points = {{.lon = -1.0, .lat = 0.0},
475 {.lon = 1.0, .lat = 0.0}},
477 .p = {.lon = 0.0, .lat = 0.0},
478 .q = {.lon = 180.0, .lat = 0.0},
480 {.circles = {{.points = {{.lon = 0.0, .lat = 45.0},
481 {.lon = 0.0, .lat = 45.0}},
483 {.points = {{.lon = -1.0, .lat = 45.0},
484 {.lon = 1.0, .lat = 45.0}},
486 .p = {.lon = 0.0, .lat = 45.0},
487 .q = {.lon = 180.0, .lat = 45.0},
489 {.circles = {{.points = {{.lon = 0.0, .lat = 0.0},
490 {.lon = 0.0, .lat = 0.0}},
492 {.points = {{.lon = -1.0, .lat = 45.0},
493 {.lon = 1.0, .lat = 45.0}},
495 .p = {.lon = 0.0, .lat = 45.0},
496 .q = {.lon = 180.0, .lat = 45.0},
498 {.circles = {{.points = {{.lon = 5.0, .lat = 5.0},
499 {.lon = 5.0, .lat = 5.0}},
501 {.points = {{.lon = 5.0, .lat = 5.0},
502 {.lon = 5.0, .lat = 5.0}},
504 .p = {.lon = 5.0, .lat = 5.0},
505 .q = {.lon = 185.0, .lat = -5.0},
507 enum {
NUM_TESTS =
sizeof(test_data) /
sizeof(test_data[0])};
511 for (
int j = 0; j < 2; ++j) {
512 double points_3d[2][3];
513 for (
int k = 0; k < 2; ++k)
516 test_data[i].circles[j].
points[k].
lat, points_3d[k]);
518 points_3d[0], points_3d[1], test_data[i].circles[j].edge_type,
519 1, &test_circles[j]);
521 double ref_p[3], ref_q[3],
p[3], q[3];
522 LLtoXYZ_deg(test_data[i].
p.lon, test_data[i].p.lat, ref_p);
523 LLtoXYZ_deg(test_data[i].q.lon, test_data[i].q.lat, ref_q);
524 for (
int j = 0; j < 2; ++j) {
526 test_circles[j], test_circles[j^1],
p, q) !=
527 test_data[i].ret_value)
528 PUT_ERR(
"error in yac_circle_intersect");
529 if (test_data[i].ret_value > 0)
534 PUT_ERR(
"error in yac_circle_intersect");
542static void utest_check_compare_circles(
struct yac_circle * circle_a,
int a_is_lat,
548 if ((are_identical && (ret_a || ret_b)) ||
550 ((!ret_a || !ret_b) ||
551 (ret_a != - ret_b) ||
552 ((a_is_lat != b_is_lat) &&
553 ((ret_a > ret_b) ^ a_is_lat)))))
554 PUT_ERR(
"error in yac_circle_compare");
int yac_circle_point_is_inside(double const point[3], struct yac_circle *circle)
int yac_circle_compare(void const *a, void const *b)
int yac_circle_contains_north_pole(struct yac_circle *circle)
void yac_circle_generate(double const *a, double const *b, enum yac_edge_type type, int edge_ordering, struct yac_circle *circle)
int yac_circle_compare_distances(double const a[3], double const b[3], struct yac_circle *circle)
int yac_circle_intersect(struct yac_circle a, struct yac_circle b, double p[3], double q[3])
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
static double get_vector_angle(double const a[3], double const b[3])
@ YAC_GREAT_CIRCLE_EDGE
great circle
@ YAC_LAT_CIRCLE_EDGE
latitude circle
@ YAC_LON_CIRCLE_EDGE
longitude circle
struct yac_circle::@8::@10 lat
struct yac_circle::@8::@11 p
struct yac_circle::@8::@9 lon
double(* p)(double lon, double lat)
static struct user_input_data_points ** points