YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_circle.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <math.h>
8
9#include "clipping.h"
10#include "geometry.h"
11#include "test_common.h"
12#include "tests.h"
13
20static void utest_check_compare_circles(
21 struct yac_circle * circle_a, int a_is_lat,
22 struct yac_circle * circle_b, int b_is_lat,
23 int are_identical);
24
25int main (void) {
26
27 struct point_2d {double lon, lat;};
28
29 { // test yac_circle_compare and yac_circle_contains_north_pole
30 struct {
31 struct point_2d a, b;
32 enum yac_edge_type edge_type;
33 int edge_ordering;
34 int circle_idx;
35 int contains_north_pole;
36 } test_data[] =
37 {{.a = {.lon = 45.0, .lat = 0.0}, // equator clockwise
38 .b = {.lon = -45.0, .lat = 0.0},
39 .edge_type = YAC_GREAT_CIRCLE_EDGE,
40 .edge_ordering = -1,
41 .circle_idx = 0,
42 .contains_north_pole = 1},
43 {.a = {.lon = -45.0, .lat = 0.0}, // equator clockwise
44 .b = {.lon = 45.0, .lat = 0.0},
45 .edge_type = YAC_GREAT_CIRCLE_EDGE,
46 .edge_ordering = 1,
47 .circle_idx = 0,
48 .contains_north_pole = 1},
49 {.a = {.lon = 45.0, .lat = 0.0}, // equator counter clockwise
50 .b = {.lon = -45.0, .lat = 0.0},
51 .edge_type = YAC_GREAT_CIRCLE_EDGE,
52 .edge_ordering = 1,
53 .circle_idx = 1,
54 .contains_north_pole = 0},
55 {.a = {.lon = -45.0, .lat = 0.0}, // equator counter clockwise
56 .b = {.lon = 45.0, .lat = 0.0},
57 .edge_type = YAC_GREAT_CIRCLE_EDGE,
58 .edge_ordering = -1,
59 .circle_idx = 1,
60 .contains_north_pole = 0},
61 {.a = {.lon = 0.0, .lat = 88.0}, // Prime meridian
62 .b = {.lon = 180.0, .lat = 88.0},
63 .edge_type = YAC_GREAT_CIRCLE_EDGE,
64 .edge_ordering = 1,
65 .circle_idx = 2,
66 .contains_north_pole = 0},
67 {.a = {.lon = 180.0, .lat = 88.0}, // Prime meridian
68 .b = {.lon = 0.0, .lat = 88.0},
69 .edge_type = YAC_GREAT_CIRCLE_EDGE,
70 .edge_ordering = -1,
71 .circle_idx = 2,
72 .contains_north_pole = 0},
73 {.a = {.lon = 0.0, .lat = -1.0}, // Prime meridian (other direction)
74 .b = {.lon = 0.0, .lat = 1.0},
75 .edge_type = YAC_GREAT_CIRCLE_EDGE,
76 .edge_ordering = -1,
77 .circle_idx = 3,
78 .contains_north_pole = 0},
79 {.a = {.lon = 10.0, .lat = 10.0}, // lon circle
80 .b = {.lon = 10.0, .lat = 20.0},
81 .edge_type = YAC_LON_CIRCLE_EDGE,
82 .edge_ordering = -1,
83 .circle_idx = 4,
84 .contains_north_pole = 0},
85 {.a = {.lon = 10.0, .lat = 10.0}, // lon circle
86 .b = {.lon = 10.0, .lat = 20.0},
87 .edge_type = YAC_LON_CIRCLE_EDGE,
88 .edge_ordering = 1,
89 .circle_idx = 5,
90 .contains_north_pole = 0},
91 {.a = {.lon = 45.0, .lat = 89.0}, // lon circle
92 .b = {.lon = 45.0+180.0, .lat = 85.0},
93 .edge_type = YAC_LON_CIRCLE_EDGE,
94 .edge_ordering = 1,
95 .circle_idx = 6,
96 .contains_north_pole = 0},
97 {.a = {.lon = 45.0, .lat = 89.0}, // lon circle
98 .b = {.lon = 45.0+180.0, .lat = 85.0},
99 .edge_type = YAC_LON_CIRCLE_EDGE,
100 .edge_ordering = -1,
101 .circle_idx = 7,
102 .contains_north_pole = 0},
103 {.a = {.lon = 10.0, .lat = 70.0}, // lat circle
104 .b = {.lon = 20.0, .lat = 70.0},
105 .edge_type = YAC_LAT_CIRCLE_EDGE,
106 .edge_ordering = 1,
107 .circle_idx = 8,
108 .contains_north_pole = 1},
109 {.a = {.lon = 10.0, .lat = 70.0}, // lat circle
110 .b = {.lon = 20.0, .lat = 70.0},
111 .edge_type = YAC_LAT_CIRCLE_EDGE,
112 .edge_ordering = -1,
113 .circle_idx = 9,
114 .contains_north_pole = 0},
115 {.a = {.lon = -5.0, .lat = 15.0}, // lat circle
116 .b = {.lon = 5.0, .lat = 15.0},
117 .edge_type = YAC_LAT_CIRCLE_EDGE,
118 .edge_ordering = 1,
119 .circle_idx = 10,
120 .contains_north_pole = 1}};
121 enum {NUM_TESTS = sizeof(test_data) / sizeof(test_data[0])};
122
123 struct yac_circle test_circles[NUM_TESTS];
124
125 for (size_t i = 0; i < NUM_TESTS; ++i) {
126 double a[3], b[3];
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,
131 &test_circles[i]);
132 }
133 for (size_t i = 0; i < NUM_TESTS; ++i) {
134 if (yac_circle_contains_north_pole(&test_circles[i]) !=
135 test_data[i].contains_north_pole)
136 PUT_ERR("error in yac_circle_contains_north_pole");
137 for (size_t j = 0; j < NUM_TESTS; ++j) {
138 utest_check_compare_circles(
139 &test_circles[i], test_data[i].edge_type == YAC_LAT_CIRCLE_EDGE,
140 &test_circles[j], test_data[j].edge_type == YAC_LAT_CIRCLE_EDGE,
141 test_data[i].circle_idx == test_data[j].circle_idx);
142 }
143 }
144 }
145
146 { // test yac_circle_point_is_inside
147 struct {
148 struct point_2d a, b, point;
149 enum yac_edge_type edge_type;
150 int edge_ordering;
151 int is_inside;
152 } test_data[] =
153 {{.a = {.lon = -45.0, .lat = 0.0},
154 .b = {.lon = 45.0, .lat = 0.0},
155 .point = {.lon = 0.0, .lat = 90.0},
156 .edge_type = YAC_GREAT_CIRCLE_EDGE,
157 .edge_ordering = 1,
158 .is_inside = 1},
159 {.a = {.lon = -45.0, .lat = 0.0},
160 .b = {.lon = 45.0, .lat = 0.0},
161 .point = {.lon = 0.0, .lat = 90.0},
162 .edge_type = YAC_GREAT_CIRCLE_EDGE,
163 .edge_ordering = -1,
164 .is_inside = 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},
168 .edge_type = YAC_GREAT_CIRCLE_EDGE,
169 .edge_ordering = 1,
170 .is_inside = 2},
171 {.a = {.lon = -45.0, .lat = 0.0},
172 .b = {.lon = 45.0, .lat = 0.0},
173 .point = {.lon = 1.0, .lat = 1.0},
174 .edge_type = YAC_GREAT_CIRCLE_EDGE,
175 .edge_ordering = 1,
176 .is_inside = 1},
177 {.a = {.lon = 15.0, .lat = 25.0},
178 .b = {.lon = 15.0, .lat = 30.0},
179 .point = {.lon = 10.0, .lat = 10.0},
180 .edge_type = YAC_LON_CIRCLE_EDGE,
181 .edge_ordering = 1,
182 .is_inside = 1},
183 {.a = {.lon = 15.0, .lat = 25.0},
184 .b = {.lon = 15.0, .lat = 30.0},
185 .point = {.lon = 10.0, .lat = 10.0},
186 .edge_type = YAC_LON_CIRCLE_EDGE,
187 .edge_ordering = -1,
188 .is_inside = 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},
192 .edge_type = YAC_LON_CIRCLE_EDGE,
193 .edge_ordering = -1,
194 .is_inside = 2},
195 {.a = {.lon = 15.0, .lat = 25.0},
196 .b = {.lon = 15.0, .lat = 30.0},
197 .point = {.lon = 15.0, .lat = 60.0},
198 .edge_type = YAC_LON_CIRCLE_EDGE,
199 .edge_ordering = -1,
200 .is_inside = 2},
201 {.a = {.lon = 75.0, .lat = 75.0},
202 .b = {.lon = 80.0, .lat = 75.0},
203 .point = {.lon = 15.0, .lat = 80.0},
204 .edge_type = YAC_LAT_CIRCLE_EDGE,
205 .edge_ordering = 1,
206 .is_inside = 1},
207 {.a = {.lon = 75.0, .lat = 75.0},
208 .b = {.lon = 80.0, .lat = 75.0},
209 .point = {.lon = 15.0, .lat = 90.0},
210 .edge_type = YAC_LAT_CIRCLE_EDGE,
211 .edge_ordering = 1,
212 .is_inside = 1},
213 {.a = {.lon = 75.0, .lat = 75.0},
214 .b = {.lon = 80.0, .lat = 75.0},
215 .point = {.lon = 15.0, .lat = 80.0},
216 .edge_type = YAC_LAT_CIRCLE_EDGE,
217 .edge_ordering = -1,
218 .is_inside = 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},
222 .edge_type = YAC_LAT_CIRCLE_EDGE,
223 .edge_ordering = -1,
224 .is_inside = 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},
228 .edge_type = YAC_LAT_CIRCLE_EDGE,
229 .edge_ordering = 1,
230 .is_inside = 2}};
231 enum {NUM_TESTS = sizeof(test_data) / sizeof(test_data[0])};
232
233 for (size_t i = 0; i < NUM_TESTS; ++i) {
234 double point[3];
235 LLtoXYZ_deg(test_data[i].point.lon,
236 test_data[i].point.lat, point);
237 struct yac_circle test_circle;
238 double a[3], b[3];
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,
243 &test_circle);
244 if (yac_circle_point_is_inside(point, &test_circle) !=
245 test_data[i].is_inside)
246 PUT_ERR("error in yac_circle_point_is_inside");
247 }
248 }
249
250 { // test yac_circle_compare_distances
251 struct {
252 struct point_2d a, b, point_a, point_b;
253 enum yac_edge_type edge_type;
254 int compare;
255 } test_data[] =
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},
260 .edge_type = YAC_GREAT_CIRCLE_EDGE,
261 .compare = -1},
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},
266 .edge_type = YAC_GREAT_CIRCLE_EDGE,
267 .compare = 1},
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},
272 .edge_type = YAC_GREAT_CIRCLE_EDGE,
273 .compare = 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},
278 .edge_type = YAC_GREAT_CIRCLE_EDGE,
279 .compare = -1},
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},
284 .edge_type = YAC_GREAT_CIRCLE_EDGE,
285 .compare = 1},
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},
290 .edge_type = YAC_LON_CIRCLE_EDGE,
291 .compare = -1},
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},
296 .edge_type = YAC_LON_CIRCLE_EDGE,
297 .compare = 1},
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},
302 .edge_type = YAC_LON_CIRCLE_EDGE,
303 .compare = 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},
308 .edge_type = YAC_LAT_CIRCLE_EDGE,
309 .compare = -1},
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},
314 .edge_type = YAC_LAT_CIRCLE_EDGE,
315 .compare = 1},
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},
320 .edge_type = YAC_LAT_CIRCLE_EDGE,
321 .compare = 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},
326 .edge_type = YAC_GREAT_CIRCLE_EDGE,
327 .compare = -1},
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},
332 .edge_type = YAC_GREAT_CIRCLE_EDGE,
333 .compare = 1},
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},
338 .edge_type = YAC_GREAT_CIRCLE_EDGE,
339 .compare = -1},
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},
344 .edge_type = YAC_GREAT_CIRCLE_EDGE,
345 .compare = 1},
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},
350 .edge_type = YAC_GREAT_CIRCLE_EDGE,
351 .compare = 0}};
352 enum {NUM_TESTS = sizeof(test_data) / sizeof(test_data[0])};
353
354 for (size_t i = 0; i < NUM_TESTS; ++i) {
355 double point_a[3], point_b[3];
356 LLtoXYZ_deg(test_data[i].point_a.lon,
357 test_data[i].point_a.lat, point_a);
358 LLtoXYZ_deg(test_data[i].point_b.lon,
359 test_data[i].point_b.lat, point_b);
360 struct yac_circle test_circle;
361 double a[3], b[3];
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);
366 if (yac_circle_compare_distances(point_a, point_b, &test_circle) !=
367 test_data[i].compare)
368 PUT_ERR("error in yac_circle_compare_distances");
369 }
370 }
371
372 { // basic tests for yac_circle_intersect
373 struct {
374 struct {
375 struct point_2d points[2];
376 enum yac_edge_type edge_type;
377 } circles[2];
378 struct point_2d p, q;
379 int ret_value;
380 } test_data[] =
381 {{.circles = {{.points = {{.lon = -1.0, .lat = -1.0},
382 {.lon = 1.0, .lat = 1.0}},
383 .edge_type = YAC_GREAT_CIRCLE_EDGE},
384 {.points = {{.lon = -1.0, .lat = 1.0},
385 {.lon = 1.0, .lat = -1.0}},
386 .edge_type = YAC_GREAT_CIRCLE_EDGE}},
387 .p = {.lon = 0.0, .lat = 0.0},
388 .q = {.lon = 180.0, .lat = 0.0},
389 .ret_value = 2},
390 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
391 {.lon = 0.0, .lat = 1.0}},
392 .edge_type = YAC_GREAT_CIRCLE_EDGE},
393 {.points = {{.lon = 180.0, .lat = -2.0},
394 {.lon = 180.0, .lat = 2.0}},
395 .edge_type = YAC_GREAT_CIRCLE_EDGE}},
396 .p = {.lon = 0.0, .lat = 0.0},
397 .q = {.lon = 0.0, .lat = 0.0},
398 .ret_value = -1},
399 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
400 {.lon = 0.0, .lat = 1.0}},
401 .edge_type = YAC_GREAT_CIRCLE_EDGE},
402 {.points = {{.lon = 6.0, .lat = 45.0},
403 {.lon = 9.0, .lat = 45.0}},
404 .edge_type = YAC_LAT_CIRCLE_EDGE}},
405 .p = {.lon = 0.0, .lat = 45.0},
406 .q = {.lon = 180.0, .lat = 45.0},
407 .ret_value = 2},
408 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
409 {.lon = 0.0, .lat = 1.0}},
410 .edge_type = YAC_GREAT_CIRCLE_EDGE},
411 {.points = {{.lon = 6.0, .lat = 90.0},
412 {.lon = 9.0, .lat = 90.0}},
413 .edge_type = YAC_LAT_CIRCLE_EDGE}},
414 .p = {.lon = 0.0, .lat = 90.0},
415 .q = {.lon = 180.0, .lat = -90.0},
416 .ret_value = 1},
417 {.circles = {{.points = {{.lon = 1.0, .lat = 0.0},
418 {.lon = 2.0, .lat = 0.0}},
419 .edge_type = YAC_GREAT_CIRCLE_EDGE},
420 {.points = {{.lon = 6.0, .lat = 45.0},
421 {.lon = 9.0, .lat = 45.0}},
422 .edge_type = YAC_LAT_CIRCLE_EDGE}},
423 .p = {.lon = 0.0, .lat = 0.0},
424 .q = {.lon = 0.0, .lat = 0.0},
425 .ret_value = 0},
426 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
427 {.lon = 0.0, .lat = 1.0}},
428 .edge_type = YAC_LON_CIRCLE_EDGE},
429 {.points = {{.lon = 17.0, .lat = -1.0},
430 {.lon = 17.0, .lat = 1.0}},
431 .edge_type = YAC_LON_CIRCLE_EDGE}},
432 .p = {.lon = 0.0, .lat = 90.0},
433 .q = {.lon = 0.0, .lat = -90.0},
434 .ret_value = 2},
435 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
436 {.lon = 0.0, .lat = 1.0}},
437 .edge_type = YAC_LON_CIRCLE_EDGE},
438 {.points = {{.lon = 0.0, .lat = 45.0},
439 {.lon = 0.0, .lat = 50.0}},
440 .edge_type = YAC_LON_CIRCLE_EDGE}},
441 .p = {.lon = 0.0, .lat = 90.0},
442 .q = {.lon = 0.0, .lat = -90.0},
443 .ret_value = -1},
444 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
445 {.lon = 0.0, .lat = 1.0}},
446 .edge_type = YAC_LON_CIRCLE_EDGE},
447 {.points = {{.lon = -1.0, .lat = 45.0},
448 {.lon = 1.0, .lat = 45.0}},
449 .edge_type = YAC_LAT_CIRCLE_EDGE}},
450 .p = {.lon = 0.0, .lat = 45.0},
451 .q = {.lon = 180.0, .lat = 45.0},
452 .ret_value = 2},
453 {.circles = {{.points = {{.lon = 0.0, .lat = -1.0},
454 {.lon = 0.0, .lat = 1.0}},
455 .edge_type = YAC_LON_CIRCLE_EDGE},
456 {.points = {{.lon = -1.0, .lat = -90.0},
457 {.lon = 1.0, .lat = -90.0}},
458 .edge_type = YAC_LAT_CIRCLE_EDGE}},
459 .p = {.lon = 0.0, .lat = -90.0},
460 .q = {.lon = 180.0, .lat = 90.0},
461 .ret_value = 1},
462 {.circles = {{.points = {{.lon = 0.0, .lat = 0.0},
463 {.lon = 0.0, .lat = 0.0}},
464 .edge_type = YAC_GREAT_CIRCLE_EDGE}, // point
465 {.points = {{.lon = -1.0, .lat = 0.0},
466 {.lon = 1.0, .lat = 0.0}},
467 .edge_type = YAC_GREAT_CIRCLE_EDGE}},
468 .p = {.lon = 0.0, .lat = 0.0},
469 .q = {.lon = 180.0, .lat = 0.0},
470 .ret_value = 1},
471 {.circles = {{.points = {{.lon = 0.0, .lat = 1.0},
472 {.lon = 0.0, .lat = 1.0}},
473 .edge_type = YAC_GREAT_CIRCLE_EDGE}, // point
474 {.points = {{.lon = -1.0, .lat = 0.0},
475 {.lon = 1.0, .lat = 0.0}},
476 .edge_type = YAC_GREAT_CIRCLE_EDGE}},
477 .p = {.lon = 0.0, .lat = 0.0},
478 .q = {.lon = 180.0, .lat = 0.0},
479 .ret_value = 0},
480 {.circles = {{.points = {{.lon = 0.0, .lat = 45.0},
481 {.lon = 0.0, .lat = 45.0}},
482 .edge_type = YAC_GREAT_CIRCLE_EDGE}, // point
483 {.points = {{.lon = -1.0, .lat = 45.0},
484 {.lon = 1.0, .lat = 45.0}},
485 .edge_type = YAC_LAT_CIRCLE_EDGE}},
486 .p = {.lon = 0.0, .lat = 45.0},
487 .q = {.lon = 180.0, .lat = 45.0},
488 .ret_value = 1},
489 {.circles = {{.points = {{.lon = 0.0, .lat = 0.0},
490 {.lon = 0.0, .lat = 0.0}},
491 .edge_type = YAC_GREAT_CIRCLE_EDGE}, // point
492 {.points = {{.lon = -1.0, .lat = 45.0},
493 {.lon = 1.0, .lat = 45.0}},
494 .edge_type = YAC_LAT_CIRCLE_EDGE}},
495 .p = {.lon = 0.0, .lat = 45.0},
496 .q = {.lon = 180.0, .lat = 45.0},
497 .ret_value = 0},
498 {.circles = {{.points = {{.lon = 5.0, .lat = 5.0},
499 {.lon = 5.0, .lat = 5.0}},
500 .edge_type = YAC_GREAT_CIRCLE_EDGE}, // point
501 {.points = {{.lon = 5.0, .lat = 5.0},
502 {.lon = 5.0, .lat = 5.0}},
503 .edge_type = YAC_GREAT_CIRCLE_EDGE}}, // point
504 .p = {.lon = 5.0, .lat = 5.0},
505 .q = {.lon = 185.0, .lat = -5.0},
506 .ret_value = 1}};
507 enum {NUM_TESTS = sizeof(test_data) / sizeof(test_data[0])};
508
509 for (size_t i = 0; i < NUM_TESTS; ++i) {
510 struct yac_circle test_circles[2];
511 for (int j = 0; j < 2; ++j) {
512 double points_3d[2][3];
513 for (int k = 0; k < 2; ++k)
515 test_data[i].circles[j].points[k].lon,
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]);
520 }
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)
530 if (!(((get_vector_angle(p, ref_p) < yac_angle_tol) &&
531 (get_vector_angle(q, ref_q) < yac_angle_tol)) ||
532 ((get_vector_angle(q, ref_p) < yac_angle_tol) &&
533 (get_vector_angle(p, ref_q) < yac_angle_tol))))
534 PUT_ERR("error in yac_circle_intersect");
535 }
536 }
537 }
538
539 return TEST_EXIT_CODE;
540}
541
542static void utest_check_compare_circles(struct yac_circle * circle_a, int a_is_lat,
543 struct yac_circle * circle_b, int b_is_lat,
544 int are_identical) {
545
546 int ret_a = yac_circle_compare(&circle_a, &circle_b);
547 int ret_b = yac_circle_compare(&circle_b, &circle_a);
548 if ((are_identical && (ret_a || ret_b)) ||
549 (!are_identical &&
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");
555}
int yac_circle_point_is_inside(double const point[3], struct yac_circle *circle)
Definition clipping.c:473
int yac_circle_compare(void const *a, void const *b)
Definition clipping.c:346
int yac_circle_contains_north_pole(struct yac_circle *circle)
Definition clipping.c:565
void yac_circle_generate(double const *a, double const *b, enum yac_edge_type type, int edge_ordering, struct yac_circle *circle)
Definition clipping.c:417
int yac_circle_compare_distances(double const a[3], double const b[3], struct yac_circle *circle)
Definition clipping.c:511
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[])
Definition geometry.h:269
#define yac_angle_tol
Definition geometry.h:26
static double get_vector_angle(double const a[3], double const b[3])
Definition geometry.h:340
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 yac_circle::@8::@10 lat
struct yac_circle::@8::@11 p
struct yac_circle::@8::@9 lon
#define NUM_TESTS
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
double(* p)(double lon, double lat)
Definition toy_scrip.c:119
static struct user_input_data_points ** points
Definition yac.c:158