Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / geometry / test / algorithms / set_operations / difference / difference.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands.
5
6 // This file was modified by Oracle on 2015, 2016.
7 // Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
14
15 #include <iomanip>
16 #include <iostream>
17 #include <sstream>
18 #include <string>
19
20 #include <boost/geometry/algorithms/correct.hpp>
21 #include <boost/geometry/algorithms/is_valid.hpp>
22
23 #include <boost/geometry/io/wkt/wkt.hpp>
24
25 #include <boost/geometry/geometries/point_xy.hpp>
26
27 #include "test_difference.hpp"
28 #include <algorithms/test_overlay.hpp>
29 #include <algorithms/overlay/overlay_cases.hpp>
30 #include <algorithms/overlay/multi_overlay_cases.hpp>
31
32
33 #ifdef HAVE_TTMATH
34 #  include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
35 #endif
36
37
38 // Convenience macros (points are not checked)
39 #define TEST_DIFFERENCE(caseid, clips1, area1, clips2, area2, clips3) \
40     (test_one<polygon, polygon, polygon>) \
41     ( #caseid, caseid[0], caseid[1], clips1, -1, area1, clips2, -1, area2, \
42                 clips3, -1, area1 + area2)
43
44 #define TEST_DIFFERENCE_WITH(caseid, clips1, area1, clips2, area2, clips3) \
45     (test_one<polygon, polygon, polygon>) \
46     ( #caseid, caseid[0], caseid[1], clips1, -1, area1, clips2, -1, area2, \
47                 clips3, -1, area1 + area2, settings)
48
49 template <typename P>
50 void test_all()
51 {
52     typedef bg::model::polygon<P> polygon;
53
54     typedef typename bg::coordinate_type<P>::type ct;
55
56     ut_settings sym_settings;
57 #if ! defined(BOOST_GEOMETRY_USE_RESCALING)
58     sym_settings.sym_difference = false;
59 #endif
60
61     ut_settings ignore_validity_settings;
62     ignore_validity_settings.test_validity = false;
63
64     test_one<polygon, polygon, polygon>("simplex_normal",
65         simplex_normal[0], simplex_normal[1],
66         3, 12, 2.52636706856656,
67         3, 12, 3.52636706856656,
68         sym_settings);
69
70     test_one<polygon, polygon, polygon>("simplex_with_empty",
71         simplex_normal[0], polygon_empty,
72         1, 4, 8.0,
73         0, 0, 0.0);
74
75     test_one<polygon, polygon, polygon>(
76             "star_ring", example_star, example_ring,
77             5, 22, 1.1901714,
78             5, 27, 1.6701714,
79             sym_settings);
80
81     test_one<polygon, polygon, polygon>("two_bends",
82         two_bends[0], two_bends[1],
83         1, 5, 8.0,
84         1, 5, 8.0);
85
86     test_one<polygon, polygon, polygon>("star_comb_15",
87         star_comb_15[0], star_comb_15[1],
88         30, -1, 227.658275102812,
89         30, -1, 480.485775259312,
90         sym_settings);
91
92     test_one<polygon, polygon, polygon>("new_hole",
93         new_hole[0], new_hole[1],
94         1, 9, 7.0,
95         1, 13, 14.0);
96
97
98     test_one<polygon, polygon, polygon>("crossed",
99         crossed[0], crossed[1],
100         1, 18, 19.5,
101         1, 7, 2.5);
102
103     test_one<polygon, polygon, polygon>("disjoint",
104         disjoint[0], disjoint[1],
105         1, 5, 1.0,
106         1, 5, 1.0);
107
108     // The too small one might be discarded (depending on point-type / compiler)
109     // We check area only
110     test_one<polygon, polygon, polygon>("distance_zero",
111         distance_zero[0], distance_zero[1],
112         -1, -1, 8.7048386,
113         -1, -1, 0.0098387,
114         tolerance(0.001));
115
116     test_one<polygon, polygon, polygon>("equal_holes_disjoint",
117         equal_holes_disjoint[0], equal_holes_disjoint[1],
118         1, 5, 9.0,
119         1, 5, 9.0);
120
121     test_one<polygon, polygon, polygon>("only_hole_intersections1",
122         only_hole_intersections[0], only_hole_intersections[1],
123         2, 10,  1.9090909,
124         4, 16, 10.9090909,
125         sym_settings);
126
127     test_one<polygon, polygon, polygon>("only_hole_intersection2",
128         only_hole_intersections[0], only_hole_intersections[2],
129         3, 20, 30.9090909,
130         4, 16, 10.9090909,
131         sym_settings);
132
133     test_one<polygon, polygon, polygon>("first_within_second",
134         first_within_second[1], first_within_second[0],
135         1, 10, 24,
136         0, 0, 0);
137
138     test_one<polygon, polygon, polygon>("fitting",
139         fitting[0], fitting[1],
140         1, 9, 21.0,
141         1, 4, 4.0,
142         1, 5, 25.0);
143
144     test_one<polygon, polygon, polygon>("identical",
145         identical[0], identical[1],
146         0, 0, 0.0,
147         0, 0, 0.0);
148
149     test_one<polygon, polygon, polygon>("intersect_exterior_and_interiors_winded",
150         intersect_exterior_and_interiors_winded[0], intersect_exterior_and_interiors_winded[1],
151         4, 20, 11.533333,
152         5, 26, 29.783333);
153
154     test_one<polygon, polygon, polygon>("intersect_holes_intersect_and_disjoint",
155         intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1],
156         2, 16, 15.75,
157         3, 17, 6.75,
158         ignore_validity_settings);
159
160     test_one<polygon, polygon, polygon>("intersect_holes_intersect_and_touch",
161         intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1],
162         3, 21, 16.25,
163         3, 17, 6.25,
164         ignore_validity_settings);
165
166     {
167         ut_settings settings = sym_settings;
168         settings.percentage = 0.01;
169         test_one<polygon, polygon, polygon>("intersect_holes_new_ring",
170             intersect_holes_new_ring[0], intersect_holes_new_ring[1],
171             3, 15, 9.8961,
172             4, 25, 121.8961,
173             settings);
174     }
175
176     test_one<polygon, polygon, polygon>("first_within_hole_of_second",
177         first_within_hole_of_second[0], first_within_hole_of_second[1],
178         1, 5, 1,
179         1, 10, 16);
180
181     test_one<polygon, polygon, polygon>("intersect_holes_disjoint",
182         intersect_holes_disjoint[0], intersect_holes_disjoint[1],
183         2, 14, 16.0,
184         2, 10, 6.0);
185
186     test_one<polygon, polygon, polygon>("intersect_holes_intersect",
187         intersect_holes_intersect[0], intersect_holes_intersect[1],
188         2, 16, 15.75,
189         2, 12, 5.75,
190         ignore_validity_settings);
191
192     test_one<polygon, polygon, polygon>(
193             "case4", case_4[0], case_4[1],
194             6, 28, 2.77878787878788,
195             4, 22, 4.77878787878788,
196             sym_settings);
197
198     test_one<polygon, polygon, polygon>(
199             "case5", case_5[0], case_5[1],
200             8, 36, 2.43452380952381,
201             7, 33, 3.18452380952381);
202
203 #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
204     // Fails with rescaling, a-b is partly generated, b-a does not have any output
205     // It failed already in 1.59
206     test_one<polygon, polygon, polygon>("case_58_iet",
207         case_58[0], case_58[2],
208         3, 12, 0.6666666667,
209         1, -1, 11.1666666667,
210         2, -1, 0.6666666667 + 11.1666666667);
211 #endif
212
213     test_one<polygon, polygon, polygon>("case_80",
214         case_80[0], case_80[1],
215         1, 9, 44.5,
216         1, 10, 84.5);
217
218 #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
219     // Fails without rescaling, holes are not subtracted
220     test_one<polygon, polygon, polygon>("case_81",
221         case_81[0], case_81[1],
222         1, 8, 80.5,
223         1, 8, 83.0,
224         1, 12, 80.5 + 83.0);
225 #endif
226
227     test_one<polygon, polygon, polygon>("case_100",
228         case_100[0], case_100[1],
229         1, 7, 3.125,
230         1, 7, 16.0,
231         1, 13, 16.0 + 3.125);
232
233     test_one<polygon, polygon, polygon>("case_101",
234         case_101[0], case_101[1],
235         3, 17, 13.75,
236         1, 4, 1.0);
237
238     test_one<polygon, polygon, polygon>("case_102",
239         case_102[0], case_102[1],
240         4, 18, 1.5,
241         3, 15, 4.0625);
242
243     TEST_DIFFERENCE(case_105, 4, 8.0, 1, 16.0, 5);
244     TEST_DIFFERENCE(case_106, 1, 17.5, 2, 32.5, 3);
245     TEST_DIFFERENCE(case_107, 2, 18.0, 2, 29.0, 4);
246
247     TEST_DIFFERENCE(case_precision_1, 1, 14.0, 1, BG_IF_KRAMER(8.00001, 8.0), 1);
248     TEST_DIFFERENCE(case_precision_2, 1, 14.0, 1, 8.0, 1);
249     TEST_DIFFERENCE(case_precision_3, 1, 14.0, 1, 8.0, 1);
250     TEST_DIFFERENCE(case_precision_4, 1, 14.0, 1, 8.0, 1);
251 #if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES)
252     TEST_DIFFERENCE(case_precision_5, 1, 14.0, 1, 8.0, 1);
253     TEST_DIFFERENCE(case_precision_6, 0, 0.0, 1, 57.0, 1);
254 #endif
255     TEST_DIFFERENCE(case_precision_7, 1, 14.0, 1, 8.0, 1);
256     TEST_DIFFERENCE(case_precision_8, 0, 0.0, 1, 59.0, 1);
257 #if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES)
258     TEST_DIFFERENCE(case_precision_9, 0, 0.0, 1, 59.0, 1);
259     TEST_DIFFERENCE(case_precision_10, 0, 0.0, 1, 59.0, 1);
260     TEST_DIFFERENCE(case_precision_11, 0, 0.0, 1, 59.0, 1);
261 #endif
262     TEST_DIFFERENCE(case_precision_12, 1, 12.0, 0, 0.0, 1);
263     TEST_DIFFERENCE(case_precision_13, 1, BG_IF_KRAMER(12.00002, 12.0), 0, 0.0, 1);
264     TEST_DIFFERENCE(case_precision_14, 1, 14.0, 1, 8.0, 1);
265     TEST_DIFFERENCE(case_precision_15, 0, 0.0, 1, 59.0, 1);
266 #if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES)
267     TEST_DIFFERENCE(case_precision_16, 0, 0.0, 1, 59.0, 1);
268 #endif
269     TEST_DIFFERENCE(case_precision_17, 0, 0.0, 1, 59.0, 1);
270     TEST_DIFFERENCE(case_precision_18, 0, 0.0, 1, 59.0, 1);
271 #if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES)
272     TEST_DIFFERENCE(case_precision_19, 1, 0.0, 1, 59.0, 2);
273 #endif
274     TEST_DIFFERENCE(case_precision_20, 1, 14.0, 1, 8.0, 1);
275     TEST_DIFFERENCE(case_precision_21, 1, 14.0, 1, 7.99999, 1);
276 #if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES)
277     TEST_DIFFERENCE(case_precision_22, 0, 0.0, 1, 59.0, 1);
278     TEST_DIFFERENCE(case_precision_23, 0, 0.0, 1, 59.0, 1);
279 #endif
280     TEST_DIFFERENCE(case_precision_24, 1, 14.0, 1, 8.0, 1);
281     TEST_DIFFERENCE(case_precision_25, 1, 14.0, 1, 7.99999, 1);
282 #if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES)
283     TEST_DIFFERENCE(case_precision_26, 0, 0.0, 1, 59.0, 1);
284 #endif
285
286     test_one<polygon, polygon, polygon>("winded",
287         winded[0], winded[1],
288         3, 37, 61,
289         1, 15, 13);
290
291     test_one<polygon, polygon, polygon>("within_holes_disjoint",
292         within_holes_disjoint[0], within_holes_disjoint[1],
293         2, 15, 25,
294         1, 5, 1);
295
296     test_one<polygon, polygon, polygon>("side_side",
297         side_side[0], side_side[1],
298         1, 5, 1,
299         1, 5, 1,
300         1, 7, 2);
301
302     test_one<polygon, polygon, polygon>("buffer_mp1",
303         buffer_mp1[0], buffer_mp1[1],
304         1, 61, 10.2717,
305         1, 61, 10.2717);
306
307     if ( BOOST_GEOMETRY_CONDITION((boost::is_same<ct, double>::value)) )
308     {
309         test_one<polygon, polygon, polygon>("buffer_mp2",
310             buffer_mp2[0], buffer_mp2[1],
311             1, 91, 12.09857,
312             1, 155, 24.19714,
313             BG_IF_RESCALED(2, 1), -1, 12.09857 + 24.19714);
314     }
315
316     /*** TODO: self-tangencies for difference
317     test_one<polygon, polygon, polygon>("wrapped_a",
318         wrapped[0], wrapped[1],
319         3, 1, 61,
320         1, 0, 13);
321
322     test_one<polygon, polygon, polygon>("wrapped_b",
323         wrapped[0], wrapped[2],
324         3, 1, 61,
325         1, 0, 13);
326     ***/
327
328     {
329         ut_settings settings;
330         settings.percentage = BG_IF_RESCALED(0.001, 0.1);
331         settings.test_validity = BG_IF_RESCALED(true, false);
332         settings.sym_difference = BG_IF_RESCALED(true, false);
333
334         // Isovist - the # output polygons differ per compiler/pointtype, (very) small
335         // rings might be discarded. We check area only
336
337         // SQL Server gives:    0.279121891701124 and 224.889211358929
338         // PostGIS gives:       0.279121991127244 and 224.889205853156
339         // No robustness gives: 0.279121991127106 and 224.825363749290
340
341         test_one<polygon, polygon, polygon>("isovist",
342             isovist1[0], isovist1[1],
343             -1, -1, 0.279132,
344             -1, -1, 224.8892,
345             settings);
346     }
347
348 #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
349     {
350         ut_settings settings;
351         settings.percentage = 0.1;
352         settings.test_validity = false;
353
354         // SQL Server gives: 0.28937764436705 and 0.000786406897532288 with 44/35 rings
355         // PostGIS gives:    0.30859375       and 0.033203125 with 35/35 rings
356         TEST_DIFFERENCE_WITH(geos_1,
357             -1, BG_IF_KRAMER(0.29171, 0.20705),
358             -1, BG_IF_KRAMER(0.00076855, 0.00060440758),
359             -1);
360     }
361 #endif
362
363     {
364         // MSVC 14 expects 138.69214 and 211.85913: increase percentage
365
366         ut_settings settings = sym_settings;
367         settings.percentage = 0.01;
368         settings.test_validity = false;
369
370         // Output polygons for sym difference might be combined
371         test_one<polygon, polygon, polygon>("geos_2",
372             geos_2[0], geos_2[1],
373             1, -1, 138.6923828,
374             1, -1, 211.859375,
375             BG_IF_RESCALED(2, 1), -1, 138.6923828 + 211.859375,
376             settings);
377     }
378
379     // Output polygons for sym difference might be combined
380     test_one<polygon, polygon, polygon>("geos_3",
381         geos_3[0], geos_3[1],
382         1, -1, 16211128.5,
383         1, -1, 13180420.0,
384         BG_IF_RESCALED(1, 2), -1, 16211128.5 + 13180420.0,
385         sym_settings);
386
387     test_one<polygon, polygon, polygon>("geos_4",
388         geos_4[0], geos_4[1],
389         1, -1, 971.9163115,
390         1, -1, 1332.4163115,
391         sym_settings);
392
393     test_one<polygon, polygon, polygon>("ggl_list_20110306_javier",
394         ggl_list_20110306_javier[0], ggl_list_20110306_javier[1],
395         1, -1, 71495.3331,
396         2, -1, 8960.49049,
397         2, -1, 71495.3331 + 8960.49049);
398
399     test_one<polygon, polygon, polygon>("ggl_list_20110307_javier",
400         ggl_list_20110307_javier[0], ggl_list_20110307_javier[1],
401         1, if_typed<ct, float>(14, 13), 16815.6,
402         1, 4, 3200.4,
403         tolerance(0.01));
404
405     if ( BOOST_GEOMETRY_CONDITION((! boost::is_same<ct, float>::value)) )
406     {
407         TEST_DIFFERENCE(ggl_list_20110716_enrico,
408             3, 35723.8506317139, // TODO FOR GENERIC, misses one of three outputs
409             1, 58456.4964294434,
410             1);
411     }
412
413 #if defined(BOOST_GEOMETRY_USE_RESCALING) \
414     || ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) \
415     || defined(BOOST_GEOMETRY_TEST_FAILURES)
416     {
417         // Symmetric difference should output one polygon
418         // Using rescaling, it currently outputs two.
419         ut_settings settings;
420         settings.test_validity = false;
421
422         TEST_DIFFERENCE_WITH(ggl_list_20110820_christophe,
423             1, 2.8570121719168924,
424             1, 64.498061986388564,
425             BG_IF_RESCALED(2, 1));
426     }
427 #endif
428
429     test_one<polygon, polygon, polygon>("ggl_list_20120717_volker",
430         ggl_list_20120717_volker[0], ggl_list_20120717_volker[1],
431         1, 11, 3370866.2295081965,
432         1, 5, 384.2295081964694,
433         tolerance(0.01));
434
435     // 2011-07-02 / 2014-06-19
436     // Interesting FP-precision case.
437     // sql server gives: 6.62295817619452E-05
438     // PostGIS gives: 0.0 (no output)
439     // Boost.Geometry gave results depending on FP-type, and compiler, and operating system.
440     // With rescaling results are equal w.r.t. compiler/FP type,
441     // however, some long spikes are still generated in the resulting difference
442     // Without rescaling there is no output, like PostGIS
443     test_one<polygon, polygon, polygon>("ggl_list_20110627_phillip",
444         ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
445         BG_IF_RESCALED(1, 0), -1,
446         BG_IF_RESCALED(if_typed_tt<ct>(0.0000000000001105367, 0.000125137888971949), 0),
447         1, -1, 3577.40960816756,
448         tolerance(0.01)
449         );
450
451     {
452         // With rescaling, difference of output a-b and a sym b is invalid
453         ut_settings settings;
454         settings.test_validity = BG_IF_RESCALED(false, true);
455         TEST_DIFFERENCE_WITH(ggl_list_20190307_matthieu_1,
456                 BG_IF_KRAMER(2, 1), 0.18461532,
457                 BG_IF_KRAMER(2, 1), 0.617978,
458                 BG_IF_KRAMER(4, 2));
459         TEST_DIFFERENCE_WITH(ggl_list_20190307_matthieu_2, 2, 12.357152, 0, 0.0, 2);
460     }
461
462     // Ticket 8310, one should be completely subtracted from the other.
463     test_one<polygon, polygon, polygon>("ticket_8310a",
464         ticket_8310a[0], ticket_8310a[1],
465         1, 10, 10.11562724,
466         0, 0, 0);
467     test_one<polygon, polygon, polygon>("ticket_8310b",
468         ticket_8310b[0], ticket_8310b[1],
469         1, 10, 10.12655608,
470         0, 0, 0);
471     test_one<polygon, polygon, polygon>("ticket_8310c",
472         ticket_8310c[0], ticket_8310c[1],
473         1, 10, 10.03103292,
474         0, 0, 0);
475
476     test_one<polygon, polygon, polygon>("ticket_9081_15",
477             ticket_9081_15[0], ticket_9081_15[1],
478             2, -1, 0.0334529710902111,
479             BG_IF_RESCALED(1, 0), -1, BG_IF_RESCALED(5.3469555172380723e-010, 0));
480
481     test_one<polygon, polygon, polygon>("ticket_9081_314",
482             ticket_9081_314[0], ticket_9081_314[1],
483             2, 12, 0.0451236449624935,
484             0, 0, 0);
485
486     {
487         ut_settings settings;
488         settings.test_validity = BG_IF_RESCALED(true, false);
489 #if ! defined(BOOST_GEOMETRY_USE_RESCALING) && defined(BOOST_GEOMETRY_USE_KRAMER_RULE)
490         const int expected_count = 1; // Wrong, considers all consecutive polygons as one
491 #else
492         const int expected_count = 6;
493 #endif
494         TEST_DIFFERENCE_WITH(ticket_9563,
495                 0, 0,
496                 expected_count, 20.096189,
497                 expected_count);
498     }
499
500     test_one<polygon, polygon, polygon>("ticket_10108_a",
501             ticket_10108_a[0], ticket_10108_a[1],
502             1, 4,  0.0145037,
503             1, 4,  0.029019232,
504             sym_settings);
505
506     test_one<polygon, polygon, polygon>("ticket_10108_b",
507             ticket_10108_b[0], ticket_10108_b[1],
508             1, -1, 1081.68697,
509             1, -1, 1342.65795,
510             BG_IF_RESCALED(2, 1), -1, 1081.68697 + 1342.65795);
511
512     test_one<polygon, polygon, polygon>("ticket_11725",
513         ticket_11725[0], ticket_11725[1],
514         1, -1, 3.0,
515         1, -1, 4.5,
516         1, -1, 7.5);
517
518     // From assemble-test, with a u/u case
519     test_one<polygon, polygon, polygon>("assemble_0210",
520             "POLYGON((0 0,0 10,10 10,10 0,0 0),(8.5 1,9.5 1,9.5 2,8.5 2,8.5 1))",
521             "POLYGON((2 0.5,0.5 2,0.5 8,2 9.5,6 9.5,8.5 8,8.5 2,7 0.5,2 0.5),(2 2,7 2,7 8,2 8,2 2))",
522             2, 23, 62.25,
523             0, 0, 0.0);
524
525 #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
526     typedef bg::model::box<P> box;
527     typedef bg::model::ring<P> ring;
528
529     // Other combinations
530     {
531         test_one<polygon, polygon, ring>(
532                 "star_ring_ring", example_star, example_ring,
533                 5, 22, 1.1901714,
534                 5, 27, 1.6701714,
535                 sym_settings);
536
537         test_one<polygon, ring, polygon>(
538                 "ring_star_ring", example_ring, example_star,
539                 5, 27, 1.6701714,
540                 5, 22, 1.1901714,
541                 sym_settings);
542
543         static std::string const clip = "POLYGON((2.5 0.5,5.5 2.5))";
544
545         test_one<polygon, box, ring>("star_box",
546             clip, example_star,
547             4, 20, 2.833333, 4, 16, 0.833333);
548
549         test_one<polygon, ring, box>("box_star",
550             example_star, clip,
551             4, 16, 0.833333, 4, 20, 2.833333);
552     }
553
554     // Counter clockwise
555     {
556         typedef bg::model::polygon<P, false> polygon_ccw;
557         test_one<polygon, polygon_ccw, polygon_ccw>(
558                 "star_ring_ccw", example_star, example_ring,
559                 5, 22, 1.1901714,
560                 5, 27, 1.6701714,
561                 sym_settings);
562         test_one<polygon, polygon, polygon_ccw>(
563                 "star_ring_ccw1", example_star, example_ring,
564                 5, 22, 1.1901714,
565                 5, 27, 1.6701714,
566                 sym_settings);
567         test_one<polygon, polygon_ccw, polygon>(
568                 "star_ring_ccw2", example_star, example_ring,
569                 5, 22, 1.1901714,
570                 5, 27, 1.6701714,
571                 sym_settings);
572     }
573
574     // Multi/box (should be moved to multi)
575     {
576         typedef bg::model::multi_polygon<polygon> mp;
577
578         static std::string const clip = "POLYGON((2 2,4 4))";
579
580         test_one<polygon, box, mp>("simplex_multi_box_mp",
581             clip, case_multi_simplex[0],
582             2, -1, 0.53333333333, 3, -1, 8.53333333333);
583         test_one<polygon, mp, box>("simplex_multi_mp_box",
584             case_multi_simplex[0], clip,
585             3, -1, 8.53333333333, 2, -1, 0.53333333333);
586
587     }
588 #endif
589
590     // Rescaling generates a very small false polygon
591     {
592         ut_settings settings;
593 #if defined(BOOST_GEOMETRY_USE_KRAMER_RULE)
594         settings.test_validity = BG_IF_RESCALED(true, false);
595 #endif
596         TEST_DIFFERENCE_WITH(issue_566_a, 1, 143.662, BG_IF_RESCALED(1, 0),
597                              BG_IF_RESCALED(1.605078e-6, 0.0),
598                              BG_IF_RESCALED(2, 1));
599     }
600     TEST_DIFFERENCE(issue_566_b, 1, 143.662, BG_IF_RESCALED(1, 0),
601                     BG_IF_RESCALED(1.605078e-6, 0.0),
602                     BG_IF_RESCALED(2, 1));
603
604     TEST_DIFFERENCE(mysql_21977775, 2, 160.856568913, 2, 92.3565689126, 4);
605     TEST_DIFFERENCE(mysql_21965285, 1, 92.0, 1, 14.0, 1);
606     TEST_DIFFERENCE(mysql_23023665_1, 1, 92.0, 1, 142.5, 2);
607     TEST_DIFFERENCE(mysql_23023665_2, 1, 96.0, 1, 16.0, 2);
608     TEST_DIFFERENCE(mysql_23023665_3, 1, 225.0, 1, 66.0, 2);
609     TEST_DIFFERENCE(mysql_23023665_5, 2, 165.23735, 2, 105.73735, 4);
610 #if defined(BOOST_GEOMETRY_USE_RESCALING) \
611     || ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) \
612     || defined(BOOST_GEOMETRY_TEST_FAILURES)
613     // Testcases going wrong with Kramer's rule and no rescaling
614     TEST_DIFFERENCE(mysql_23023665_6, 2, 105.68756, 3, 10.18756, 5);
615     TEST_DIFFERENCE(mysql_23023665_13, 3, 99.74526, 3, 37.74526, 6);
616 #endif
617 }
618
619
620 // Test cases for integer coordinates / ccw / open
621 template <typename Point, bool ClockWise, bool Closed>
622 void test_specific()
623 {
624     typedef bg::model::polygon<Point, ClockWise, Closed> polygon;
625
626     test_one<polygon, polygon, polygon>("ggl_list_20120717_volker",
627         ggl_list_20120717_volker[0], ggl_list_20120717_volker[1],
628         1, 11, 3371540,
629         1, 4, 385,
630         1, 16, 3371540 + 385);
631
632     test_one<polygon, polygon, polygon>("ticket_10658",
633         ticket_10658[0], ticket_10658[1],
634         1, 6, 1510434,
635         0, 0, 0);
636
637     test_one<polygon, polygon, polygon>("ticket_11121",
638         ticket_11121[0], ticket_11121[1],
639         2, 8, 489763.5,
640         1, 4, 6731652.0);
641
642     // Generates spikes, both a-b and b-a
643     TEST_DIFFERENCE(ticket_11676, 2, 2537992.5, 2, 294963.5, 3);
644 }
645
646 int test_main(int, char* [])
647 {
648     BoostGeometryWriteTestConfiguration();
649     test_all<bg::model::d2::point_xy<default_test_type> >();
650
651     test_specific<bg::model::d2::point_xy<int>, false, false>();
652
653 #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
654     test_all<bg::model::d2::point_xy<float> >();
655
656 #ifdef HAVE_TTMATH
657     std::cout << "Testing TTMATH" << std::endl;
658     test_all<bg::model::d2::point_xy<ttmath_big> >();
659 #endif
660 #endif
661
662     return 0;
663 }