Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL algorithms
4 : * Purpose: Tests for the marching squares algorithm
5 : * Author: Hugo Mercier, <hugo dot mercier at oslandia dot com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2018, Hugo Mercier, <hugo dot mercier at oslandia dot com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "gdal_unit_test.h"
14 :
15 : #include "gdal_alg.h"
16 :
17 : #include "marching_squares/square.h"
18 : #include "marching_squares/level_generator.h"
19 : #include <vector>
20 : #include <limits>
21 : #include <map>
22 : #include <fstream>
23 :
24 : #include "gtest_include.h"
25 :
26 : #if defined(__clang__)
27 : #pragma clang diagnostic push
28 : #pragma clang diagnostic ignored "-Wweak-vtables"
29 : #endif
30 :
31 : namespace test_marching_squares_square
32 : {
33 : using namespace marching_squares;
34 :
35 : struct Writer
36 : {
37 : typedef std::pair<Point, Point> Segment;
38 :
39 6 : void addSegment(int levelIdx, const Point &first, const Point &second)
40 : {
41 6 : contours[levelIdx].push_back(Segment(first, second));
42 6 : }
43 :
44 11 : void addBorderSegment(int levelIdx, const Point &first, const Point &second)
45 : {
46 11 : borders[levelIdx].push_back(Segment(first, second));
47 11 : }
48 :
49 : std::map<int, std::vector<Segment>> contours;
50 : std::map<int, std::vector<Segment>> borders;
51 : const bool polygonize = true;
52 : };
53 :
54 : // Common fixture with test data
55 : struct test_ms_square : public ::testing::Test
56 : {
57 : };
58 :
59 : // Dummy test
60 4 : TEST_F(test_ms_square, dummy)
61 : {
62 : {
63 1 : const double levels[] = {0, 4};
64 : FixedLevelRangeIterator levelGenerator(
65 1 : levels, 2, -std::numeric_limits<double>::infinity(),
66 2 : std::numeric_limits<double>::infinity());
67 1 : auto r = levelGenerator.range(0, 5.0);
68 1 : auto b = r.begin();
69 1 : EXPECT_EQ((*b).first, 1);
70 1 : EXPECT_EQ((*b).second, 4.0);
71 1 : auto e = r.end();
72 1 : EXPECT_EQ((*e).first, 2);
73 1 : EXPECT_EQ((*e).second, Inf);
74 : }
75 : {
76 : IntervalLevelRangeIterator levelGenerator(
77 1 : 0, 4, -std::numeric_limits<double>::infinity());
78 1 : auto r = levelGenerator.range(0, 5.0);
79 1 : auto b = r.begin();
80 1 : EXPECT_EQ((*b).first, 1);
81 1 : EXPECT_EQ((*b).second, 4.0);
82 1 : auto e = r.end();
83 1 : EXPECT_EQ((*e).first, 2);
84 1 : EXPECT_EQ((*e).second, 8.0);
85 : }
86 : {
87 : IntervalLevelRangeIterator levelGenerator(
88 1 : 0, 10, -std::numeric_limits<double>::infinity());
89 1 : auto r = levelGenerator.range(-18, 5.0);
90 1 : auto b = r.begin();
91 1 : EXPECT_EQ((*b).first, -1);
92 1 : EXPECT_EQ((*b).second, -10.0);
93 1 : auto e = r.end();
94 1 : EXPECT_EQ((*e).first, 1);
95 1 : EXPECT_EQ((*e).second, 10.0);
96 : }
97 : {
98 : ExponentialLevelRangeIterator levelGenerator(
99 1 : 2, -std::numeric_limits<double>::infinity());
100 1 : auto r = levelGenerator.range(0, 5.0);
101 1 : auto b = r.begin();
102 1 : EXPECT_EQ((*b).first, 1);
103 1 : EXPECT_EQ((*b).second, 1.0);
104 1 : ++b;
105 1 : EXPECT_EQ((*b).first, 2);
106 1 : EXPECT_EQ((*b).second, 2.0);
107 1 : ++b;
108 1 : EXPECT_EQ((*b).first, 3);
109 1 : EXPECT_EQ((*b).second, 4.0);
110 1 : auto e = r.end();
111 1 : EXPECT_EQ((*e).first, 4);
112 1 : EXPECT_EQ((*e).second, 8.0);
113 : }
114 1 : }
115 :
116 4 : TEST_F(test_ms_square, only_zero)
117 : {
118 : // Square with only 0, level = 0.1
119 1 : Square square(ValuedPoint(0, 1, 0), ValuedPoint(1, 1, 0),
120 2 : ValuedPoint(0, 0, 0), ValuedPoint(1, 0, 0));
121 : Square::Segments segments(
122 1 : square.segments(.1, -std::numeric_limits<double>::infinity()));
123 : //
124 : // 0 0
125 : // +------------------+
126 : // | |
127 : // | |
128 : // | |
129 : // | |
130 : // | |
131 : // | |
132 : // | |
133 : // +------------------+
134 : // 0 0
135 1 : EXPECT_EQ(segments.size(), size_t(0));
136 1 : }
137 :
138 4 : TEST_F(test_ms_square, only_one)
139 : {
140 : // Square with only 1, level = 0.1
141 1 : Square square(ValuedPoint(0, 1, 1), ValuedPoint(1, 1, 1),
142 2 : ValuedPoint(0, 0, 1), ValuedPoint(1, 0, 1));
143 : //
144 : // 1 1
145 : // +------------------+
146 : // | |
147 : // | |
148 : // | |
149 : // | |
150 : // | |
151 : // | |
152 : // | |
153 : // +------------------+
154 : // 1 1
155 : Square::Segments segments(
156 1 : square.segments(.1, -std::numeric_limits<double>::infinity()));
157 1 : EXPECT_EQ(segments.size(), size_t(0));
158 1 : }
159 :
160 4 : TEST_F(test_ms_square, only_zero_level_1)
161 : {
162 : // Square with only 1, level = 1.0
163 1 : Square square(ValuedPoint(0, 1, 1), ValuedPoint(1, 1, 1),
164 2 : ValuedPoint(0, 0, 1), ValuedPoint(1, 0, 1));
165 : //
166 : // 1 1
167 : // +------------------+
168 : // | |
169 : // | |
170 : // | |
171 : // | |
172 : // | |
173 : // | |
174 : // | |
175 : // +------------------+
176 : // 1 1
177 : Square::Segments segments(
178 1 : square.segments(1.0, -std::numeric_limits<double>::infinity()));
179 1 : EXPECT_EQ(segments.size(), size_t(0));
180 1 : }
181 :
182 4 : TEST_F(test_ms_square, one_segment)
183 : {
184 : // Square with one segment, level = 0.1
185 1 : Square square(ValuedPoint(0, 1, 1), ValuedPoint(1, 1, 0),
186 2 : ValuedPoint(0, 0, 0), ValuedPoint(1, 0, 0));
187 : //
188 : // 0 0
189 : // +------------------+
190 : // | |
191 : // | |
192 : // | |
193 : // | |
194 : // | |
195 : // o |
196 : // | \ |
197 : // +---o--------------+
198 : // 1 0
199 : Square::Segments segments(
200 1 : square.segments(.1, -std::numeric_limits<double>::infinity()));
201 1 : EXPECT_EQ(segments.size(), size_t(1));
202 1 : EXPECT_TRUE(segments[0].first == Point(.9, 1));
203 1 : EXPECT_TRUE(segments[0].second == Point(0, .1));
204 1 : }
205 :
206 4 : TEST_F(test_ms_square, fudge_test_1)
207 : {
208 : // Fudge test 1
209 1 : Square square(ValuedPoint(0, 1, 0), ValuedPoint(1, 1, 1),
210 2 : ValuedPoint(0, 0, 1), ValuedPoint(1, 0, 1));
211 : //
212 : // 0 1
213 : // +------------------o
214 : // | __/|
215 : // | __/ |
216 : // | __/ |
217 : // | _/ |
218 : // | __/ |
219 : // | __/ |
220 : // |/ |
221 : // o------------------+
222 : // 1 1
223 : // (0,0)
224 : {
225 : Square::Segments segments(
226 1 : square.segments(0.0, -std::numeric_limits<double>::infinity()));
227 1 : EXPECT_EQ(segments.size(), size_t(0));
228 : }
229 : {
230 : Square::Segments segments(
231 1 : square.segments(1.0, -std::numeric_limits<double>::infinity()));
232 1 : EXPECT_EQ(segments.size(), size_t(1));
233 1 : EXPECT_NEAR(segments[0].first.x, 0.0, 0.001);
234 1 : EXPECT_NEAR(segments[0].first.y, 0.0, 0.001);
235 1 : EXPECT_NEAR(segments[0].second.x, 1.0, 0.001);
236 1 : EXPECT_NEAR(segments[0].second.y, 1.0, 0.001);
237 : }
238 1 : }
239 :
240 4 : TEST_F(test_ms_square, fudge_test_2)
241 : {
242 : // Fudge test 2
243 1 : Square square(ValuedPoint(0, 1, 1), ValuedPoint(1, 1, 0),
244 2 : ValuedPoint(0, 0, 0), ValuedPoint(1, 0, 0));
245 : //
246 : // 1 0
247 : // +o-----------------+
248 : // o+ |
249 : // | |
250 : // | |
251 : // | |
252 : // | |
253 : // | |
254 : // | |
255 : // +------------------+
256 : // 0 0
257 : // (0,0)
258 : {
259 : Square::Segments segments(
260 1 : square.segments(1.0, -std::numeric_limits<double>::infinity()));
261 1 : EXPECT_EQ(segments.size(), 1);
262 1 : EXPECT_NEAR(segments[0].first.x, 0.0, 0.001);
263 1 : EXPECT_NEAR(segments[0].first.y, 1.0, 0.001);
264 1 : EXPECT_NEAR(segments[0].second.x, 0.0, 0.001);
265 1 : EXPECT_NEAR(segments[0].second.y, 1.0, 0.001);
266 : }
267 : {
268 : Square::Segments segments(
269 1 : square.segments(0.0, -std::numeric_limits<double>::infinity()));
270 1 : EXPECT_EQ(segments.size(), 0);
271 : }
272 1 : }
273 :
274 4 : TEST_F(test_ms_square, nan)
275 : {
276 : // A square with NaN
277 1 : const Square square(ValuedPoint(2.500000, 1.500000, 224.990005),
278 1 : ValuedPoint(3.500000, 1.500000, NaN),
279 1 : ValuedPoint(2.500000, 2.500000, 225.029999),
280 2 : ValuedPoint(3.500000, 2.500000, 224.770004));
281 :
282 : //
283 : // 224.990005 NaN
284 : // +------------------+
285 : // | |
286 : // | |
287 : // | |
288 : // | |
289 : // | |
290 : // | |
291 : // | |
292 : // +------------------+
293 : // 225.029999 224.770004
294 :
295 1 : const Square ul(square.upperLeftSquare());
296 1 : const Square ll(square.lowerLeftSquare());
297 :
298 : // upper left and lower left squares
299 : //
300 : // 224.990005 224.990005 NaN
301 : // +--------+---------+
302 : // | | |
303 : // | | |
304 : // | | |
305 : // +--------+ 224.930002
306 : // 225.010002 | |
307 : // | | |
308 : // | 224.900001 |
309 : // +--------+---------+
310 : // 225.029999 224.770004
311 :
312 1 : EXPECT_NEAR(ul.lowerLeft.value, 225.010002, 0.000001);
313 1 : EXPECT_NEAR(ul.lowerRight.value, 224.930002, 0.000001);
314 1 : EXPECT_NEAR(ul.upperRight.value, 224.990005, 0.000001);
315 1 : EXPECT_NEAR(ll.lowerRight.value, 224.900001, 0.000001);
316 :
317 1 : EXPECT_EQ(ul.lowerLeft.x, ll.upperLeft.x);
318 1 : EXPECT_EQ(ul.lowerLeft.y, ll.upperLeft.y);
319 1 : EXPECT_EQ(ul.lowerLeft.value, ll.upperLeft.value);
320 :
321 1 : EXPECT_EQ(ul.lowerRight.x, ll.upperRight.x);
322 1 : EXPECT_EQ(ul.lowerRight.y, ll.upperRight.y);
323 1 : EXPECT_EQ(ul.lowerRight.value, ll.upperRight.value);
324 :
325 : const Square::Segments segments_up(
326 1 : ul.segments(225, -std::numeric_limits<double>::infinity()));
327 : const Square::Segments segments_down(
328 1 : ll.segments(225, -std::numeric_limits<double>::infinity()));
329 :
330 : // segments on 225
331 : //
332 : // 224.990005 224.990005 NaN
333 : // <--------<---------+
334 : // | | |
335 : // o_ | |
336 : // | \ | |
337 : // >--o-----< 224.930002
338 : // 225.01|002 | |
339 : // | \ | |
340 : // | |224.900001 |
341 : // >---o----<---------+
342 : // 225.029999 224.770004
343 :
344 1 : EXPECT_EQ(segments_up.size(), 1);
345 1 : EXPECT_EQ(segments_down.size(), 1);
346 :
347 : // the two segments have a point in common
348 1 : EXPECT_EQ(segments_up[0].second, segments_down[0].first);
349 1 : }
350 :
351 4 : TEST_F(test_ms_square, border_test_1)
352 : {
353 : // Border test 1
354 1 : const Square square(ValuedPoint(0.5, 0.5, NaN), ValuedPoint(1.5, 0.5, NaN),
355 1 : ValuedPoint(0.5, 1.5, 272.87),
356 2 : ValuedPoint(1.5, 1.5, 272.93));
357 : //
358 : // NaN NaN
359 : // +------------------+
360 : // | |
361 : // | |
362 : // | |
363 : // | |
364 : // | |
365 : // | |
366 : // | |
367 : // +------------------+
368 : // 272.87 272.93
369 1 : const Square ll(square.lowerLeftSquare());
370 1 : const Square lr(square.lowerRightSquare());
371 :
372 : //
373 : // NaN NaN
374 : // +------------------+
375 : // | |
376 : // | |
377 : // 272.87 272.90000 272.93
378 : // +--------+---------+
379 : // | | |
380 : // | | |
381 : // | | |
382 : // +--------+---------+
383 : // 272.87 272.90000 272.93
384 :
385 : Square::Segments segments_l(
386 1 : ll.segments(272.9, -std::numeric_limits<double>::infinity()));
387 : Square::Segments segments_r(
388 1 : lr.segments(272.9, -std::numeric_limits<double>::infinity()));
389 :
390 : // the level falls exactly on corners
391 : // thanks to the fudge, each corner should be shifted away a bit
392 :
393 : //
394 : // NaN NaN
395 : // +------------------+
396 : // | |
397 : // | |
398 : // 272.87 272.90000 272.93
399 : // <-------o>--------->
400 : // | :| |
401 : // | :| |
402 : // | :| |
403 : // <-------o>--------->
404 : // 272.87 272.90000 272.93
405 :
406 1 : EXPECT_EQ(segments_l.size(), size_t(1));
407 1 : EXPECT_EQ(segments_r.size(), size_t(0));
408 1 : }
409 :
410 4 : TEST_F(test_ms_square, multiple_levels)
411 : {
412 : // Multiple levels
413 : const Square square(
414 1 : ValuedPoint(0.5, 1.5, 272.99), ValuedPoint(1.5, 1.5, NaN),
415 2 : ValuedPoint(0.5, 0.5, 273.03), ValuedPoint(1.5, 0.5, 272.9));
416 : //
417 : // 272.99 NaN
418 : // +------------------+
419 : // | |
420 : // | |
421 : // | |
422 : // | |
423 : // | |
424 : // | |
425 : // | |
426 : // +------------------+
427 : // 273.03 272.90
428 :
429 1 : const Square ul(square.upperLeftSquare());
430 :
431 : //
432 : // 272.99 272.99 NaN
433 : // +---------+--------+
434 : // | | |
435 : // | | |
436 : // | | |
437 : // +---------+ |
438 : // 273.01 272.97 |
439 : // | |
440 : // | |
441 : // +------------------+
442 : // 273.03 272.90
443 1 : EXPECT_TRUE((std::fabs(ul.lowerLeft.value - 273.01) < 0.01));
444 1 : EXPECT_TRUE((std::fabs(ul.lowerRight.value - 272.97) < 0.01));
445 1 : EXPECT_TRUE((std::fabs(ul.upperRight.value - 272.99) < 0.01));
446 :
447 : // We have a NaN value on the right, we should then have a right border
448 1 : EXPECT_TRUE((ul.borders == Square::RIGHT_BORDER));
449 :
450 2 : Writer writer;
451 : // levels starting at min and increasing by 0.1
452 : IntervalLevelRangeIterator levelGenerator(
453 1 : 0, .1, -std::numeric_limits<double>::infinity());
454 :
455 1 : ul.process(levelGenerator, writer);
456 :
457 : // we only have a contour when level = 273.0
458 : // (0.5, 1.5) (1.5, 1.5)
459 : // 272.99 272.99 NaN
460 : // +---------+--------+
461 : // | || |
462 : // o || |
463 : // |\ || |
464 : // +-o-------+ |
465 : // 273.01 272.97 |
466 : // | |
467 : // | |
468 : // +------------------+
469 : // 273.03 272.90
470 : // (0.5, 0.5) (1.5, 0.5)
471 :
472 1 : EXPECT_TRUE((writer.contours.size() == 2));
473 1 : EXPECT_TRUE((writer.borders.size() == 1));
474 1 : EXPECT_TRUE((writer.contours.find(2730) != writer.contours.end()));
475 1 : EXPECT_TRUE((writer.contours.find(2731) != writer.contours.end()));
476 1 : EXPECT_TRUE((writer.borders.find(2730) != writer.borders.end()));
477 : // we have one segment border on the right
478 1 : EXPECT_TRUE((writer.borders[2730].size() == 1));
479 1 : EXPECT_TRUE((writer.contours[2730].size() == 1));
480 1 : EXPECT_TRUE((writer.contours[2731].size() == 1));
481 1 : }
482 :
483 4 : TEST_F(test_ms_square, border_test_3)
484 : {
485 : // Border test 3
486 1 : Square square(ValuedPoint(0, 0, 10), ValuedPoint(1, 0, 5),
487 2 : ValuedPoint(0, 1, NaN), ValuedPoint(1, 1, 4));
488 : // level value = 7
489 : // 10 7.5 5
490 : // +---------+--------+
491 : // | | |
492 : // | _o |
493 : // | _/ | |
494 : // 10 +====o====+ 6.33 |
495 : // | |
496 : // | |
497 : // | |
498 : // +------------------+
499 : // NaN 4
500 1 : const Square ul(square.upperLeftSquare());
501 : // "Lower left value",
502 1 : EXPECT_TRUE((std::fabs(ul.lowerLeft.value - 10.00) < 0.01));
503 : // "Lower right value",
504 1 : EXPECT_TRUE((std::fabs(ul.lowerRight.value - 6.33) < 0.01));
505 : // "Upper right value",
506 1 : EXPECT_TRUE((std::fabs(ul.upperRight.value - 7.50) < 0.01));
507 :
508 : // We have a NaN value on the right, we should then have a right border
509 : // "We have the lower border",
510 1 : EXPECT_TRUE(ul.borders == Square::LOWER_BORDER);
511 :
512 : {
513 : // ... with a level interval
514 2 : Writer writer;
515 : IntervalLevelRangeIterator levelGenerator(
516 1 : 7, 5, -std::numeric_limits<double>::infinity());
517 1 : ul.process(levelGenerator, writer);
518 :
519 : // we have one contour at 7 and 12
520 : // and two borders: one, at 7 and the second at >7 (12)
521 : // "We have 2 borders",
522 1 : EXPECT_EQ(writer.borders.size(), size_t(2));
523 : // "We have 2 contours",
524 1 : EXPECT_EQ(writer.contours.size(), size_t(2));
525 :
526 : // "Border at 0",
527 1 : EXPECT_TRUE(writer.borders.find(0) != writer.borders.end());
528 : // "Border at 1",
529 1 : EXPECT_TRUE(writer.borders.find(1) != writer.borders.end());
530 : // "No contour at 0",
531 1 : EXPECT_TRUE(writer.contours.find(0) != writer.contours.end());
532 : // and we have one contour and 2 borders
533 : // "1 contour at 0",
534 1 : EXPECT_EQ(writer.contours[0].size(), size_t(1));
535 : // "1 border at 0",
536 1 : EXPECT_EQ(writer.borders[0].size(), size_t(1));
537 : // "1 border at 1",
538 1 : EXPECT_EQ(writer.borders[1].size(), size_t(1));
539 : // the border at 7.0 is around 0.5, 0.5
540 : // "Border at 1 is around 0.5, 0.5",
541 1 : EXPECT_TRUE((writer.borders[0][0].first.x == 0.5 &&
542 : writer.borders[0][0].first.y == 0.5) ||
543 : (writer.borders[0][0].second.x == 0.5 &&
544 : writer.borders[0][0].second.y == 0.5));
545 : // the border at 12.0 is around 0, 0.5
546 : // "Border at 1 is around 0, 0.5",
547 1 : EXPECT_TRUE((writer.borders[1][0].first.x == 0.0 &&
548 : writer.borders[1][0].first.y == 0.5) ||
549 : (writer.borders[1][0].second.x == 0.0 &&
550 : writer.borders[1][0].second.y == 0.5));
551 : }
552 :
553 : // test with a fixed set of levels
554 : {
555 2 : Writer writer;
556 2 : std::vector<double> levels = {7.0};
557 : FixedLevelRangeIterator levelGenerator(
558 1 : &levels[0], 1, -std::numeric_limits<double>::infinity(),
559 2 : std::numeric_limits<double>::infinity());
560 1 : ul.process(levelGenerator, writer);
561 :
562 : // we have one contour at 7 and 12
563 : // and two borders: one, at 7 and the second at >7 (12)
564 : // "We have 2 borders",
565 1 : EXPECT_EQ(writer.borders.size(), size_t(2));
566 : // "We have 2 contours",
567 1 : EXPECT_EQ(writer.contours.size(), size_t(2));
568 :
569 : // "Border at 0",
570 1 : EXPECT_TRUE(writer.borders.find(0) != writer.borders.end());
571 : // "Border at 1",
572 1 : EXPECT_TRUE(writer.borders.find(1) != writer.borders.end());
573 : // "No contour at 0",
574 1 : EXPECT_TRUE(writer.contours.find(0) != writer.contours.end());
575 : // and we have one contour and 2 borders
576 : // "1 contour at 0",
577 1 : EXPECT_EQ(writer.contours[0].size(), size_t(1));
578 : // "1 border at 0",
579 1 : EXPECT_EQ(writer.borders[0].size(), size_t(1));
580 : // "1 border at 1",
581 1 : EXPECT_EQ(writer.borders[1].size(), size_t(1));
582 : // the border at 7.0 is around 0.5, 0.5
583 : // "Border at 1 is around 0.5, 0.5",
584 1 : EXPECT_TRUE((writer.borders[0][0].first.x == 0.5 &&
585 : writer.borders[0][0].first.y == 0.5) ||
586 : (writer.borders[0][0].second.x == 0.5 &&
587 : writer.borders[0][0].second.y == 0.5));
588 : // the border at 12.0 is around 0, 0.5
589 : // "Border at 1 is around 0, 0.5",
590 1 : EXPECT_TRUE((writer.borders[1][0].first.x == 0.0 &&
591 : writer.borders[1][0].first.y == 0.5) ||
592 : (writer.borders[1][0].second.x == 0.0 &&
593 : writer.borders[1][0].second.y == 0.5));
594 : }
595 1 : }
596 :
597 4 : TEST_F(test_ms_square, level_value_below_square_values)
598 : {
599 : // Test level value below square values
600 1 : Square square(ValuedPoint(0, 0, 10), ValuedPoint(1, 0, 5),
601 2 : ValuedPoint(0, 1, 8), ValuedPoint(1, 1, 4));
602 : // level value = 2
603 : // 10 5
604 : // +------------------+
605 : // | |
606 : // | |
607 : // | |
608 : // | |
609 : // | |
610 : // | |
611 : // | |
612 : // +------------------+
613 : // 8 4
614 : {
615 2 : Writer writer;
616 2 : std::vector<double> levels = {2.0};
617 : FixedLevelRangeIterator levelGenerator(
618 1 : &levels[0], 1, -std::numeric_limits<double>::infinity(),
619 2 : std::numeric_limits<double>::infinity());
620 1 : square.process(levelGenerator, writer);
621 1 : EXPECT_TRUE((writer.borders.size() == 0));
622 1 : EXPECT_TRUE((writer.contours.size() == 0));
623 : }
624 1 : }
625 :
626 4 : TEST_F(test_ms_square, full_border_test_1)
627 : {
628 : // Full border test 1
629 1 : Square square(ValuedPoint(-0.5, -0.5, NaN), ValuedPoint(0.5, -0.5, NaN),
630 2 : ValuedPoint(-0.5, 0.5, NaN), ValuedPoint(0.5, 0.5, 5));
631 : // level value = 0, 10
632 : // NaN NaN
633 : // +------------------+
634 : // | |
635 : // | |
636 : // | |
637 : // | |
638 : // | |
639 : // | |
640 : // | |
641 : // +------------------+
642 : // NaN 5
643 : {
644 2 : Writer writer;
645 : IntervalLevelRangeIterator levelGenerator(
646 1 : 0, 10.0, -std::numeric_limits<double>::infinity());
647 1 : square.process(levelGenerator, writer);
648 1 : EXPECT_TRUE((writer.borders.size() == 1));
649 1 : EXPECT_TRUE((writer.borders[1].size() == 2));
650 1 : EXPECT_TRUE(((writer.borders[1][0].first.x == 0.0 &&
651 : writer.borders[1][0].first.y == 0.0) ||
652 : (writer.borders[1][0].second.x == 0.0 &&
653 : writer.borders[1][0].second.y == 0.0)));
654 1 : EXPECT_TRUE(((writer.borders[1][0].first.x == 0.5 &&
655 : writer.borders[1][0].first.y == 0.0) ||
656 : (writer.borders[1][0].second.x == 0.5 &&
657 : writer.borders[1][0].second.y == 0.0)));
658 1 : EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
659 : writer.borders[1][1].first.y == 0.0) ||
660 : (writer.borders[1][1].second.x == 0.0 &&
661 : writer.borders[1][1].second.y == 0.0)));
662 1 : EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
663 : writer.borders[1][1].first.y == 0.0) ||
664 : (writer.borders[1][1].second.x == 0.0 &&
665 : writer.borders[1][1].second.y == 0.5)));
666 : }
667 1 : }
668 :
669 4 : TEST_F(test_ms_square, full_border_test_2)
670 : {
671 : // Full border test 2
672 1 : Square square(ValuedPoint(-0.5, -0.5, NaN), ValuedPoint(0.5, -0.5, NaN),
673 2 : ValuedPoint(-0.5, 0.5, NaN), ValuedPoint(0.5, 0.5, 5));
674 : // level value = 5.0, 10.0
675 : // NaN NaN
676 : // +------------------+
677 : // | |
678 : // | |
679 : // | |
680 : // | |
681 : // | |
682 : // | |
683 : // | |
684 : // +------------------+
685 : // NaN 5
686 : {
687 2 : Writer writer;
688 : IntervalLevelRangeIterator levelGenerator(
689 1 : 5.0, 5.0, -std::numeric_limits<double>::infinity());
690 1 : square.process(levelGenerator, writer);
691 1 : EXPECT_TRUE((writer.borders.size() == 1));
692 1 : EXPECT_TRUE((writer.borders[1].size() == 2));
693 1 : EXPECT_TRUE(((writer.borders[1][0].first.x == 0.0 &&
694 : writer.borders[1][0].first.y == 0.0) ||
695 : (writer.borders[1][0].second.x == 0.0 &&
696 : writer.borders[1][0].second.y == 0.0)));
697 1 : EXPECT_TRUE(((writer.borders[1][0].first.x == 0.5 &&
698 : writer.borders[1][0].first.y == 0.0) ||
699 : (writer.borders[1][0].second.x == 0.5 &&
700 : writer.borders[1][0].second.y == 0.0)));
701 1 : EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
702 : writer.borders[1][1].first.y == 0.0) ||
703 : (writer.borders[1][1].second.x == 0.0 &&
704 : writer.borders[1][1].second.y == 0.0)));
705 1 : EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
706 : writer.borders[1][1].first.y == 0.0) ||
707 : (writer.borders[1][1].second.x == 0.0 &&
708 : writer.borders[1][1].second.y == 0.5)));
709 : }
710 : {
711 2 : Writer writer;
712 2 : std::vector<double> levels = {5.0};
713 : FixedLevelRangeIterator levelGenerator(
714 1 : &levels[0], 1, -std::numeric_limits<double>::infinity(),
715 2 : std::numeric_limits<double>::infinity());
716 1 : square.process(levelGenerator, writer);
717 1 : EXPECT_TRUE((writer.borders.size() == 1));
718 1 : EXPECT_TRUE((writer.borders[1].size() == 2));
719 1 : EXPECT_TRUE(((writer.borders[1][0].first.x == 0.0 &&
720 : writer.borders[1][0].first.y == 0.0) ||
721 : (writer.borders[1][0].second.x == 0.0 &&
722 : writer.borders[1][0].second.y == 0.0)));
723 1 : EXPECT_TRUE(((writer.borders[1][0].first.x == 0.5 &&
724 : writer.borders[1][0].first.y == 0.0) ||
725 : (writer.borders[1][0].second.x == 0.5 &&
726 : writer.borders[1][0].second.y == 0.0)));
727 1 : EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
728 : writer.borders[1][1].first.y == 0.0) ||
729 : (writer.borders[1][1].second.x == 0.0 &&
730 : writer.borders[1][1].second.y == 0.0)));
731 1 : EXPECT_TRUE(((writer.borders[1][1].first.x == 0.0 &&
732 : writer.borders[1][1].first.y == 0.0) ||
733 : (writer.borders[1][1].second.x == 0.0 &&
734 : writer.borders[1][1].second.y == 0.5)));
735 : }
736 1 : }
737 : } // namespace test_marching_squares_square
738 :
739 : #if defined(__clang__)
740 : #pragma clang diagnostic pop
741 : #endif
|