summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/polygon/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/polygon/test
parentInitial commit. (diff)
downloadceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz
ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/polygon/test')
-rw-r--r--src/boost/libs/polygon/test/Jamfile.v226
-rw-r--r--src/boost/libs/polygon/test/gtl_boost_unit_test.cpp3866
-rw-r--r--src/boost/libs/polygon/test/polygon_90_data_test.cpp52
-rw-r--r--src/boost/libs/polygon/test/polygon_interval_test.cpp271
-rw-r--r--src/boost/libs/polygon/test/polygon_point_test.cpp205
-rw-r--r--src/boost/libs/polygon/test/polygon_rectangle_formation_test.cpp44
-rw-r--r--src/boost/libs/polygon/test/polygon_rectangle_test.cpp45
-rw-r--r--src/boost/libs/polygon/test/polygon_segment_test.cpp485
-rw-r--r--src/boost/libs/polygon/test/polygon_set_data_test.cpp114
-rw-r--r--src/boost/libs/polygon/test/voronoi_builder_test.cpp681
-rw-r--r--src/boost/libs/polygon/test/voronoi_ctypes_test.cpp334
-rw-r--r--src/boost/libs/polygon/test/voronoi_diagram_test.cpp125
-rw-r--r--src/boost/libs/polygon/test/voronoi_geometry_type_test.cpp34
-rw-r--r--src/boost/libs/polygon/test/voronoi_predicates_test.cpp636
-rw-r--r--src/boost/libs/polygon/test/voronoi_robust_fpt_test.cpp405
-rw-r--r--src/boost/libs/polygon/test/voronoi_structures_test.cpp150
-rw-r--r--src/boost/libs/polygon/test/voronoi_test_helper.hpp260
17 files changed, 7733 insertions, 0 deletions
diff --git a/src/boost/libs/polygon/test/Jamfile.v2 b/src/boost/libs/polygon/test/Jamfile.v2
new file mode 100644
index 000000000..16787e3d4
--- /dev/null
+++ b/src/boost/libs/polygon/test/Jamfile.v2
@@ -0,0 +1,26 @@
+# test/Jamfile.v2 controls building of Polygon Library unit tests
+#
+# Copyright (c) 2010 Intel Corporation
+#
+# Use, modification and distribution is subject to the Boost Software License,
+# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import testing ;
+
+run polygon_point_test.cpp ;
+run polygon_segment_test.cpp ;
+run polygon_interval_test.cpp ;
+run polygon_rectangle_test.cpp ;
+run polygon_rectangle_formation_test.cpp ;
+run polygon_set_data_test.cpp ;
+run polygon_90_data_test.cpp ;
+run gtl_boost_unit_test.cpp ;
+
+run voronoi_builder_test.cpp ;
+run voronoi_ctypes_test.cpp ;
+run voronoi_diagram_test.cpp ;
+run voronoi_geometry_type_test.cpp ;
+run voronoi_predicates_test.cpp ;
+run voronoi_robust_fpt_test.cpp ;
+run voronoi_structures_test.cpp ;
diff --git a/src/boost/libs/polygon/test/gtl_boost_unit_test.cpp b/src/boost/libs/polygon/test/gtl_boost_unit_test.cpp
new file mode 100644
index 000000000..c85d5d661
--- /dev/null
+++ b/src/boost/libs/polygon/test/gtl_boost_unit_test.cpp
@@ -0,0 +1,3866 @@
+/*
+ Copyright 2008 Intel Corporation
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+*/
+#include <iostream>
+#define BOOST_POLYGON_NO_DEPS
+#include <boost/polygon/polygon.hpp>
+
+namespace gtl = boost::polygon;
+using namespace boost::polygon::operators;
+#include <time.h>
+#include <stdlib.h>
+
+void assert_s(bool c, std::string msg) {
+ if(!c) {
+ std::cout << msg << std::endl;
+ exit( 1);
+ }
+}
+
+namespace boost { namespace polygon{
+ void addpoly(polygon_45_set_data<int>& pset,
+ int* pts, unsigned int numpts) {
+ std::vector<point_data<int> > mppts;
+ for(unsigned int i = 0; i < numpts*2; i += 2) {
+ point_data<int> pt(pts[i], pts[i+1]);
+ mppts.push_back(pt);
+ }
+ polygon_45_data<int> poly;
+ poly.set(mppts.begin(), mppts.end());
+ pset += poly;
+ }
+
+ template <class T>
+ std::ostream& operator << (std::ostream& o, const interval_data<T>& i)
+ {
+ return o << i.get(LOW) << ' ' << i.get(HIGH);
+ }
+ template <class T>
+ std::ostream& operator << (std::ostream& o, const point_data<T>& r)
+ {
+ return o << r.get(HORIZONTAL) << ' ' << r.get(VERTICAL);
+ }
+ template <typename T>
+ std::ostream& operator<<(std::ostream& o, const polygon_45_data<T>& poly) {
+ o << "Polygon { ";
+ for(typename polygon_45_data<T>::iterator_type itr = poly.begin();
+ itr != poly.end(); ++itr) {
+ if(itr != poly.begin()) o << ", ";
+ o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL);
+ }
+ o << " } ";
+ return o;
+ }
+ template <typename Unit>
+ inline std::ostream& operator<< (std::ostream& o, const polygon_45_set_data<Unit>& p) {
+ o << "Polygon45Set ";
+ o << " " << !p.sorted() << " " << p.dirty() << " { ";
+ for(typename polygon_45_set_data<Unit>::iterator_type itr = p.begin();
+ itr != p.end(); ++itr) {
+ o << (*itr).pt << ":";
+ for(unsigned int i = 0; i < 4; ++i) {
+ o << (*itr).count[i] << ",";
+ } o << " ";
+ //o << (*itr).first << ":" << (*itr).second << "; ";
+ }
+ o << "} ";
+ return o;
+ }
+
+ template <typename Unit>
+ inline std::istream& operator>> (std::istream& i, polygon_45_set_data<Unit>& p) {
+ //TODO
+ return i;
+ }
+ template <typename T>
+ std::ostream& operator << (std::ostream& o, const polygon_90_data<T>& r)
+ {
+ o << "Polygon { ";
+ for(typename polygon_90_data<T>::iterator_type itr = r.begin(); itr != r.end(); ++itr) {
+ o << *itr << ", ";
+ }
+ return o << "} ";
+ }
+
+ template <typename T>
+ std::istream& operator >> (std::istream& i, polygon_90_data<T>& r)
+ {
+ std::size_t size;
+ i >> size;
+ std::vector<T> vec;
+ vec.reserve(size);
+ for(std::size_t ii = 0; ii < size; ++ii) {
+ T coord;
+ i >> coord;
+ vec.push_back(coord);
+ }
+ r.set_compact(vec.begin(), vec.end());
+ return i;
+ }
+
+ template <typename T>
+ std::ostream& operator << (std::ostream& o, const std::vector<polygon_90_data<T> >& r) {
+ o << r.size() << ' ';
+ for(std::size_t ii = 0; ii < r.size(); ++ii) {
+ o << (r[ii]);
+ }
+ return o;
+ }
+ template <typename T>
+ std::istream& operator >> (std::istream& i, std::vector<polygon_90_data<T> >& r) {
+ std::size_t size;
+ i >> size;
+ r.clear();
+ r.reserve(size);
+ for(std::size_t ii = 0; ii < size; ++ii) {
+ polygon_90_data<T> tmp;
+ i >> tmp;
+ r.push_back(tmp);
+ }
+ return i;
+ }
+ template <typename T>
+ std::ostream& operator<<(std::ostream& o, const polygon_data<T>& poly) {
+ o << "Polygon { ";
+ for(typename polygon_data<T>::iterator_type itr = poly.begin();
+ itr != poly.end(); ++itr) {
+ if(itr != poly.begin()) o << ", ";
+ o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL);
+ }
+ o << " } ";
+ return o;
+ }
+ template <typename T>
+ std::ostream& operator << (std::ostream& o, const polygon_set_data<T>& r)
+ {
+ o << "Polygon Set Data { ";
+ for(typename polygon_set_data<T>::iterator_type itr = r.begin(); itr != r.end(); ++itr) {
+ o << "<" << (*itr).first.first << ", " << (*itr).first.second << ">:" << (*itr).second << " ";
+ }
+ o << "} ";
+ return o;
+ }
+ template <typename T>
+ std::ostream& operator<<(std::ostream& o, const polygon_90_with_holes_data<T>& poly) {
+ o << "Polygon With Holes { ";
+ for(typename polygon_90_with_holes_data<T>::iterator_type itr = poly.begin();
+ itr != poly.end(); ++itr) {
+ if(itr != poly.begin()) o << ", ";
+ o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL);
+ } o << " { ";
+ for(typename polygon_90_with_holes_data<T>::iterator_holes_type itr = poly.begin_holes();
+ itr != poly.end_holes(); ++itr) {
+ o << (*itr);
+ }
+ o << " } } ";
+ return o;
+ }
+ template <typename T>
+ std::ostream& operator<<(std::ostream& o, const polygon_45_with_holes_data<T>& poly) {
+ o << "Polygon With Holes { ";
+ for(typename polygon_45_with_holes_data<T>::iterator_type itr = poly.begin();
+ itr != poly.end(); ++itr) {
+ if(itr != poly.begin()) o << ", ";
+ o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL);
+ } o << " { ";
+ for(typename polygon_45_with_holes_data<T>::iterator_holes_type itr = poly.begin_holes();
+ itr != poly.end_holes(); ++itr) {
+ o << (*itr);
+ }
+ o << " } } ";
+ return o;
+ }
+ template <typename T>
+ std::ostream& operator<<(std::ostream& o, const polygon_with_holes_data<T>& poly) {
+ o << "Polygon With Holes { ";
+ for(typename polygon_with_holes_data<T>::iterator_type itr = poly.begin();
+ itr != poly.end(); ++itr) {
+ if(itr != poly.begin()) o << ", ";
+ o << (*itr).get(HORIZONTAL) << " " << (*itr).get(VERTICAL);
+ } o << " { ";
+ for(typename polygon_with_holes_data<T>::iterator_holes_type itr = poly.begin_holes();
+ itr != poly.end_holes(); ++itr) {
+ o << (*itr);
+ }
+ o << " } } ";
+ return o;
+ }
+ template <class T>
+ std::ostream& operator << (std::ostream& o, const rectangle_data<T>& r)
+ {
+ return o << r.get(HORIZONTAL) << ' ' << r.get(VERTICAL);
+ }
+ template <class T>
+ std::ostream& operator << (std::ostream& o, const segment_data<T>& r)
+ {
+ return o << r.get(LOW) << ' ' << r.get(HIGH);
+ }
+
+
+ template <typename T>
+ typename enable_if<typename is_polygon_90_set_type<T>::type, void>::type
+ print_is_polygon_90_set_concept(const T& ) { std::cout << "is polygon 90 set concept\n"; }
+ template <typename T>
+ typename enable_if<typename is_mutable_polygon_90_set_type<T>::type, void>::type
+ print_is_mutable_polygon_90_set_concept(const T& ) { std::cout << "is mutable polygon 90 set concept\n"; }
+ namespace boolean_op {
+ //self contained unit test for BooleanOr algorithm
+ template <typename Unit>
+ inline bool testBooleanOr() {
+ BooleanOp<int, Unit> booleanOr;
+ //test one rectangle
+ std::vector<std::pair<interval_data<Unit>, int> > container;
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
+ if(container.size() != 2) {
+ std::cout << "Test one rectangle, wrong output size\n";
+ return false;
+ }
+ if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
+ std::cout << "Test one rectangle, first output wrong: Interval(" <<
+ container[0].first << "), " << container[0].second << std::endl;
+ }
+ if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
+ std::cout << "Test one rectangle, second output wrong: Interval(" <<
+ container[1].first << "), " << container[1].second << std::endl;
+ }
+
+ //test two rectangles
+ container.clear();
+ booleanOr = BooleanOp<int, Unit>();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(5, 15), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(5, 15), -1);
+ if(container.size() != 4) {
+ std::cout << "Test two rectangles, wrong output size\n";
+ for(std::size_t i = 0; i < container.size(); ++i){
+ std::cout << container[i].first << "), " << container[i].second << std::endl;
+ }
+ return false;
+ }
+ if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
+ std::cout << "Test two rectangles, first output wrong: Interval(" <<
+ container[0].first << "), " << container[0].second << std::endl;
+ }
+ if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(10, 15), 1)) {
+ std::cout << "Test two rectangles, second output wrong: Interval(" <<
+ container[1].first << "), " << container[1].second << std::endl;
+ }
+ if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 5), -1)) {
+ std::cout << "Test two rectangles, third output wrong: Interval(" <<
+ container[2].first << "), " << container[2].second << std::endl;
+ }
+ if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(5, 15), -1)) {
+ std::cout << "Test two rectangles, fourth output wrong: Interval(" <<
+ container[3].first << "), " << container[3].second << std::endl;
+ }
+
+ //test two rectangles
+ container.clear();
+ booleanOr = BooleanOp<int, Unit>();
+ booleanOr.processInterval(container, interval_data<Unit>(5, 15), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(5, 15), -1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
+ if(container.size() != 4) {
+ std::cout << "Test other two rectangles, wrong output size\n";
+ for(std::size_t i = 0; i < container.size(); ++i){
+ std::cout << container[i].first << "), " << container[i].second << std::endl;
+ }
+ return false;
+ }
+ if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(5, 15), 1)) {
+ std::cout << "Test other two rectangles, first output wrong: Interval(" <<
+ container[0].first << "), " << container[0].second << std::endl;
+ }
+ if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 5), 1)) {
+ std::cout << "Test other two rectangles, second output wrong: Interval(" <<
+ container[1].first << "), " << container[1].second << std::endl;
+ }
+ if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(10, 15), -1)) {
+ std::cout << "Test other two rectangles, third output wrong: Interval(" <<
+ container[2].first << "), " << container[2].second << std::endl;
+ }
+ if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
+ std::cout << "Test other two rectangles, fourth output wrong: Interval(" <<
+ container[3].first << "), " << container[3].second << std::endl;
+ }
+
+ //test two nonoverlapping rectangles
+ container.clear();
+ booleanOr = BooleanOp<int, Unit>();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(15, 25), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(15, 25), -1);
+ if(container.size() != 4) {
+ std::cout << "Test two nonoverlapping rectangles, wrong output size\n";
+ return false;
+ }
+ if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
+ std::cout << "Test two nonoverlapping rectangles, first output wrong: Interval(" <<
+ container[0].first << "), " << container[0].second << std::endl;
+ }
+ if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(15, 25), 1)) {
+ std::cout << "Test two nonoverlapping rectangles, second output wrong: Interval(" <<
+ container[1].first << "), " << container[1].second << std::endl;
+ }
+ if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
+ std::cout << "Test two nonoverlapping rectangles, third output wrong: Interval(" <<
+ container[2].first << "), " << container[2].second << std::endl;
+ }
+ if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(15, 25), -1)) {
+ std::cout << "Test two nonoverlapping rectangles, fourth output wrong: Interval(" <<
+ container[3].first << "), " << container[3].second << std::endl;
+ }
+ return true;
+ }
+ }
+
+ void test_assign() {
+ using namespace gtl;
+ std::vector<polygon_data<int> > ps;
+ polygon_90_set_data<int> ps90;
+ assign(ps, ps90);
+ }
+
+ //this is a compile time test, if it compiles it passes
+ void test_view_as() {
+ using namespace gtl;
+ polygon_data<int> p;
+ polygon_45_data<int> p45;
+ polygon_90_data<int> p90;
+ polygon_with_holes_data<int> pwh;
+ polygon_45_with_holes_data<int> p45wh;
+ polygon_90_with_holes_data<int> p90wh;
+ rectangle_data<int> rect(0, 1, 10, 11);
+ polygon_90_set_data<int> ps90;
+ polygon_45_set_data<int> ps45;
+ polygon_set_data<int> ps;
+
+ assign(p, rect);
+ assign(p90, view_as<polygon_90_concept>(p));
+ if(!equivalence(p90, rect))
+ std::cout << "fail 1\n";
+ assign(p45, view_as<polygon_45_concept>(p));
+ if(!equivalence(p45, rect))
+ std::cout << "fail 2\n";
+ assign(p90, view_as<polygon_90_concept>(p45));
+ if(!equivalence(p90, rect))
+ std::cout << "fail 3\n";
+ if(!equivalence(rect, view_as<rectangle_concept>(p)))
+ std::cout << "fail 4\n";
+ if(!equivalence(rect, view_as<rectangle_concept>(p45)))
+ std::cout << "fail 5\n";
+ if(!equivalence(rect, view_as<rectangle_concept>(p90)))
+ std::cout << "fail 6\n";
+ assign(pwh, rect);
+ assign(p90wh, rect);
+ assign(p45wh, rect);
+ if(!equivalence(rect, view_as<rectangle_concept>(pwh)))
+ std::cout << "fail 7\n";
+ if(!equivalence(rect, view_as<rectangle_concept>(p45wh)))
+ std::cout << "fail 8\n";
+ if(!equivalence(rect, view_as<rectangle_concept>(p90wh)))
+ std::cout << "fail 9\n";
+ assign(p90wh, view_as<polygon_90_with_holes_concept>(pwh));
+ if(!equivalence(p90wh, rect))
+ std::cout << "fail 10\n";
+ assign(p45wh, view_as<polygon_45_with_holes_concept>(pwh));
+ if(!equivalence(p45wh, rect))
+ std::cout << "fail 11\n";
+ assign(p90wh, view_as<polygon_90_with_holes_concept>(p45wh));
+ if(!equivalence(p90wh, rect))
+ std::cout << "fail 12\n";
+ assign(p90, view_as<polygon_90_concept>(pwh));
+ if(!equivalence(p90, rect))
+ std::cout << "fail 13\n";
+ assign(p45, view_as<polygon_45_concept>(pwh));
+ if(!equivalence(p45, rect))
+ std::cout << "fail 14\n";
+ assign(p90, view_as<polygon_90_concept>(p45wh));
+ if(!equivalence(p90, rect))
+ std::cout << "fail 15\n";
+ assign(ps, rect);
+ assign(ps90, view_as<polygon_90_set_concept>(ps));
+ if(!equivalence(ps90, rect))
+ std::cout << "fail 16\n";
+ assign(ps45, view_as<polygon_45_set_concept>(ps));
+ if(!equivalence(ps45, rect))
+ std::cout << "fail 17\n";
+ assign(ps90, view_as<polygon_90_set_concept>(ps45));
+ if(!equivalence(ps90, rect))
+ std::cout << "fail 18\n";
+ }
+
+ inline bool testPolygon45SetRect() {
+ std::vector<point_data<int> > points;
+ points.push_back(point_data<int>(0,0));
+ points.push_back(point_data<int>(0,10));
+ points.push_back(point_data<int>(10,10));
+ points.push_back(point_data<int>(10,0));
+ polygon_45_data<int> poly;
+ poly.set(points.begin(), points.end());
+ polygon_45_set_data<int> ps;
+ ps.insert(poly);
+ std::vector<polygon_45_data<int> > polys;
+ ps.get_polygons(polys);
+ std::cout << polys.size() << std::endl;
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ return true;
+ }
+
+ inline bool testPolygon45Set() {
+ polygon_45_formation<int>::Polygon45Formation pf(true);
+ typedef boolean_op_45<int>::Vertex45 Vertex45;
+ std::vector<Vertex45> data;
+ // result == 0 8 -1 1
+ data.push_back(Vertex45(point_data<int>(0, 8), -1, 1));
+ // result == 0 8 1 -1
+ data.push_back(Vertex45(point_data<int>(0, 8), 1, -1));
+ // result == 4 0 1 1
+ data.push_back(Vertex45(point_data<int>(4, 0), 1, 1));
+ // result == 4 0 2 1
+ data.push_back(Vertex45(point_data<int>(4, 0), 2, 1));
+ // result == 4 4 2 -1
+ data.push_back(Vertex45(point_data<int>(4, 4), 2, -1));
+ // result == 4 4 -1 -1
+ data.push_back(Vertex45(point_data<int>(4, 4), -1, -1));
+ // result == 4 12 1 1
+ data.push_back(Vertex45(point_data<int>(4, 12), 1, 1));
+ // result == 4 12 2 1
+ data.push_back(Vertex45(point_data<int>(4, 12), 2, 1));
+ // result == 4 16 2 -1
+ data.push_back(Vertex45(point_data<int>(4, 16), 2, 1));
+ // result == 4 16 -1 -1
+ data.push_back(Vertex45(point_data<int>(4, 16), -1, -1));
+ // result == 6 2 1 -1
+ data.push_back(Vertex45(point_data<int>(6, 2), 1, -1));
+ // result == 6 14 -1 1
+ data.push_back(Vertex45(point_data<int>(6, 14), -1, 1));
+ // result == 6 2 -1 1
+ data.push_back(Vertex45(point_data<int>(6, 2), -1, 1));
+ // result == 6 14 1 -1
+ data.push_back(Vertex45(point_data<int>(6, 14), 1, -1));
+ // result == 8 0 -1 -1
+ data.push_back(Vertex45(point_data<int>(8, 0), -1, -1));
+ // result == 8 0 2 -1
+ data.push_back(Vertex45(point_data<int>(8, 0), 2, -1));
+ // result == 8 4 2 1
+ data.push_back(Vertex45(point_data<int>(8, 4), 2, 1));
+ // result == 8 4 1 1
+ data.push_back(Vertex45(point_data<int>(8, 4), 1, 1));
+ // result == 8 12 -1 -1
+ data.push_back(Vertex45(point_data<int>(8, 12), -1, -1));
+ // result == 8 12 2 -1
+ data.push_back(Vertex45(point_data<int>(8, 12), 2, -1));
+ // result == 8 16 2 1
+ data.push_back(Vertex45(point_data<int>(8, 16), 2, 1));
+ // result == 8 16 1 1
+ data.push_back(Vertex45(point_data<int>(8, 16), 1, 1));
+ // result == 12 8 1 -1
+ data.push_back(Vertex45(point_data<int>(12, 8), 1, -1));
+ // result == 12 8 -1 1
+ data.push_back(Vertex45(point_data<int>(12, 8), -1, 1));
+
+ data.push_back(Vertex45(point_data<int>(6, 4), 1, -1));
+ data.push_back(Vertex45(point_data<int>(6, 4), 2, -1));
+ data.push_back(Vertex45(point_data<int>(6, 12), -1, 1));
+ data.push_back(Vertex45(point_data<int>(6, 12), 2, 1));
+ data.push_back(Vertex45(point_data<int>(10, 8), -1, -1));
+ data.push_back(Vertex45(point_data<int>(10, 8), 1, 1));
+
+ std::sort(data.begin(), data.end());
+ std::vector<polygon_45_data<int> > polys;
+ pf.scan(polys, data.begin(), data.end());
+ polygon_45_set_data<int> ps;
+ std::cout << "inserting1\n";
+ //std::vector<point_data<int> > points;
+ //points.push_back(point_data<int>(0,0));
+ //points.push_back(point_data<int>(0,10));
+ //points.push_back(point_data<int>(10,10));
+ //points.push_back(point_data<int>(10,0));
+ //Polygon45 poly;
+ //poly.set(points.begin(), points.end());
+ //ps.insert(poly);
+ ps.insert(polys[0]);
+
+ polygon_45_set_data<int> ps2;
+ std::cout << "inserting2\n";
+ ps2.insert(polys[0]);
+ std::cout << "applying boolean\n";
+ ps |= ps2;
+ std::vector<polygon_45_data<int> > polys2;
+ std::cout << "getting result\n";
+ ps.get_polygons(polys2);
+ std::cout << ps2 << std::endl;
+ std::cout << ps << std::endl;
+ std::cout << polys[0] << std::endl;
+ std::cout << polys2[0] << std::endl;
+ if(polys != polys2) std::cout << "test Polygon45Set failed\n";
+ return polys == polys2;
+ }
+
+ inline bool testPolygon45SetPerterbation() {
+ polygon_45_formation<int>::Polygon45Formation pf(true);
+ typedef boolean_op_45<int>::Vertex45 Vertex45;
+ std::vector<Vertex45> data;
+ // result == 0 8 -1 1
+ data.push_back(Vertex45(point_data<int>(0, 80), -1, 1));
+ // result == 0 8 1 -1
+ data.push_back(Vertex45(point_data<int>(0, 80), 1, -1));
+ // result == 4 0 1 1
+ data.push_back(Vertex45(point_data<int>(40, 0), 1, 1));
+ // result == 4 0 2 1
+ data.push_back(Vertex45(point_data<int>(40, 0), 2, 1));
+ // result == 4 4 2 -1
+ data.push_back(Vertex45(point_data<int>(40, 40), 2, -1));
+ // result == 4 4 -1 -1
+ data.push_back(Vertex45(point_data<int>(40, 40), -1, -1));
+ // result == 4 12 1 1
+ data.push_back(Vertex45(point_data<int>(40, 120), 1, 1));
+ // result == 4 12 2 1
+ data.push_back(Vertex45(point_data<int>(40, 120), 2, 1));
+ // result == 4 16 2 -1
+ data.push_back(Vertex45(point_data<int>(40, 160), 2, 1));
+ // result == 4 16 -1 -1
+ data.push_back(Vertex45(point_data<int>(40, 160), -1, -1));
+ // result == 6 2 1 -1
+ data.push_back(Vertex45(point_data<int>(60, 20), 1, -1));
+ // result == 6 14 -1 1
+ data.push_back(Vertex45(point_data<int>(60, 140), -1, 1));
+ // result == 6 2 -1 1
+ data.push_back(Vertex45(point_data<int>(60, 20), -1, 1));
+ // result == 6 14 1 -1
+ data.push_back(Vertex45(point_data<int>(60, 140), 1, -1));
+ // result == 8 0 -1 -1
+ data.push_back(Vertex45(point_data<int>(80, 0), -1, -1));
+ // result == 8 0 2 -1
+ data.push_back(Vertex45(point_data<int>(80, 0), 2, -1));
+ // result == 8 4 2 1
+ data.push_back(Vertex45(point_data<int>(80, 40), 2, 1));
+ // result == 8 4 1 1
+ data.push_back(Vertex45(point_data<int>(80, 40), 1, 1));
+ // result == 8 12 -1 -1
+ data.push_back(Vertex45(point_data<int>(80, 120), -1, -1));
+ // result == 8 12 2 -1
+ data.push_back(Vertex45(point_data<int>(80, 120), 2, -1));
+ // result == 8 16 2 1
+ data.push_back(Vertex45(point_data<int>(80, 160), 2, 1));
+ // result == 8 16 1 1
+ data.push_back(Vertex45(point_data<int>(80, 160), 1, 1));
+ // result == 12 8 1 -1
+ data.push_back(Vertex45(point_data<int>(120, 80), 1, -1));
+ // result == 12 8 -1 1
+ data.push_back(Vertex45(point_data<int>(120, 80), -1, 1));
+
+ data.push_back(Vertex45(point_data<int>(60, 40), 1, -1));
+ data.push_back(Vertex45(point_data<int>(60, 40), 2, -1));
+ data.push_back(Vertex45(point_data<int>(60, 120), -1, 1));
+ data.push_back(Vertex45(point_data<int>(60, 120), 2, 1));
+ data.push_back(Vertex45(point_data<int>(100, 80), -1, -1));
+ data.push_back(Vertex45(point_data<int>(100, 80), 1, 1));
+
+ std::sort(data.begin(), data.end());
+ std::vector<polygon_45_data<int> > polys;
+ pf.scan(polys, data.begin(), data.end());
+ polygon_45_set_data<int> ps;
+ std::cout << "inserting1\n";
+ //std::vector<point_data<int> > points;
+ //points.push_back(point_data<int>(0,0));
+ //points.push_back(point_data<int>(0,10));
+ //points.push_back(point_data<int>(10,10));
+ //points.push_back(point_data<int>(10,0));
+ //Polygon45 poly;
+ //poly.set(points.begin(), points.end());
+ //ps.insert(poly);
+ polygon_45_set_data<int> preps(polys[0]);
+
+ ps.insert(polys[0]);
+ convolve(polys[0], point_data<int>(0, 1) );
+
+ polygon_45_set_data<int> ps2;
+ std::cout << "inserting2\n";
+ ps2.insert(polys[0]);
+ std::cout << "applying boolean\n";
+ ps |= ps2;
+ std::vector<polygon_45_data<int> > polys2;
+ std::cout << "getting result\n";
+ ps.get_polygons(polys2);
+ std::cout << preps << std::endl;
+ std::cout << ps2 << std::endl;
+ std::cout << ps << std::endl;
+ std::cout << polys[0] << std::endl;
+ std::cout << polys2[0] << std::endl;
+ if(polys != polys2) std::cout << "test Polygon45Set failed\n";
+ return polys == polys2;
+ //return true;
+ }
+
+ inline int testPolygon45SetDORA() {
+ std::cout << "testPolygon45SetDORA" << std::endl;
+ std::vector<point_data<int> > pts;
+ pts.push_back(point_data<int>(0, 0));
+ pts.push_back(point_data<int>(10, 0));
+ pts.push_back(point_data<int>(10, 10));
+ pts.push_back(point_data<int>(0, 10));
+ polygon_45_data<int> apoly;
+ apoly.set(pts.begin(), pts.end());
+ polygon_45_set_data<int> ps(apoly);
+ polygon_45_set_data<int> ps2(ps);
+ ps2 = apoly;
+ std::vector<polygon_45_data<int> > apolys;
+ apolys.push_back(apoly);
+ ps2.insert(apolys.begin(), apolys.end());
+ apolys.clear();
+ ps2.get(apolys);
+ std::cout << apolys.size() << std::endl;
+ std::cout << (ps == ps2) << std::endl;
+ std::cout << !(ps != ps2) << std::endl;
+ ps2.clear();
+ std::cout << (ps2.value().empty()) << std::endl;
+ ps2.set(apolys.begin(), apolys.end());
+ ps2.set(ps.value());
+ ps.clean();
+ ps2.set_clean(ps.value());
+ ps2.insert(ps.value().begin(), ps.value().end());
+ ps2.clear();
+ for(polygon_45_set_data<int>::iterator_type itr = ps.begin();
+ itr != ps.end(); ++itr) {
+ ps2.insert(*itr);
+ }
+ std::vector<polygon_45_with_holes_data<int> > apolywhs;
+ ps2.get_polygons_with_holes(apolywhs);
+ std::cout << apolywhs.size() << std::endl;
+ ps2 += 1;
+ apolywhs.clear();
+ ps2.get_polygons_with_holes(apolywhs);
+ if(apolywhs.size()) std::cout << apolywhs[0] << std::endl;
+ ps2 -= 1;
+ apolywhs.clear();
+ ps2.get_polygons_with_holes(apolywhs);
+ if(apolywhs.size()) std::cout << apolywhs[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ rectangle_data<int> rect;
+ extents(rect, apolywhs[0]);
+ ps2.clear();
+ ps2.insert(rect);
+ ps2.extents(rect);
+ ps2.clear();
+ ps2.insert(rect);
+ ps2.clear();
+ ps2.insert(apolywhs[0]);
+ apolywhs.clear();
+ ps2.get_trapezoids(apolywhs);
+ if(apolywhs.size()) std::cout << apolywhs[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ ps2 *= ps;
+ std::cout << (ps2 == ps) << std::endl;
+ ps2 ^= ps;
+ std::cout << ps2.empty() << std::endl;
+ axis_transformation atr(axis_transformation::WEST_SOUTH);
+ ps2 = ps;
+ ps.transform(atr);
+ transformation<int> tr(atr);
+ tr.invert();
+ ps.transform(tr);
+ ps.scale_up(2);
+ ps.scale_down(2);
+ std::cout << (ps2 == ps) << std::endl;
+ pts.clear();
+ pts.push_back(point_data<int>(0,0));
+ pts.push_back(point_data<int>(10,10));
+ pts.push_back(point_data<int>(10,11));
+ pts.push_back(point_data<int>(0,21));
+ apoly.set(pts.begin(), pts.end());
+ ps2.clear();
+ ps2.insert(apoly);
+ ps2 -= 1;
+ apolywhs.clear();
+ ps2.get_polygons_with_holes(apolywhs);
+ if(apolywhs.size()) std::cout << apolywhs[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ pts.clear();
+ pts.push_back(point_data<int>(0, 0));
+ pts.push_back(point_data<int>(10, 10));
+ pts.push_back(point_data<int>(0, 20));
+ apoly.set(pts.begin(), pts.end());
+ ps2.clear();
+ ps2.insert(apoly);
+ pts.clear();
+ pts.push_back(point_data<int>(0, 5));
+ pts.push_back(point_data<int>(10, 15));
+ pts.push_back(point_data<int>(0, 25));
+ apoly.set(pts.begin(), pts.end());
+ ps2.insert(apoly);
+ apolywhs.clear();
+ ps2.get_polygons_with_holes(apolywhs);
+ if(apolywhs.size()) std::cout << apolywhs[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ return 0;
+
+ }
+}
+}
+using namespace gtl;
+
+bool testRectangle() {
+ rectangle_data<int> rect, rect2;
+#ifdef BOOST_POLYGON_MSVC
+ horizontal(rect, interval_data<int>(0, 10));
+ vertical(rect, interval_data<int>(20, 30));
+#else
+ horizontal(rect, interval_data<polygon_long_long_type>(0, 10));
+ vertical(rect, interval_data<polygon_long_long_type>(20, 30));
+#endif
+ xl(rect2, 0);
+ xh(rect2, 10);
+ yl(rect2, 20);
+ yh(rect2, 30);
+ if(euclidean_distance(rect, rect2) != 0) return false;
+ if(euclidean_distance(rect2, rect) != 0) return false;
+#ifdef BOOST_POLYGON_MSVC
+ set(rect, HORIZONTAL, interval_data<int>(0, 10));
+ if(!equivalence(horizontal(rect), interval_data<int>(0, 10))) return false;
+ if(!equivalence(vertical(rect2), interval_data<int>(20, 30))) return false;
+#else
+ set(rect, HORIZONTAL, interval_data<polygon_long_long_type>(0, 10));
+ if(!equivalence(horizontal(rect), interval_data<polygon_long_long_type>(0, 10))) return false;
+ if(!equivalence(vertical(rect2), interval_data<polygon_long_long_type>(20, 30))) return false;
+#endif
+ if(xl(rect) != 0) return false;
+ if(xh(rect) != 10) return false;
+ if(yl(rect) != 20) return false;
+ if(yh(rect) != 30) return false;
+ move(rect, HORIZONTAL, 10);
+ if(xl(rect) != 10) return false;
+#ifdef BOOST_POLYGON_MSVC
+ set_points(rect, point_data<int>(0, 20), point_data<int>(10, 30));
+#else
+ set_points(rect, point_data<int>(0, 20), point_data<polygon_long_long_type>(10, 30));
+#endif
+ if(xl(rect) != 0) return false;
+ convolve(rect, rect2);
+ if(xh(rect) != 20) return false;
+ deconvolve(rect, rect2);
+ if(xh(rect) != 10) return false;
+ reflected_convolve(rect, rect2);
+ reflected_deconvolve(rect, rect2);
+ if(!equivalence(rect, rect2)) return false;
+#ifdef BOOST_POLYGON_MSVC
+ convolve(rect, point_data<int>(100, 200));
+#else
+ convolve(rect, point_data<polygon_long_long_type>(100, 200));
+#endif
+ if(xh(rect) != 110) return false;
+ deconvolve(rect, point_data<int>(100, 200));
+ if(!equivalence(rect, rect2)) return false;
+ xh(rect, 100);
+ if(delta(rect, HORIZONTAL) != 100) return false;
+ if(area(rect) != 1000) return false;
+ if(half_perimeter(rect) != 110) return false;
+ if(perimeter(rect) != 220) return false;
+ if(guess_orientation(rect) != HORIZONTAL) return false;
+ return true;
+}
+
+
+bool testPolygon() {
+ int rect[4] = {0, 10, 20, 30};
+ iterator_compact_to_points<int*, point_data<int> > itr(rect, rect+4);
+ iterator_compact_to_points<int*, point_data<int> > itr_end(rect, rect+4);
+ std::vector<point_data<int> > points;
+ points.insert(points.end(), itr, itr_end);
+ polygon_90_data<int> p90;
+ assign(p90, rectangle_data<int>(interval_data<int>(0, 10), interval_data<int>(20, 30)));
+ if(winding(p90) != COUNTERCLOCKWISE) return false;
+ polygon_45_data<int> p45;
+ assign(p45, rectangle_data<int>(interval_data<int>(0, 10), interval_data<int>(20, 30)));
+ if(winding(p45) != COUNTERCLOCKWISE) return false;
+ polygon_data<int> p;
+ assign(p, rectangle_data<int>(interval_data<int>(0, 10), interval_data<int>(20, 30)));
+ if(winding(p) != COUNTERCLOCKWISE) return false;
+ set_compact(p90, rect, rect+4);
+ if(winding(p90) != COUNTERCLOCKWISE) return false;
+ points.clear();
+ points.push_back(point_data<int>(0, 0));
+ points.push_back(point_data<int>(10, 10));
+ points.push_back(point_data<int>(0, 20));
+ points.push_back(point_data<int>(-10, 10));
+ set_points(p45, points.begin(), points.end());
+ if(winding(p45) != COUNTERCLOCKWISE) return false;
+ std::swap(points[1], points[3]);
+ set_points(p, points.begin(), points.end());
+ if(winding(p) == COUNTERCLOCKWISE) return false;
+ point_data<int> cp;
+ center(cp, p);
+ if(cp != point_data<int>(0, 10)) return false;
+ move(p, HORIZONTAL, 3);
+ rectangle_data<int> bounding_box;
+ extents(bounding_box, p);
+ if(bounding_box != rectangle_data<int>(interval_data<int>(-7, 13), interval_data<int>(0, 20))) return false;
+ if(area(p90) != 400) return false;
+ if(area(p45) != 200) return false;
+ if(perimeter(p90) != 80) return false;
+ return true;
+}
+
+bool testPolygonAssign() {
+ polygon_data<int> p;
+ polygon_data<int> p1;
+ polygon_45_data<int> p_45;
+ polygon_45_data<int> p_451;
+ polygon_90_data<int> p_90;
+ polygon_90_data<int> p_901;
+ polygon_with_holes_data<int> p_wh;
+ polygon_with_holes_data<int> p_wh1;
+ polygon_45_with_holes_data<int> p_45_wh;
+ polygon_45_with_holes_data<int> p_45_wh1;
+ polygon_90_with_holes_data<int> p_90_wh;
+ polygon_90_with_holes_data<int> p_90_wh1;
+ assign(p, p1);
+ assign(p, p_45);
+ assign(p, p_90);
+ //assign(p, p_wh);
+ //assign(p, p_45_wh);
+ //assign(p, p_90_wh);
+ //assign(p_45, p);
+ assign(p_451, p_45);
+ assign(p_45, p_90);
+ //assign(p_45, p_wh);
+ //assign(p_45, p_45_wh);
+ //assign(p_45, p_90_wh);
+ //assign(p_90, p);
+ //assign(p_90, p_45);
+ assign(p_901, p_90);
+ //assign(p_90, p_wh);
+ //assign(p_90, p_45_wh);
+ //assign(p_90, p_90_wh);
+ assign(p_wh, p);
+ assign(p_wh, p_45);
+ assign(p_wh, p_90);
+ assign(p_wh1, p_wh);
+ assign(p_wh, p_45_wh);
+ assign(p_wh, p_90_wh);
+ //assign(p_45_wh, p);
+ assign(p_45_wh, p_45);
+ assign(p_45_wh, p_90);
+ //assign(p_45_wh, p_wh);
+ assign(p_45_wh1, p_45_wh);
+ //assign(p_90_wh, p);
+ //assign(p_90_wh, p_45);
+ assign(p_90_wh, p_90);
+ assign(p_90_wh1, p_90_wh);
+ return true;
+}
+
+int testPropertyMerge() {
+ rectangle_data<int> rect1 = construct<rectangle_data<int> >(0, 1, 10, 11);
+ rectangle_data<int> rect2 = construct<rectangle_data<int> >(5, 6, 17, 18);
+ property_merge_90<int, int> pm;
+ pm.insert(rect1, 0);
+ pm.insert(rect2, 1);
+ std::map<std::set<int>, polygon_90_set_data<int> > result;
+ pm.merge(result);
+ std::vector<rectangle_data<int> > rects;
+ std::set<int> key;
+ key.insert(0);
+ result[key].get(rects);
+ std::cout << rects.size() << std::endl;
+ std::vector<polygon_data<int> > polys;
+ result[key].get(polys);
+ std::cout << polys.size() << std::endl;
+ std::vector<polygon_90_with_holes_data<int> > polywhs;
+ result[key].get(polywhs);
+ std::cout << polys.size() << std::endl;
+ return result.size();
+}
+
+bool testPolygonWithHoles() {
+ int rect[4] = {0, 10, 20, 30};
+ iterator_compact_to_points<int*, point_data<int> > itr(rect, rect+4);
+ iterator_compact_to_points<int*, point_data<int> > itr_end(rect, rect+4);
+ std::vector<point_data<int> > points;
+ points.insert(points.end(), itr, itr_end);
+ polygon_45_with_holes_data<int> p45wh;
+ assign(p45wh, rectangle_data<int>(interval_data<int>(0, 10), interval_data<int>(20, 30)));
+ if(winding(p45wh) != COUNTERCLOCKWISE) return false;
+ polygon_45_with_holes_data<int> p45;
+ assign(p45, rectangle_data<int>(interval_data<int>(0, 10), interval_data<int>(20, 30)));
+ if(winding(p45) != COUNTERCLOCKWISE) return false;
+ polygon_45_with_holes_data<int> p;
+ assign(p, rectangle_data<int>(interval_data<int>(0, 10), interval_data<int>(20, 30)));
+ if(winding(p) != COUNTERCLOCKWISE) return false;
+ set_compact(p45wh, rect, rect+4);
+ if(winding(p45wh) != COUNTERCLOCKWISE) return false;
+ points.clear();
+ points.push_back(point_data<int>(0, 0));
+ points.push_back(point_data<int>(10, 10));
+ points.push_back(point_data<int>(0, 20));
+ points.push_back(point_data<int>(-10, 10));
+ set_points(p45, points.begin(), points.end());
+ if(winding(p45) != COUNTERCLOCKWISE) return false;
+ std::swap(points[1], points[3]);
+ set_points(p, points.begin(), points.end());
+ if(winding(p) == COUNTERCLOCKWISE) return false;
+ point_data<int> cp;
+ center(cp, p);
+ if(cp != point_data<int>(0, 10)) return false;
+ move(p, HORIZONTAL, 3);
+ rectangle_data<int> bounding_box;
+ extents(bounding_box, p);
+ if(bounding_box != rectangle_data<int>(interval_data<int>(-7, 13), interval_data<int>(0, 20))) return false;
+ if(area(p45wh) != 400) return false;
+ if(area(p45) != 200) return false;
+ if(perimeter(p45wh) != 80) return false;
+ return true;
+}
+
+using namespace gtl;
+
+typedef int Unit;
+typedef point_data<int> Point;
+typedef interval_data<int> Interval;
+typedef rectangle_data<int> Rectangle;
+typedef polygon_90_data<int> Polygon;
+typedef polygon_90_with_holes_data<int> PolygonWithHoles;
+typedef polygon_45_data<int> Polygon45;
+typedef polygon_45_with_holes_data<int> Polygon45WithHoles;
+typedef polygon_90_set_data<int> PolygonSet;
+typedef polygon_45_set_data<int> Polygon45Set;
+typedef axis_transformation AxisTransform;
+typedef transformation<int> Transform;
+
+bool getRandomBool() {
+ return rand()%2 != 0;
+}
+int getRandomInt() {
+ return rand()%6-2;
+}
+Point getRandomPoint() {
+ int x = rand()%8;
+ int y = rand()%8;
+ return Point(x, y);
+}
+Polygon45 getRandomTriangle() {
+ Point pts[3];
+ pts[0] = getRandomPoint();
+ pts[1] = pts[2] = pts[0];
+ int disp = getRandomInt();
+ bool dir = getRandomBool();
+ x(pts[2], x(pts[2]) + disp);
+ x(pts[1], x(pts[1]) + disp);
+ if(dir)
+ y(pts[1], y(pts[1]) + disp);
+ else
+ y(pts[1], y(pts[1]) - disp);
+ return Polygon45(pts, pts+3);
+}
+
+bool nonInteger45StessTest() {
+ for(unsigned int tests = 0; tests < 10; ++tests) {
+ Polygon45Set ps1, ps2;
+ std::vector<Polygon45> p45s;
+ for(unsigned int i = 0; i < 10; ++i) {
+ Polygon45 p45 = getRandomTriangle();
+ p45s.push_back(p45);
+ ps1.insert(p45);
+ scale_up(p45, 2);
+ ps2.insert(p45);
+ }
+ std::vector<Polygon45> polys;
+ ps1.get(polys);
+ Polygon45Set ps3;
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ scale_up(polys[i], 2);
+ ps3.insert(polys[i]);
+ }
+ Polygon45Set ps4 = ps3 ^ ps2;
+ std::vector<Polygon45> polys_error;
+ ps4.get(polys_error);
+ for(unsigned int i = 0; i < polys_error.size(); ++i) {
+ //if(polys_error[i].size() > 3) return false;
+ if(area(polys_error[i]) != 1) {
+ if(area(polys_error[i]) == 2) {
+ //if two area 1 errors merge it will have area 2
+ continue;
+ }
+ std::cout << "test failed\n";
+ for(unsigned int j =0; j < p45s.size(); ++j) {
+ std::cout << p45s[j] << std::endl;
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool validate_polygon_set_op(Polygon45Set& ps45_o,
+ const Polygon45Set& ps45_1,
+ const Polygon45Set& ps45_2,
+ int op_type) {
+ Polygon45Set s_ps_45_o(ps45_o);
+ Polygon45Set s_ps_45_1(ps45_1);
+ Polygon45Set s_ps_45_2(ps45_2);
+ s_ps_45_o.scale_up(2);
+ s_ps_45_1.scale_up(2);
+ s_ps_45_2.scale_up(2);
+ Polygon45Set s_ps_45_validate;
+ if(op_type == 0) {
+ s_ps_45_validate = s_ps_45_1 + s_ps_45_2;
+ s_ps_45_validate += Rectangle(4, 4, 6, 6);
+ } else if(op_type == 1) {
+ s_ps_45_validate = s_ps_45_1 * s_ps_45_2;
+ s_ps_45_validate -= Rectangle(4, 4, 6, 6);
+ } else if(op_type == 2) {
+ s_ps_45_validate = s_ps_45_1 ^ s_ps_45_2;
+ s_ps_45_validate -= Rectangle(4, 4, 6, 6);
+ } else {
+ s_ps_45_validate = s_ps_45_1 - s_ps_45_2;
+ s_ps_45_validate -= Rectangle(4, 4, 6, 6);
+ }
+ if(s_ps_45_validate != s_ps_45_o) {
+ std::cout << "TEST FAILED\n";
+ std::vector<Polygon45> polys;
+ s_ps_45_o.get(polys);
+ std::cout << "Result:\n";
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ polys.clear();
+ s_ps_45_validate.get(polys);
+ std::cout << "Expected Result:\n";
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ //redo the operation, set breakpoints here
+ switch (op_type) {
+ case 0:
+ ps45_o = ps45_1 + ps45_2;
+ ps45_o.get(polys);//needed to force clean
+ break;
+ case 1:
+ ps45_o = ps45_1 * ps45_2;
+ break;
+ case 2:
+ ps45_o = ps45_1 ^ ps45_2;
+ break;
+ default:
+ ps45_o = ps45_1 - ps45_2;
+ };
+ //redo the check, set breakpoints here
+ if(op_type == 0) {
+ s_ps_45_validate = s_ps_45_1 + s_ps_45_2;
+ s_ps_45_validate += Rectangle(4, 4, 6, 6);
+ s_ps_45_validate.get(polys);
+ } else if(op_type == 1) {
+ s_ps_45_validate = s_ps_45_1 * s_ps_45_2;
+ s_ps_45_validate -= Rectangle(4, 4, 6, 6);
+ } else if(op_type == 2) {
+ s_ps_45_validate = s_ps_45_1 ^ s_ps_45_2;
+ s_ps_45_validate -= Rectangle(4, 4, 6, 6);
+ } else {
+ s_ps_45_validate = s_ps_45_1 - s_ps_45_2;
+ s_ps_45_validate -= Rectangle(4, 4, 6, 6);
+ }
+ return false;
+ }
+ return true;
+}
+
+bool test_two_polygon_sets(const Polygon45Set& ps45_1,
+ const Polygon45Set& ps45_2) {
+ std::cout << "test two polygon sets \n";
+ std::vector<Polygon45> polys;
+ ps45_1.get(polys);
+ std::cout << "LVALUE:\n";
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ polys.clear();
+ ps45_2.get(polys);
+ std::cout << "RVALUE:\n";
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ Polygon45Set ps45_o;
+ std::cout << "OR\n";
+ ps45_o = ps45_1 + ps45_2;
+ polys.clear();
+ ps45_o.get(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ if(!validate_polygon_set_op(ps45_o, ps45_1, ps45_2, 0)) return false;
+ std::cout << "AND\n";
+ ps45_o = ps45_1 * ps45_2;
+ polys.clear();
+ ps45_o.get(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ if(!validate_polygon_set_op(ps45_o, ps45_1, ps45_2, 1)) return false;
+ std::cout << "XOR\n";
+ ps45_o = ps45_1 ^ ps45_2;
+ polys.clear();
+ ps45_o.get(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ if(!validate_polygon_set_op(ps45_o, ps45_1, ps45_2, 2)) return false;
+ std::cout << "SUBTRACT\n";
+ ps45_o = ps45_1 - ps45_2;
+ polys.clear();
+ ps45_o.get(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ if(!validate_polygon_set_op(ps45_o, ps45_1, ps45_2, 3)) return false;
+ return true;
+}
+
+bool test_two_polygons(const Polygon45& p45_1,
+ const Polygon45& p45_2) {
+ Polygon45Set ps45_1, ps45_2;
+ ps45_1.insert(p45_1);
+ ps45_2.insert(p45_2);
+ ps45_1.insert(rectangle_data<int>(10, -100, 20, 100));
+ ps45_2.insert(rectangle_data<int>(0, 10, 100, 20));
+ if(!test_two_polygon_sets(ps45_1, ps45_2)) return false;
+ Polygon45Set ps45_1_c = ps45_1 - Rectangle(0, 0, 2, 5);
+ Polygon45Set ps45_2_c = ps45_2 - Rectangle(0, 0, 2, 5);
+ if(!test_two_polygon_sets(ps45_1_c, ps45_2_c)) return false;
+ if(!test_two_polygon_sets(ps45_1_c, ps45_2)) return false;
+ if(!test_two_polygon_sets(ps45_1, ps45_2_c)) return false;
+ return true;
+}
+
+bool test_45_touch() {
+ using namespace gtl;
+ connectivity_extraction_45<int> ce;
+ rectangle_data<int> rect1(0, 0, 10, 10);
+ rectangle_data<int> rect2(5, 5, 15, 15);
+ rectangle_data<int> rect3(5, 20, 15, 25);
+ ce.insert(rect1);
+ ce.insert(rect2);
+ ce.insert(rect3);
+ std::vector<std::set<int> > graph(3);
+ ce.extract(graph);
+ if(graph[0].size() == 1 && graph[1].size() == 1 && graph[2].size() == 0) {
+ std::set<int>::iterator itr = graph[0].begin();
+ std::cout << *itr << std::endl;
+ std::set<int>::iterator itr1 = graph[1].begin();
+ std::cout << *itr1 << std::endl;
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_45_touch_ur() {
+ using namespace gtl;
+ connectivity_extraction_45<int> ce;
+ rectangle_data<int> rect1(0, 0, 5, 5);
+ rectangle_data<int> rect2(5, 5, 10, 10);
+ ce.insert(rect1);
+ ce.insert(rect2);
+ std::vector<std::set<int> > graph(2);
+ ce.extract(graph);
+ if(graph[0].size() == 1 && graph[1].size() == 1) {
+ std::set<int>::iterator itr = graph[0].begin();
+ std::cout << *itr << std::endl;
+ std::set<int>::iterator itr1 = graph[1].begin();
+ std::cout << *itr1 << std::endl;
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_45_touch_r() {
+ using namespace gtl;
+ connectivity_extraction_45<int> ce;
+ rectangle_data<int> rect1(0, 0, 5, 5);
+ rectangle_data<int> rect2(5, 0, 10, 5);
+ ce.insert(rect1);
+ ce.insert(rect2);
+ std::vector<std::set<int> > graph(2);
+ ce.extract(graph);
+ if(graph[0].size() == 1 && graph[1].size() == 1) {
+ std::set<int>::iterator itr = graph[0].begin();
+ std::cout << *itr << std::endl;
+ std::set<int>::iterator itr1 = graph[1].begin();
+ std::cout << *itr1 << std::endl;
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_45_touch_boundaries() {
+ using namespace gtl;
+ connectivity_extraction_45<int> ce;
+ rectangle_data<int> rect1(0, 0, 10, 10);
+ rectangle_data<int> rect2(10, 0, 20, 10);
+ rectangle_data<int> rect3(20, 0, 30, 10);
+ rectangle_data<int> rect4(0, 10, 10, 20);
+ rectangle_data<int> rect5(10, 10, 20, 20);
+ rectangle_data<int> rect6(20, 10, 30, 20);
+ rectangle_data<int> rect7(0, 20, 10, 30);
+ rectangle_data<int> rect8(10, 20, 20, 30);
+ rectangle_data<int> rect9(20, 20, 30, 30);
+ ce.insert(rect1);
+ ce.insert(rect2);
+ ce.insert(rect3);
+ ce.insert(rect4);
+ ce.insert(rect5);
+ ce.insert(rect6);
+ ce.insert(rect7);
+ ce.insert(rect8);
+ ce.insert(rect9);
+ std::vector<std::set<int> > graph(9);
+ ce.extract(graph);
+ for(unsigned int i = 0; i < 9; ++i) {
+ std::cout << i << ": ";
+ for(std::set<int>::iterator itr = graph[i].begin(); itr != graph[i].end(); ++itr) {
+ std::cout << *itr << " ";
+ } std::cout << std::endl;
+ }
+ if(graph[0].size() == 3 && graph[1].size() == 5 && graph[2].size() == 3 &&
+ graph[3].size() == 5 && graph[4].size() == 8 && graph[5].size() == 5 &&
+ graph[6].size() == 3 && graph[7].size() == 5 && graph[8].size() == 3) {
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_45_concept_interact() {
+ using namespace gtl;
+ std::vector<polygon_45_data<int> > polys;
+ polys += rectangle_data<int>(10, 10, 20, 20);
+ polys += rectangle_data<int>(15, 15, 25, 25);
+ polys += rectangle_data<int>(5, 25, 10, 35);
+ interact(polys, rectangle_data<int>(0, 0, 13, 13));
+ if(polys.size() != 1) return false;
+ return true;
+}
+
+bool test_aa_touch() {
+ using namespace gtl;
+ connectivity_extraction<int> ce;
+ rectangle_data<int> rect1(0, 0, 10, 10);
+ rectangle_data<int> rect2(5, 5, 15, 15);
+ rectangle_data<int> rect3(5, 20, 15, 25);
+ ce.insert(rect1);
+ ce.insert(rect2);
+ ce.insert(rect3);
+ std::vector<std::set<int> > graph(3);
+ ce.extract(graph);
+ if(graph[0].size() == 1 && graph[1].size() == 1 && graph[2].size() == 0) {
+ std::set<int>::iterator itr = graph[0].begin();
+ std::cout << *itr << std::endl;
+ std::set<int>::iterator itr1 = graph[1].begin();
+ std::cout << *itr1 << std::endl;
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_aa_touch_ur() {
+ using namespace gtl;
+ connectivity_extraction<int> ce;
+ rectangle_data<int> rect1(0, 0, 5, 5);
+ rectangle_data<int> rect2(5, 5, 10, 10);
+ ce.insert(rect1);
+ ce.insert(rect2);
+ std::vector<std::set<int> > graph(2);
+ ce.extract(graph);
+ if(graph[0].size() == 1 && graph[1].size() == 1) {
+ std::set<int>::iterator itr = graph[0].begin();
+ std::cout << *itr << std::endl;
+ std::set<int>::iterator itr1 = graph[1].begin();
+ std::cout << *itr1 << std::endl;
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_aa_touch_ur2() {
+ using namespace gtl;
+ connectivity_extraction<int> ce;
+ rectangle_data<int> rect2(5, 5, 10, 10);
+ point_data<int> pts[3] = {
+ point_data<int>(0, 0),
+ point_data<int>(5, 5),
+ point_data<int>(0, 5)
+ };
+ polygon_data<int> poly;
+ poly.set(pts, pts+3);
+ ce.insert(poly);
+ ce.insert(rect2);
+ std::vector<std::set<int> > graph(2);
+ ce.extract(graph);
+ if(graph[0].size() == 1 && graph[1].size() == 1) {
+ std::set<int>::iterator itr = graph[0].begin();
+ std::cout << *itr << std::endl;
+ std::set<int>::iterator itr1 = graph[1].begin();
+ std::cout << *itr1 << std::endl;
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_aa_touch_r() {
+ using namespace gtl;
+ connectivity_extraction<int> ce;
+ rectangle_data<int> rect1(0, 0, 5, 5);
+ rectangle_data<int> rect2(5, 0, 10, 5);
+ ce.insert(rect1);
+ ce.insert(rect2);
+ std::vector<std::set<int> > graph(2);
+ ce.extract(graph);
+ if(graph[0].size() == 1 && graph[1].size() == 1) {
+ std::set<int>::iterator itr = graph[0].begin();
+ std::cout << *itr << std::endl;
+ std::set<int>::iterator itr1 = graph[1].begin();
+ std::cout << *itr1 << std::endl;
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_aa_touch_boundaries() {
+ using namespace gtl;
+ connectivity_extraction<int> ce;
+ rectangle_data<int> rect1(0, 0, 10, 10);
+ rectangle_data<int> rect2(10, 0, 20, 10);
+ rectangle_data<int> rect3(20, 0, 30, 10);
+ rectangle_data<int> rect4(0, 10, 10, 20);
+ rectangle_data<int> rect5(10, 10, 20, 20);
+ rectangle_data<int> rect6(20, 10, 30, 20);
+ rectangle_data<int> rect7(0, 20, 10, 30);
+ rectangle_data<int> rect8(10, 20, 20, 30);
+ rectangle_data<int> rect9(20, 20, 30, 30);
+ ce.insert(rect1);
+ ce.insert(rect2);
+ ce.insert(rect3);
+ ce.insert(rect4);
+ ce.insert(rect5);
+ ce.insert(rect6);
+ ce.insert(rect7);
+ ce.insert(rect8);
+ ce.insert(rect9);
+ std::vector<std::set<int> > graph(9);
+ ce.extract(graph);
+ for(unsigned int i = 0; i < 9; ++i) {
+ std::cout << i << ": ";
+ for(std::set<int>::iterator itr = graph[i].begin(); itr != graph[i].end(); ++itr) {
+ std::cout << *itr << " ";
+ } std::cout << std::endl;
+ }
+ if(graph[0].size() == 3 && graph[1].size() == 5 && graph[2].size() == 3 &&
+ graph[3].size() == 5 && graph[4].size() == 8 && graph[5].size() == 5 &&
+ graph[6].size() == 3 && graph[7].size() == 5 && graph[8].size() == 3) {
+ return true;
+ }
+ std::cout << "test failed\n";
+ return false;
+}
+
+bool test_aa_concept_interact() {
+ using namespace gtl;
+ std::vector<polygon_data<int> > polys;
+ polys += rectangle_data<int>(10, 10, 20, 20);
+ polys += rectangle_data<int>(15, 15, 25, 25);
+ polys += rectangle_data<int>(5, 25, 10, 35);
+ interact(polys, rectangle_data<int>(0, 0, 13, 13));
+ if(polys.size() != 1) return false;
+ return true;
+}
+
+bool test_get_rectangles() {
+ using namespace gtl;
+ polygon_90_set_data<int> ps(VERTICAL);
+ ps += rectangle_data<int>(0, 0, 10, 10);
+ ps += rectangle_data<int>(5, 5, 15, 15);
+ std::vector<polygon_90_data<int> > polys;
+ ps.get_rectangles(polys, HORIZONTAL);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ if(polys.size() != 3) return false;
+ std::vector<rectangle_data<int> > rects;
+ ps.get_rectangles(rects, HORIZONTAL);
+ for(unsigned int i = 0; i < rects.size(); ++i) {
+ std::cout << rects[i] << std::endl;
+ }
+ if(rects.size() != 3) return false;
+ if(!equivalence(rects[2], rectangle_data<int>(5,10,15,15))) return false;
+
+ get_rectangles(polys, rects, VERTICAL);
+ get_rectangles(rects, polys, HORIZONTAL);
+ return equivalence(rects, polys);
+}
+
+bool test_get_trapezoids() {
+ using namespace gtl;
+ polygon_45_set_data<int> ps;
+ ps += rectangle_data<int>(0, 0, 10, 10);
+ ps += rectangle_data<int>(5, 5, 15, 15);
+ std::vector<polygon_45_data<int> > polys;
+ ps.get_trapezoids(polys, HORIZONTAL);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ if(polys.size() != 3) return false;
+ std::vector<polygon_45_data<int> > rects;
+ ps.get_trapezoids(rects, HORIZONTAL);
+ for(unsigned int i = 0; i < rects.size(); ++i) {
+ std::cout << rects[i] << std::endl;
+ }
+ if(rects.size() != 3) return false;
+ if(!equivalence(rects[2], rectangle_data<int>(5,10,15,15))) return false;
+ get_trapezoids(polys, rects, VERTICAL);
+ get_trapezoids(rects, polys, HORIZONTAL);
+ return equivalence(rects, polys);
+}
+
+bool test_SQRT1OVER2() {
+ Point pts[] = {
+ Point(100, 100),
+ Point(0, 100),
+ Point(100, 200),
+ Point(0, 300),
+ Point(100, 400),
+ Point(0, 500),
+ Point(100, 500),
+ Point(100, 600),
+ Point(200, 500),
+ Point(300, 600),
+ Point(400, 500),
+ Point(500, 600),
+ Point(500, 500),
+ Point(600, 500),
+ Point(500, 400),
+ Point(600, 300),
+ Point(500, 200),
+ Point(600, 100),
+ Point(500, 100),
+ Point(500, 0),
+ Point(400, 100),
+ Point(300, 0),
+ Point(200, 100),
+ Point(100, 0),
+ Point(100, 100)
+ };
+ Polygon45 p45(pts, pts+25);
+ std::cout << is_45(p45) << std::endl;
+ std::cout << p45 << std::endl;
+ Polygon45Set ps45;
+ ps45 += p45;
+ ps45.resize(10, SQRT1OVER2, ORTHOGONAL);
+ std::vector<Polygon45> polys;
+ ps45.get(polys);
+ if(polys.size() != 1) return false;
+ Point pts2[] = {
+ Point(90, 90),
+ Point(-10, 90),
+ Point(-10, 100),
+ Point(90, 200),
+ Point(-10, 300),
+ Point(90, 400),
+ Point(-10, 500),
+ Point(-10, 510),
+ Point(90, 510),
+ Point(90, 610),
+ Point(100, 610),
+ Point(200, 510),
+ Point(300, 610),
+ Point(400, 510),
+ Point(500, 610),
+ Point(510, 610),
+ Point(510, 510),
+ Point(610, 510),
+ Point(610, 500),
+ Point(510, 400),
+ Point(610, 300),
+ Point(510, 200),
+ Point(610, 100),
+ Point(610, 90),
+ Point(510, 90),
+ Point(510, -10),
+ Point(500, -10),
+ Point(400, 90),
+ Point(300, -10),
+ Point(200, 90),
+ Point(100, -10),
+ Point(90, -10),
+ Point(90, 90)
+ };
+ Polygon45 p45reference(pts2, pts2+33);
+ std::cout << is_45(polys[0]) << std::endl;
+ std::cout << polys[0] << std::endl;
+ std::cout << p45reference << std::endl;
+ std::cout << is_45(p45reference) << std::endl;
+ if(!equivalence(polys[0], p45reference)) {
+ std::cout << "polys don't match\n";
+ return false;
+ }
+ ps45.resize(-10, SQRT1OVER2, ORTHOGONAL);
+ polys.clear();
+ ps45.get(polys);
+ if(polys.size() != 1) return false;
+ std::cout << is_45(polys[0]) << std::endl;
+ std::cout << polys[0] << std::endl;
+ if(!equivalence(polys[0], p45)) {
+ std::cout << "polys don't match\n";
+ return false;
+ }
+ ps45.resize(11, SQRT1OVER2, UNFILLED);
+ polys.clear();
+ ps45.get(polys);
+ if(polys.size() != 1) return false;
+ std::cout << is_45(polys[0]) << std::endl;
+ std::cout << polys[0] << std::endl;
+ return true;
+}
+
+bool test_scaling_by_floating(){
+ Point pts[] = {
+ Point(1, 1),
+ Point(10, 1),
+ Point(1, 10)
+ };
+ Polygon45 poly(pts, pts+3);
+ Polygon45Set ps45;
+ ps45 += poly;
+ ps45.scale(double(2.5));
+ std::vector<Polygon45> polys;
+ ps45.get(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ std::cout << area(polys[i]) << std::endl;
+ }
+ if(polys.size() != 1) return false;
+ if(area(polys[0]) != 242) return false;
+ scale(ps45, double(1)/double(2.5));
+ polys.clear();
+ ps45.get(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ return equivalence(polys, poly);
+}
+
+bool test_directional_resize() {
+ std::vector<Rectangle> rects;
+ rects.push_back(Rectangle(0, 0, 100, 100));
+ resize(rects, -10, 10, -10, 10);
+ for(unsigned int i = 0; i < rects.size(); ++i) {
+ std::cout << rects[i] << std::endl;
+ }
+ if(rects.size() != 1) return false;
+ if(rects[0] != Rectangle(10, 10, 110, 110)) return false;
+
+ return true;
+}
+
+bool test_self_xor() {
+ std::vector<Rectangle> rects;
+ rects.push_back(Rectangle(0, 0, 10, 10));
+ rects.push_back(Rectangle(5, 5, 15, 15));
+ self_xor(rects);
+ for(unsigned int i = 0; i < rects.size(); ++i) {
+ std::cout << rects[i] << std::endl;
+ }
+ if(rects.size() == 4) return true;
+ else return false;
+}
+
+bool test_grow_and_45() {
+ polygon_45_set_data<int> ps;
+ ps.insert(Rectangle(0, 0, 5, 5));
+ ps.insert(Rectangle(5, 5, 15, 15));
+ grow_and(ps, 2);
+ std::vector<polygon_45_data<int> > rects;
+ ps.get_trapezoids(rects);
+ for(unsigned int i = 0; i < rects.size(); ++i) {
+ std::cout << rects[i] << std::endl;
+ }
+ if(rects.size() != 1) return false;
+ return equivalence(rects, Rectangle(3, 3, 7, 7));
+}
+
+bool test_self_xor_45() {
+ polygon_45_set_data<int> ps;
+ ps.insert(Rectangle(0, 0, 10, 10));
+ ps.insert(Rectangle(5, 5, 15, 15));
+ self_xor(ps);
+ std::vector<polygon_45_data<int> > rects;
+ ps.get_trapezoids(rects);
+ for(unsigned int i = 0; i < rects.size(); ++i) {
+ std::cout << rects[i] << std::endl;
+ }
+ if(rects.size() == 4) return true;
+ else return false;
+}
+
+bool testViewCopyConstruct() {
+ PolygonSet ps1, ps2;
+ ps1.insert(Rectangle(0, 0, 10, 10));
+ ps2.insert(Rectangle(5, 5, 15, 15));
+ PolygonSet psr = ps1 - ps2;
+ std::vector<Rectangle> rects;
+ rects += psr;
+ for(unsigned int i = 0; i < rects.size(); ++i)
+ std::cout << rects[i] << std::endl;
+ if( rects.size() != 2) return false;
+ Polygon45Set ps45_1, ps45_2;
+ ps45_1.insert(Rectangle(0, 0, 10, 10));
+ ps45_2.insert(Rectangle(5, 5, 15, 15));
+ Polygon45Set ps45_r = ps45_1 - ps45_2;
+ std::vector<Polygon45> polys;
+ ps45_r.get_trapezoids(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i)
+ std::cout << polys[i] << std::endl;
+ if( polys.size() != 2) return false;
+ return true;
+}
+
+bool testpip() {
+ std::vector<Point> pts;
+ pts.push_back(Point(0, 0));
+ pts.push_back(Point(10, 0));
+ pts.push_back(Point(20, 10));
+ pts.push_back(Point(0, 20));
+ pts.push_back(Point(30, 40));
+ pts.push_back(Point(-10, 50));
+ pts.push_back(Point(-20, -20));
+ pts.push_back(Point(0, 0));
+ polygon_data<int> poly;
+ polygon_with_holes_data<int> poly2;
+ polygon_45_data<int> poly45;
+ polygon_45_with_holes_data<int> poly245;
+ polygon_90_data<int> poly90;
+ polygon_90_with_holes_data<int> poly290;
+ poly.set(pts.begin(), pts.end());
+ poly2.set(pts.begin(), pts.end());
+ assign(poly45, Rectangle(0, 0, 100, 100));
+ assign(poly245, Rectangle(0, 0, 100, 100));
+ assign(poly90, Rectangle(0, 0, 100, 100));
+ assign(poly290, Rectangle(0, 0, 100, 100));
+ for(unsigned int i = 0; i < pts.size(); ++i) {
+ if(!contains(poly, pts[i], true)) return false;
+ if(contains(poly, pts[i], false)) return false;
+ if(!contains(poly2, pts[i], true)) return false;
+ if(contains(poly2, pts[i], false)) return false;
+ }
+ if(!contains(poly45, pts[0], true)) return false;
+ if(contains(poly245, pts[0], false)) return false;
+ if(!contains(poly90, pts[0], true)) return false;
+ if(contains(poly290, pts[0], false)) return false;
+ Point pt(0, -10);
+ if(contains(poly, pt)) return false;
+ Point p2(0, 1);
+ if(!contains(poly, p2)) return false;
+ return true;
+}
+
+void testHand() {
+ using namespace gtl;
+ int handcoords[] = {
+12375, 11050, 13175, 10200, 15825, 9275, 18750, 8525, 24150, 8300, 27575, 8400, 31775, 7800,
+35975, 7200, 41375, 4800, 42575, 4200, 43175, 4200, 47375, 2400, 49175, 1800, 51150, 2200,
+52275, 2825, 52625, 4150, 52375, 4975, 51575, 6000, 49275, 6850, 45700, 7950, 43175, 9600,
+39575, 10800, 37775, 12000, 37775, 12600, 37775, 13800, 38975, 14400, 41375, 14400, 45575, 13200,
+48600, 13000, 51575, 13200, 55175, 12600, 58775, 12600, 61175, 13200, 62375, 14400, 62550, 15700,
+61975, 16875, 60775, 17600, 60100, 17675, 58525, 17675, 56150, 17575, 52175, 18000, 47975, 18600,
+45575, 19200, 44375, 19200, 42675, 19325, 41600, 19775, 41600, 20500, 42100, 20825, 44975, 20400,
+48575, 20400, 52775, 21000, 53975, 21000, 57575, 21000, 62375, 21000, 65450, 22000, 66300, 23100,
+66100, 24550, 64750, 25925, 62975, 26400, 61175, 26400, 58775, 26400, 56025, 26050, 53450, 26025,
+50975, 26400, 48575, 26400, 46775, 26400, 43650, 26075, 41375, 26400, 40775, 27000, 40775, 27600,
+42225, 28650, 44375, 29400, 48575, 30000, 50975, 31200, 53975, 31800, 58775, 33000, 61200, 34300,
+62375, 35400, 62375, 37200, 61175, 38400, 60000, 38700, 57575, 38400, 54550, 37575, 50975, 36600,
+49075, 36125, 47750, 36125, 45700, 35425, 42350, 34350, 38900, 33775, 30575, 33000, 26975, 33600,
+25975, 34900, 26375, 36600, 28175, 38400, 30575, 40800, 32375, 43800, 33200, 46200, 33200, 48000,
+32650, 49300, 31425, 50000, 29950, 50125, 28825, 49375, 27575, 48000, 25825, 46000, 23975, 44100,
+22175, 42600, 19775, 39600, 17325, 37300, 14975, 34800, 13175, 31800, 10775, 29400, 9600, 27400,
+10175, 27000, 11375, 27600, 12575, 28800, 14375, 31800, 16175, 34800, 18575, 37200, 21575, 39000,
+22775, 40200, 23975, 41400, 24575, 42600, 26375, 44400, 28325, 46000, 29850, 46775, 31175, 46200,
+31550, 44575, 30575, 43200, 28775, 40800, 25775, 38400, 24575, 34800, 24750, 33175, 26975, 31800,
+29975, 31800, 33575, 31800, 37775, 32400, 39575, 33000, 41975, 33600, 45150, 34175, 46975, 34750,
+48575, 35400, 50975, 35400, 51575, 34800, 51875, 33725, 50775, 32575, 48575, 31800, 45750, 30875,
+43775, 30600, 41375, 29400, 38975, 28800, 35975, 28200, 34775, 27600, 34175, 27000, 34775, 25800,
+37175, 25200, 40175, 25200, 43175, 25200, 46775, 25200, 50975, 25425, 53375, 25200, 55175, 24600,
+55525, 23450, 53975, 22200, 52775, 22200, 49075, 21850, 45950, 21925, 40775, 21600, 37775, 21600,
+35150, 21350, 34325, 20950, 34175, 19800, 35975, 19200, 38375, 19200, 40750, 18900, 42575, 18600,
+44375, 18000, 47975, 17400, 50375, 17125, 52025, 16625, 52775, 15600, 52100, 14625, 49675, 14125,
+48625, 14125, 46775, 14400, 44375, 15000, 41375, 15150, 37700, 15275, 34775, 15600, 32850, 15925,
+31775, 15600, 31425, 14875, 32375, 13800, 36575, 11400, 38975, 10200, 41375, 9000, 43075, 8150,
+43650, 7200, 43325, 6250, 42225, 5825, 40800, 6275, 38900, 6925, 35375, 8400, 32375, 10200,
+27575, 11400, 22775, 12600, 19775, 13225, 16775, 13800, 14975, 14400, 13050, 14000, 11975, 12600,
+ 0, 0 };
+ std::vector<Point> handpoints;
+ for(unsigned int i = 0; i < 100000; i += 2) {
+ Point pt(handcoords[i], handcoords[i+1]);
+ if(pt == Point(0, 0)) break;
+ handpoints.push_back(pt);
+ }
+ polygon_data<int> handpoly;
+ handpoly.set(handpoints.begin(), handpoints.end());
+ int spiralcoords [] = {
+37200, 3600, 42075, 4025, 47475, 5875, 51000, 7800, 55800, 12300, 59000, 17075, 60000, 20400,
+61200, 25800, 61200, 29400, 60600, 33600, 58800, 38400, 55800, 42600, 53200, 45625,
+49200, 48600, 43200, 51000, 35400, 51600, 29400, 50400, 23400, 47400, 19200, 43800,
+16200, 39600, 14400, 35400, 13200, 29400, 13200, 24000, 15000, 18600, 17400, 13800,
+20525, 10300, 24600, 7200, 29400, 4800, 32450, 4000, 34825, 3675, 35625, 3625,
+35825, 7275, 39600, 7200, 43800, 8400, 46800, 9600, 50400, 12000, 53400, 15000,
+55800, 18600, 57000, 23400, 57600, 27000, 57000, 32400, 55200, 37200, 52200, 41400,
+48000, 45000, 42000, 47400, 35400, 48000, 30000, 46800, 24600, 43800, 20325, 39100,
+17850, 34275, 16800, 27600, 17400, 22200, 20400, 16200, 24600, 11400, 28800, 9000,
+32400, 7800, 33200, 7575, 33925, 11050, 35400, 10800, 37200, 10800, 41400, 11400,
+46200, 13200, 49800, 16200, 51600, 19200, 53400, 23400, 54000, 29400, 52800, 33600,
+49800, 39000, 45000, 42600, 39000, 44400, 33600, 43800, 28200, 42000, 24000, 37800,
+21000, 33000, 20400, 26400, 21600, 21000, 24600, 16200, 28200, 13200, 31875, 11625,
+33200, 15625, 36000, 15000, 39000, 15000, 43800, 16800, 46800, 19200, 49200, 23400,
+49800, 27600, 48750, 32700, 46350, 36275, 42600, 39000, 38400, 40200, 31800, 39000,
+28200, 36600, 25200, 31200, 24600, 26400, 26025, 21800, 28200, 18600, 30600, 16800,
+32575, 19875, 34200, 19200, 36000, 18600, 37200, 18600, 40375, 19125, 43200, 21000,
+45600, 24000, 46200, 27600, 45600, 30600, 43800, 33600, 41475, 35625, 37800, 36600,
+33600, 36000, 30000, 33600, 28200, 28800, 28800, 24600, 30000, 22200, 31200, 23400,
+30600, 25200, 30000, 27000, 30600, 30000, 31800, 32400, 34200, 34200, 38400, 34800,
+41400, 33000, 44025, 30225, 44400, 26400, 43200, 23400, 40900, 21200, 37800, 20400,
+34950, 20675, 32400, 22200, 30175, 19475, 28425, 21300, 27000, 24000, 26400, 27600,
+27000, 31800, 31200, 36600, 36600, 38400, 42600, 37200, 46200, 33600, 48000, 30000,
+47650, 24425, 45600, 20400, 42650, 18200, 39000, 16800, 35400, 16800, 33600, 17400,
+32875, 17675, 31100, 13850, 28200, 15600, 25200, 18600, 22800, 22800, 22200, 27000,
+23400, 33600, 26400, 38400, 31675, 41575, 37800, 42600, 40850, 42150, 42800, 41550,
+47050, 39025, 50100, 35375, 52200, 29400, 51675, 23950, 49800, 19200, 46200, 15600,
+41400, 13200, 37800, 12600, 35025, 12750, 33350, 13050, 32400, 9600, 30025, 10325,
+25925, 12725, 22200, 16800, 19800, 21000, 18600, 25800, 18600, 30000, 20400, 35400,
+22575, 39250, 25225, 41825, 28200, 43800, 33600, 46200, 39000, 46200, 44400, 45000,
+48650, 42350, 52800, 37800, 55200, 32400, 55800, 26400, 54600, 21000, 53400, 18000,
+50400, 14400, 47400, 12000, 42600, 9600, 39000, 9000, 36000, 9000, 34775, 9125,
+34300, 5600, 30000, 6600, 25800, 8400, 22025, 11350, 18725, 15125, 16200, 20400,
+15000, 24600, 15000, 30600, 16800, 36600, 20400, 42600, 25800, 46800, 31200, 49200,
+38400, 49800, 45000, 48600, 51000, 45000, 55475, 40225, 58200, 34800, 59400, 30000,
+59400, 25200, 58200, 19800, 55200, 14400, 52225, 11150, 47400, 7800, 44175, 6500,
+40200, 5400, 38400, 5400, 37200, 5400, 0, 0 };
+ std::vector<Point> spiralpoints;
+ for(unsigned int i = 0; i < 100000; i += 2) {
+ Point pt(spiralcoords[i], spiralcoords[i+1]);
+ if(pt == Point(0, 0)) break;
+ spiralpoints.push_back(pt);
+ }
+ polygon_data<int> spiralpoly;
+ spiralpoly.set(spiralpoints.begin(), spiralpoints.end());
+ polygon_set_data<int> handset;
+ handset += handpoly;
+ polygon_set_data<int> spiralset;
+ spiralset += spiralpoly;
+ polygon_set_data<int> xorset = handset ^ spiralset;
+ std::vector<polygon_data<int> > polys;
+ polys += xorset;
+ std::cout << polys.size() << std::endl;
+ for(unsigned int i = 0; i < polys.size(); ++i)
+ std::cout << polys[i] << std::endl;
+}
+
+//void testHandFloat() {
+// using namespace gtl;
+// double handcoords[] = {
+//12375, 11050, 13175, 10200, 15825, 9275, 18750, 8525, 24150, 8300, 27575, 8400, 31775, 7800,
+//35975, 7200, 41375, 4800, 42575, 4200, 43175, 4200, 47375, 2400, 49175, 1800, 51150, 2200,
+//52275, 2825, 52625, 4150, 52375, 4975, 51575, 6000, 49275, 6850, 45700, 7950, 43175, 9600,
+//39575, 10800, 37775, 12000, 37775, 12600, 37775, 13800, 38975, 14400, 41375, 14400, 45575, 13200,
+//48600, 13000, 51575, 13200, 55175, 12600, 58775, 12600, 61175, 13200, 62375, 14400, 62550, 15700,
+//61975, 16875, 60775, 17600, 60100, 17675, 58525, 17675, 56150, 17575, 52175, 18000, 47975, 18600,
+//45575, 19200, 44375, 19200, 42675, 19325, 41600, 19775, 41600, 20500, 42100, 20825, 44975, 20400,
+//48575, 20400, 52775, 21000, 53975, 21000, 57575, 21000, 62375, 21000, 65450, 22000, 66300, 23100,
+//66100, 24550, 64750, 25925, 62975, 26400, 61175, 26400, 58775, 26400, 56025, 26050, 53450, 26025,
+//50975, 26400, 48575, 26400, 46775, 26400, 43650, 26075, 41375, 26400, 40775, 27000, 40775, 27600,
+//42225, 28650, 44375, 29400, 48575, 30000, 50975, 31200, 53975, 31800, 58775, 33000, 61200, 34300,
+//62375, 35400, 62375, 37200, 61175, 38400, 60000, 38700, 57575, 38400, 54550, 37575, 50975, 36600,
+//49075, 36125, 47750, 36125, 45700, 35425, 42350, 34350, 38900, 33775, 30575, 33000, 26975, 33600,
+//25975, 34900, 26375, 36600, 28175, 38400, 30575, 40800, 32375, 43800, 33200, 46200, 33200, 48000,
+//32650, 49300, 31425, 50000, 29950, 50125, 28825, 49375, 27575, 48000, 25825, 46000, 23975, 44100,
+//22175, 42600, 19775, 39600, 17325, 37300, 14975, 34800, 13175, 31800, 10775, 29400, 9600, 27400,
+//10175, 27000, 11375, 27600, 12575, 28800, 14375, 31800, 16175, 34800, 18575, 37200, 21575, 39000,
+//22775, 40200, 23975, 41400, 24575, 42600, 26375, 44400, 28325, 46000, 29850, 46775, 31175, 46200,
+//31550, 44575, 30575, 43200, 28775, 40800, 25775, 38400, 24575, 34800, 24750, 33175, 26975, 31800,
+//29975, 31800, 33575, 31800, 37775, 32400, 39575, 33000, 41975, 33600, 45150, 34175, 46975, 34750,
+//48575, 35400, 50975, 35400, 51575, 34800, 51875, 33725, 50775, 32575, 48575, 31800, 45750, 30875,
+//43775, 30600, 41375, 29400, 38975, 28800, 35975, 28200, 34775, 27600, 34175, 27000, 34775, 25800,
+//37175, 25200, 40175, 25200, 43175, 25200, 46775, 25200, 50975, 25425, 53375, 25200, 55175, 24600,
+//55525, 23450, 53975, 22200, 52775, 22200, 49075, 21850, 45950, 21925, 40775, 21600, 37775, 21600,
+//35150, 21350, 34325, 20950, 34175, 19800, 35975, 19200, 38375, 19200, 40750, 18900, 42575, 18600,
+//44375, 18000, 47975, 17400, 50375, 17125, 52025, 16625, 52775, 15600, 52100, 14625, 49675, 14125,
+//48625, 14125, 46775, 14400, 44375, 15000, 41375, 15150, 37700, 15275, 34775, 15600, 32850, 15925,
+//31775, 15600, 31425, 14875, 32375, 13800, 36575, 11400, 38975, 10200, 41375, 9000, 43075, 8150,
+//43650, 7200, 43325, 6250, 42225, 5825, 40800, 6275, 38900, 6925, 35375, 8400, 32375, 10200,
+//27575, 11400, 22775, 12600, 19775, 13225, 16775, 13800, 14975, 14400, 13050, 14000, 11975, 12600,
+// 0, 0 };
+// std::vector<point_data<double> > handpoints;
+// for(unsigned int i = 0; i < 100000; i += 2) {
+// point_data<double> pt(handcoords[i], handcoords[i+1]);
+// if(pt == point_data<double> (0, 0)) break;
+// handpoints.push_back(pt);
+// }
+// polygon_data<double> handpoly;
+// handpoly.set(handpoints.begin(), handpoints.end());
+// double spiralcoords [] = {
+//37200, 3600, 42075, 4025, 47475, 5875, 51000, 7800, 55800, 12300, 59000, 17075, 60000, 20400,
+//61200, 25800, 61200, 29400, 60600, 33600, 58800, 38400, 55800, 42600, 53200, 45625,
+//49200, 48600, 43200, 51000, 35400, 51600, 29400, 50400, 23400, 47400, 19200, 43800,
+//16200, 39600, 14400, 35400, 13200, 29400, 13200, 24000, 15000, 18600, 17400, 13800,
+//20525, 10300, 24600, 7200, 29400, 4800, 32450, 4000, 34825, 3675, 35625, 3625,
+//35825, 7275, 39600, 7200, 43800, 8400, 46800, 9600, 50400, 12000, 53400, 15000,
+//55800, 18600, 57000, 23400, 57600, 27000, 57000, 32400, 55200, 37200, 52200, 41400,
+//48000, 45000, 42000, 47400, 35400, 48000, 30000, 46800, 24600, 43800, 20325, 39100,
+//17850, 34275, 16800, 27600, 17400, 22200, 20400, 16200, 24600, 11400, 28800, 9000,
+//32400, 7800, 33200, 7575, 33925, 11050, 35400, 10800, 37200, 10800, 41400, 11400,
+//46200, 13200, 49800, 16200, 51600, 19200, 53400, 23400, 54000, 29400, 52800, 33600,
+//49800, 39000, 45000, 42600, 39000, 44400, 33600, 43800, 28200, 42000, 24000, 37800,
+//21000, 33000, 20400, 26400, 21600, 21000, 24600, 16200, 28200, 13200, 31875, 11625,
+//33200, 15625, 36000, 15000, 39000, 15000, 43800, 16800, 46800, 19200, 49200, 23400,
+//49800, 27600, 48750, 32700, 46350, 36275, 42600, 39000, 38400, 40200, 31800, 39000,
+//28200, 36600, 25200, 31200, 24600, 26400, 26025, 21800, 28200, 18600, 30600, 16800,
+//32575, 19875, 34200, 19200, 36000, 18600, 37200, 18600, 40375, 19125, 43200, 21000,
+//45600, 24000, 46200, 27600, 45600, 30600, 43800, 33600, 41475, 35625, 37800, 36600,
+//33600, 36000, 30000, 33600, 28200, 28800, 28800, 24600, 30000, 22200, 31200, 23400,
+//30600, 25200, 30000, 27000, 30600, 30000, 31800, 32400, 34200, 34200, 38400, 34800,
+//41400, 33000, 44025, 30225, 44400, 26400, 43200, 23400, 40900, 21200, 37800, 20400,
+//34950, 20675, 32400, 22200, 30175, 19475, 28425, 21300, 27000, 24000, 26400, 27600,
+//27000, 31800, 31200, 36600, 36600, 38400, 42600, 37200, 46200, 33600, 48000, 30000,
+//47650, 24425, 45600, 20400, 42650, 18200, 39000, 16800, 35400, 16800, 33600, 17400,
+//32875, 17675, 31100, 13850, 28200, 15600, 25200, 18600, 22800, 22800, 22200, 27000,
+//23400, 33600, 26400, 38400, 31675, 41575, 37800, 42600, 40850, 42150, 42800, 41550,
+//47050, 39025, 50100, 35375, 52200, 29400, 51675, 23950, 49800, 19200, 46200, 15600,
+//41400, 13200, 37800, 12600, 35025, 12750, 33350, 13050, 32400, 9600, 30025, 10325,
+//25925, 12725, 22200, 16800, 19800, 21000, 18600, 25800, 18600, 30000, 20400, 35400,
+//22575, 39250, 25225, 41825, 28200, 43800, 33600, 46200, 39000, 46200, 44400, 45000,
+//48650, 42350, 52800, 37800, 55200, 32400, 55800, 26400, 54600, 21000, 53400, 18000,
+//50400, 14400, 47400, 12000, 42600, 9600, 39000, 9000, 36000, 9000, 34775, 9125,
+//34300, 5600, 30000, 6600, 25800, 8400, 22025, 11350, 18725, 15125, 16200, 20400,
+//15000, 24600, 15000, 30600, 16800, 36600, 20400, 42600, 25800, 46800, 31200, 49200,
+//38400, 49800, 45000, 48600, 51000, 45000, 55475, 40225, 58200, 34800, 59400, 30000,
+//59400, 25200, 58200, 19800, 55200, 14400, 52225, 11150, 47400, 7800, 44175, 6500,
+//40200, 5400, 38400, 5400, 37200, 5400, 0, 0 };
+// std::vector<point_data<double> > spiralpoints;
+// for(unsigned int i = 0; i < 100000; i += 2) {
+// point_data<double> pt(spiralcoords[i], spiralcoords[i+1]);
+// if(pt == point_data<double> (0, 0)) break;
+// spiralpoints.push_back(pt);
+// }
+// polygon_data<double> spiralpoly;
+// spiralpoly.set(spiralpoints.begin(), spiralpoints.end());
+// polygon_set_data<double> handset;
+// handset += handpoly;
+// polygon_set_data<double> spiralset;
+// spiralset += spiralpoly;
+// polygon_set_data<double> xorset = handset ^ spiralset;
+// std::vector<polygon_data<double> > polys;
+// polys += xorset;
+// std::cout << polys.size() << std::endl;
+// for(unsigned int i = 0; i < polys.size(); ++i)
+// std::cout << polys[i] << std::endl;
+//}
+
+bool testDirectionalSize() {
+ {
+ PolygonSet ps(VERTICAL);
+ ps += Rectangle(0, 0, 100, 100);
+ ps.resize(0, -10, 0, -10);
+ std::vector<Rectangle> rects;
+ ps.get(rects);
+ if(rects.size() != 1) return false;
+ std::cout << rects[0] << std::endl;
+ std::cout << Rectangle(0, 0, 90, 90) << std::endl;
+ if(rects[0] != Rectangle(0, 0, 90, 90)) return false;
+ }
+ {
+ PolygonSet ps(VERTICAL);
+ ps += Rectangle(0, 0, 100, 100);
+ ps.resize(0, 0, 0, -10);
+ std::vector<Rectangle> rects;
+ ps.get(rects);
+ if(rects.size() != 1) return false;
+ std::cout << rects[0] << std::endl;
+ std::cout << Rectangle(0, 0, 100, 90) << std::endl;
+ if(rects[0] != Rectangle(0, 0, 100, 90)) return false;
+ }
+ {
+ PolygonSet ps;
+ ps += Rectangle(0, 0, 100, 100);
+ ps.resize(0, -10, 0, 0);
+ std::vector<Rectangle> rects;
+ ps.get(rects);
+ if(rects.size() != 1) return false;
+ std::cout << rects[0] << std::endl;
+ std::cout << Rectangle(0, 0, 90, 100) << std::endl;
+ if(rects[0] != Rectangle(0, 0, 90, 100)) return false;
+ }
+ {
+ PolygonSet ps;
+ ps += Rectangle(0, 0, 100, 100);
+ ps.resize(0, 0, -10, 0);
+ std::vector<Rectangle> rects;
+ ps.get(rects);
+ if(rects.size() != 1) return false;
+ std::cout << rects[0] << std::endl;
+ std::cout << Rectangle(0, 10, 100, 100) << std::endl;
+ if(rects[0] != Rectangle(0, 10, 100, 100)) return false;
+ }
+ {
+ PolygonSet ps;
+ ps += Rectangle(0, 0, 100, 100);
+ ps.resize(-10, 0, 0, 0);
+ std::vector<Rectangle> rects;
+ ps.get(rects);
+ if(rects.size() != 1) return false;
+ std::cout << rects[0] << std::endl;
+ std::cout << Rectangle(10, 0, 100, 100) << std::endl;
+ if(rects[0] != Rectangle(10, 0, 100, 100)) return false;
+ }
+ {
+ PolygonSet ps;
+ ps += Rectangle(0, 0, 100, 100);
+ ps.resize(-10, 10, 0, 0);
+ std::vector<Rectangle> rects;
+ ps.get(rects);
+ if(rects.size() != 1) return false;
+ std::cout << rects[0] << std::endl;
+ std::cout << Rectangle(10, 0, 110, 100) << std::endl;
+ if(rects[0] != Rectangle(10, 0, 110, 100)) return false;
+ }
+ {
+ PolygonSet ps;
+ ps += Rectangle(0, 0, 100, 100);
+ ps.resize(-10, 10, 10, -10);
+ std::vector<Rectangle> rects;
+ ps.get(rects);
+ if(rects.size() != 1) return false;
+ std::cout << rects[0] << std::endl;
+ std::cout << Rectangle(10, -10, 110, 90) << std::endl;
+ if(rects[0] != Rectangle(10, -10, 110, 90)) return false;
+ }
+ {
+ PolygonSet ps;
+ ps += Rectangle(0, 0, 100, 100);
+ ps.resize(10, 10, -10, -10);
+ std::vector<Rectangle> rects;
+ ps.get(rects);
+ if(rects.size() != 1) return false;
+ std::cout << rects[0] << std::endl;
+ std::cout << Rectangle(-10, 10, 110, 90) << std::endl;
+ if(rects[0] != Rectangle(-10, 10, 110, 90)) return false;
+ }
+ return true;
+}
+
+bool testMaxCover() {
+ std::vector<Rectangle> rects;
+ rects.push_back(Rectangle(Interval(60, 124), Interval( 1, 3)));
+ rects.push_back(Rectangle(Interval(59, 83), Interval( 9, 28)));
+ rects.push_back(Rectangle(Interval(90, 124), Interval( 3, 29)));
+ rects.push_back(Rectangle(Interval(64, 124), Interval( 29, 35)));
+ rects.push_back(Rectangle(Interval(64, 102), Interval( 35, 49)));
+ rects.push_back(Rectangle(Interval(1, 20), Interval( 44, 60)));
+ rects.push_back(Rectangle(Interval(50, 102), Interval( 49, 71)));
+ rects.push_back(Rectangle(Interval(49, 102), Interval( 71, 72)));
+ rects.push_back(Rectangle(Interval(49, 94), Interval( 72, 75)));
+ rects.push_back(Rectangle(Interval(50, 74), Interval( 75, 81)));
+ rects.push_back(Rectangle(Interval(90, 127), Interval( 75, 81)));
+ rects.push_back(Rectangle(Interval(50, 127), Interval( 81, 82)));
+ rects.push_back(Rectangle(Interval(3, 7), Interval( 60, 88)));
+ rects.push_back(Rectangle(Interval(50, 92), Interval( 82, 94)));
+ rects.push_back(Rectangle(Interval(58, 92), Interval( 94, 111)));
+ std::vector<Rectangle> expected_result;
+ expected_result.push_back(Rectangle(Interval(60, 124), Interval( 1, 3)));
+ expected_result.push_back(Rectangle(Interval(90, 124), Interval( 1, 35)));
+ expected_result.push_back(Rectangle(Interval(90, 102), Interval( 1, 72)));
+ expected_result.push_back(Rectangle(Interval(90, 94 ), Interval(1 ,82)));
+ expected_result.push_back(Rectangle(Interval(90, 92), Interval( 1, 111)));
+ expected_result.push_back(Rectangle(Interval(59, 83 ), Interval(9, 28)));
+ expected_result.push_back(Rectangle(Interval(64, 124), Interval( 29, 35)));
+ expected_result.push_back(Rectangle(Interval(64, 102), Interval( 29, 72)));
+ expected_result.push_back(Rectangle(Interval(64, 94), Interval( 29, 75)));
+ expected_result.push_back(Rectangle(Interval(64, 74), Interval( 29, 111)));
+ expected_result.push_back(Rectangle(Interval(1, 20), Interval( 44, 60)));
+ expected_result.push_back(Rectangle(Interval(3, 7), Interval( 44, 88)));
+ expected_result.push_back(Rectangle(Interval(50, 102 ), Interval(49, 72)));
+ expected_result.push_back(Rectangle(Interval(50, 94), Interval( 49, 75)));
+ expected_result.push_back(Rectangle(Interval(50, 74), Interval( 49, 94)));
+ expected_result.push_back(Rectangle(Interval(58, 74), Interval( 49, 111)));
+ expected_result.push_back(Rectangle(Interval(49, 102 ), Interval(71, 72)));
+ expected_result.push_back(Rectangle(Interval(49, 94 ), Interval(71, 75)));
+ expected_result.push_back(Rectangle(Interval(90, 127), Interval( 75, 82)));
+ expected_result.push_back(Rectangle(Interval(50, 127), Interval( 81, 82)));
+ expected_result.push_back(Rectangle(Interval(50, 92), Interval( 81, 94)));
+ expected_result.push_back(Rectangle(Interval(58, 92), Interval( 81, 111)));
+ std::vector<Rectangle> result;
+ get_max_rectangles(result, rects);
+ std::cout << "result XOR clean: " << equivalence(result, rects) << std::endl;
+ std::cout << "expected result XOR clean: " << equivalence(expected_result, rects) << std::endl;
+ std::vector<Rectangle>& output = result;
+ std::vector<Rectangle>& voutput = expected_result;
+ std::sort(output.begin(), output.end(), less_rectangle_concept< Rectangle, Rectangle>());
+ std::sort(voutput.begin(), voutput.end(), less_rectangle_concept< Rectangle, Rectangle>());
+ if(output != voutput) {
+ std::cerr << "Max Rectangle TEST failed\n";
+ for(unsigned int i = 0; i < output.size(); ++i) {
+ std::cerr << output[i] << std::endl;
+ }
+ std::cerr << "Incorrect result\n";
+ for(unsigned int i = 0; i < voutput.size(); ++i) {
+ std::cerr << voutput[i] << std::endl;
+ }
+ std::cerr << "Max Rectangle TEST failed\n";
+ for(unsigned int i = 0; i < rects.size(); ++i) {
+ std::cout << rects[i] << std::endl;
+ }
+ return false;
+ }
+ return true;
+}
+
+void max_cover_stress_test() {
+ for(unsigned int k = 3; k < 20; k++) {
+ for(unsigned int i = 0; i < k * k; ++i) {
+ std::vector<Rectangle> rects, result;
+ //std::cout << "test " << i << std::endl;
+ for(unsigned int j = 0; j < k; ++j) {
+ int x1 = rand() % 100;
+ int x2 = rand() % 50;
+ int y1 = rand() % 100;
+ int y2 = rand() % 50;
+ rects.push_back(Rectangle(x1, y1, x1+x2, y1+y2));
+ //std::cout << rects.back() << std::endl;
+ }
+ get_max_rectangles(result, rects);
+ }
+ }
+}
+
+// namespace boost { namespace polygon{
+// template <typename GCT, typename T>
+// struct view_of {};
+
+// template <typename T>
+// struct view_of<polygon_45_concept, T> {
+// const T* t;
+// view_of(const T& obj) : t(&obj) {}
+// typedef typename polygon_traits<T>::coordinate_type coordinate_type;
+// typedef typename polygon_traits<T>::iterator_type iterator_type;
+// typedef typename polygon_traits<T>::point_type point_type;
+
+// /// Get the begin iterator
+// inline iterator_type begin() const {
+// return polygon_traits<T>::begin_points(*t);
+// }
+
+// /// Get the end iterator
+// inline iterator_type end() const {
+// return polygon_traits<T>::end_points(*t);
+// }
+
+// /// Get the number of sides of the polygon
+// inline unsigned int size() const {
+// return polygon_traits<T>::size(*t);
+// }
+
+// /// Get the winding direction of the polygon
+// inline winding_direction winding() const {
+// return polygon_traits<T>::winding(*t);
+// }
+// };
+
+// template <typename T1, typename T2>
+// view_of<T1, T2> view_as(const T2& obj) { return view_of<T1, T2>(obj); }
+
+// template <typename T>
+// struct geometry_concept<view_of<polygon_45_concept, T> > {
+// typedef polygon_45_concept type;
+// };
+
+// template <typename T>
+// struct view_of<polygon_90_concept, T> {
+// const T* t;
+// view_of(const T& obj) : t(&obj) {}
+// typedef typename polygon_traits<T>::coordinate_type coordinate_type;
+// typedef typename polygon_traits<T>::iterator_type iterator_type;
+// typedef typename polygon_traits<T>::point_type point_type;
+// typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type;
+
+// /// Get the begin iterator
+// inline compact_iterator_type begin_compact() const {
+// return compact_iterator_type(polygon_traits<T>::begin_points(*t),
+// polygon_traits<T>::end_points(*t));
+// }
+
+// /// Get the end iterator
+// inline compact_iterator_type end_compact() const {
+// return compact_iterator_type(polygon_traits<T>::end_points(*t),
+// polygon_traits<T>::end_points(*t));
+// }
+
+// /// Get the number of sides of the polygon
+// inline unsigned int size() const {
+// return polygon_traits<T>::size(*t);
+// }
+
+// /// Get the winding direction of the polygon
+// inline winding_direction winding() const {
+// return polygon_traits<T>::winding(*t);
+// }
+// };
+
+// template <typename T>
+// struct geometry_concept<view_of<polygon_90_concept, T> > {
+// typedef polygon_90_concept type;
+// };
+// }}
+using namespace gtl;
+
+//this test fails and I'd like to get it to pass
+bool test_colinear_duplicate_points() {
+ Point pts[6] = { Point(0, 10), Point(0, 0), Point(100, 0), Point(100, 100), Point(0, 100), Point(0, 10)};
+ Polygon45 p1;
+ p1.set(pts, pts+5);
+ Polygon45 pg;
+ pg.set(pts, pts+6);
+ Polygon45 p2;
+ p2.set(pts+1, pts+6);
+ std::cout << p2 << std::endl;
+ if(!equivalence(view_as<polygon_90_concept>(p2), view_as<polygon_90_concept>(pg))) return false;
+ std::cout << p1 << std::endl;
+ if(!equivalence(view_as<polygon_90_concept>(p1), view_as<polygon_90_concept>(pg))) return false;
+ return true;
+}
+
+bool test_extents() {
+ PolygonSet psT(gtl::VERTICAL);
+ //int xy[] = { 126, 69, 54, 69, 54, 81, 126, 81 };
+ //CPolygonQuery polygon(0, 4, xy);
+ //Rectangle rectIn(54, 69, 126, 81);
+ polygon_data<int> polygon;
+ std::vector<Point> pts;
+ pts.push_back(Point(126, 69));
+ pts.push_back(Point(54, 69));
+ pts.push_back(Point(54, 81));
+ pts.push_back(Point(126, 81));
+ set_points(polygon, pts.begin(), pts.end());
+ psT.insert(view_as<polygon_90_concept>(polygon));
+
+ Rectangle rect, rect2;
+ psT.extents(rect2);
+ gtl::extents(rect, psT);
+
+ if (rect != rect2) {
+ std::cout << "gtl::Rectangles differ: " << gtl::xl(rect) << " " << gtl::xh(rect) << " " << gtl::yl(rect) << " " << gtl::yh(rect) << std::endl;
+ std::cout << " " << gtl::xl(rect2) << " " << gtl::xh(rect2) << " " << gtl::yl(rect2) << " " << gtl::yh(rect2) << std::endl;
+ return false;
+ }
+ return true;
+}
+
+bool test_extents2() {
+ Polygon45Set psT;
+ Point xy[] = { Point(130, 50), Point(50, 50), Point(50, 100), Point(119, 100),
+ Point(119, 59), Point(89, 89), Point(59, 59), Point(119, 59), Point(119, 100), Point(130, 100) };
+ Polygon45 polygon(xy, xy+10);
+
+ psT.insert(polygon);
+ psT += 2;
+
+ Rectangle rect, rect2;
+ psT.extents(rect2);
+ gtl::extents(rect, psT);
+ std::cout << "Extents: " << gtl::xl(rect) << " " << gtl::xh(rect) << " " << gtl::yl(rect) << " " << gtl::yh(rect) << std::endl;
+ std::cout << "Extents: " << gtl::xl(rect2) << " " << gtl::xh(rect2) << " " << gtl::yl(rect2) << " " << gtl::yh(rect2) << std::endl;
+ std::vector<Polygon45WithHoles> pwhs;
+ psT.get(pwhs);
+ for(unsigned int i = 0; i < pwhs.size(); ++i) {
+ std::cout << pwhs[i] << std::endl;
+ }
+ return gtl::equivalence(rect, rect2);
+}
+
+/*************New Polygon Formation Tests********************/
+/*
+ *
+ * Test Input:
+ * +--------------------+
+ * | +-------+ |
+ * | | | |
+ * | | | |
+ * +-----+ | | |
+ * | | | |
+ * | | | |
+ * +-----+ | | |
+ * | | | |
+ * | | | |
+ * | +-------+ |
+ * +--------+ |
+ * | |
+ * | |
+ * +--------+ |
+ * | |
+ * | |
+ * +--------+ |
+ * | |
+ * | |
+ * +--------+ |
+ * | |
+ * | |
+ * +--------------------+
+ *
+ * Test Plan:
+ * a. call 'get(out, param)' , param >=4
+ * b. check if each polygon in the container is <= param
+ * c. check the area of all the pieces sum up to original piece
+ */
+typedef int intDC;
+typedef boost::polygon::polygon_90_with_holes_data<intDC> GTLPolygon;
+typedef boost::polygon::polygon_90_set_data<intDC> GTLPolygonSet;
+typedef boost::polygon::polygon_90_concept GTLPolygonConcept;
+typedef boost::polygon::point_data<intDC> GTLPoint;
+inline void PrintPolygon(const GTLPolygon&);
+inline GTLPolygon CreateGTLPolygon(const int*, size_t);
+int test_new_polygon_formation(int argc, char** argv){
+ // //
+ // Sub-Test-1: do a Boolean and call the new get //
+ // //
+ int coordinates[] = {0,0, 10,0, 10,10, 0,10};
+ int coordinates1[] = {9,1, 20,1, 20,10, 9,10};
+ std::vector<GTLPoint> pts;
+ size_t count = sizeof(coordinates)/(2*sizeof(intDC));
+ size_t count1 = sizeof(coordinates1)/(2*sizeof(intDC));
+ GTLPolygon poly, poly1;
+ GTLPolygonSet polySet;
+
+ poly = CreateGTLPolygon(coordinates, count);
+ poly1 = CreateGTLPolygon(coordinates1, count1);
+
+ polySet.insert(poly);
+ polySet.insert(poly1);
+
+ std::vector<GTLPolygon> result;
+ polySet.get(result, 100);
+
+ if(result.size() > 1){
+ std::cerr << "FAILED: expecting only one polygon because the"
+ " threshold is 100" << std::endl;
+ return 1;
+ }
+
+ if(result[0].size() != 6){
+ std::cerr << "FAILED: expecting only 6 vertices" << std::endl;
+ return 1;
+ }
+
+ if(area(result[0]) != 190){
+ std::cerr <<"FAILED: expecting only 6 vertices" << std::endl;
+ return 1;
+ }
+
+ //expect no more than 1 polygon
+ std::cout << "Found " << result.size() << "polygons after union"
+ << std::endl;
+ for(size_t i=0; i<result.size(); i++){
+ PrintPolygon(result[i]);
+ }
+
+ intDC shell_coords[] = {0,0, 10,0, 10,21, 0,21, 0,15, 3,15, 3,13,
+ 0,13, 0,10, 5,10, 5,8, 0,8, 0,5, 5,5, 5,3, 0,3};
+ intDC hole_coords[] = {4,11, 7,11, 7,19, 4,19};
+ GTLPolygon slice_polygon, slice_hole;
+ count = sizeof(shell_coords)/(2*sizeof(intDC));
+ count1 = sizeof(hole_coords)/(2*sizeof(intDC));
+
+ slice_polygon = CreateGTLPolygon(shell_coords, count);
+ slice_hole = CreateGTLPolygon(hole_coords, count1);
+
+ result.clear();
+ polySet.clear();
+ polySet.insert(slice_polygon);
+ polySet.insert(slice_hole, true);
+
+ polySet.get(result);
+ double gold_area = 0;
+ std::cout << "Found " << result.size() << " slices" << std::endl;
+ for(size_t i=0; i<result.size(); i++){
+ PrintPolygon(result[i]);
+ gold_area += area(result[i]);
+ }
+
+ result.clear();
+ polySet.get(result, 6);
+ double platinum_area = 0;
+ std::cout << "Found " << result.size() << " slices" << std::endl;
+ for(size_t i=0; i<result.size(); i++){
+ PrintPolygon(result[i]);
+ platinum_area += area(result[i]);
+ if(result[i].size() > 6){
+ std::cerr << "FAILED: expecting size to be less than 6" << std::endl;
+ return 1;
+ }
+ }
+
+ std::cout << "platinum_area = " << platinum_area << " , gold_area="
+ << gold_area << std::endl;
+ if( platinum_area != gold_area){
+ std::cerr << "FAILED: Area mismatch" << std::endl;
+ return 1;
+ }
+ std::cout << "[SUB-TEST-1] PASSED\n";
+
+ result.clear();
+ polySet.get(result, 4);
+ platinum_area = 0;
+ std::cout << "Found " << result.size() << " slices" << std::endl;
+ for(size_t i=0; i<result.size(); i++){
+ PrintPolygon(result[i]);
+ platinum_area += area(result[i]);
+ if(result[i].size() > 4){
+ std::cerr << "FAILED: expecting size to be < 4" << std::endl;
+ return 1;
+ }
+ }
+
+ std::cout << "platinum_area=" << platinum_area << ", gold_area="
+ << gold_area << std::endl;
+
+ if( platinum_area != gold_area){
+ std::cerr << "FAILED: Area mismatch" << std::endl;
+ return 1;
+ }
+
+ std::cout << "[SUB-TEST-1] PASSED" << std::endl;
+ return 0;
+}
+
+/*
+ * INPUT:
+ * +--------+
+ * | |
+ * | |
+ * | +---+
+ * | |
+ * | +---+
+ * | |
+ * +--------+
+ * X
+ *
+ * TEST PLAN: as the sweepline moves and reaches
+ * X the number of vertices in the solid jumps by 4
+ * instead of 2. So make sure we don't get a 6 vertex
+ * polygon when the threshold is 4 and 6.
+ */
+int test_new_polygon_formation_marginal_threshold(int argc, char**){
+ std::vector<GTLPoint> pts;
+ GTLPolygon polygon;
+ GTLPolygonSet pset;
+ std::vector<GTLPolygon> result;
+ intDC coords[] = {0,0, 15,0, 15,10, 10,10, 10,15, 5,15, 5,10, 0,10};
+ size_t count = sizeof(coords)/(2*sizeof(intDC));
+
+ polygon = CreateGTLPolygon(coords, count);
+ pset.insert(polygon);
+
+ for(size_t i=0; i<1; i++){
+ pset.get(result, i ? 4 : 6);
+ double gold_area = 175, plat_area = 0;
+ for(size_t i=0; i<result.size(); i++){
+ if(result[i].size() > (i ? 4 : 6) ){
+ size_t expected = i ? 4 : 6;
+ std::cerr << "FAILED: Expecting no more than " <<
+ expected << " vertices" << std::endl;
+ return 1;
+ }
+ PrintPolygon(result[i]);
+ plat_area += area(result[i]);
+ }
+
+ if(plat_area != gold_area){
+ std::cerr << "FAILED area mismatch gold=" << gold_area <<
+ " plat=" << plat_area << std::endl;
+ return 1;
+ }
+ }
+ std::cout << "Test Passed" << std::endl;
+ return 0;
+}
+
+inline void PrintPolygon(const GTLPolygon& p){
+ //get an iterator of the point_data<int>
+ boost::polygon::point_data<int> pt;
+ boost::polygon::polygon_90_data<int>::iterator_type itr;
+
+ size_t vertex_id = 0;
+ for(itr = p.begin(); itr != p.end(); ++itr){
+ pt = *itr;
+ std::cout << "Vertex-" << ++vertex_id << "(" << pt.x() <<
+ "," << pt.y() << ")" << std::endl;
+ }
+}
+
+// size: is the number of vertices //
+inline GTLPolygon CreateGTLPolygon(const int *coords, size_t size){
+ GTLPolygon r;
+ std::vector<GTLPoint> pts;
+
+ for(size_t i=0; i<size; i++){
+ pts.push_back( GTLPoint(coords[2*i], coords[2*i+1]) );
+ }
+ boost::polygon::set_points(r, pts.begin(), pts.end());
+ return r;
+}
+
+/************************************************************/
+
+int main() {
+ test_view_as();
+ //this test fails and I'd like to get it to pass
+ //if(!test_colinear_duplicate_points()) return 1;
+ if(!test_extents2()) return 1;
+ if(!test_extents()) return 1;
+ if(!testMaxCover()) return 1;
+ //max_cover_stress_test(); //does not include functional testing
+ if(!testDirectionalSize()) return 1;
+ testHand();
+ //testHandFloat();
+ if(!testpip()) return 1;
+ {
+ PolygonSet ps;
+ Polygon p;
+ assign(ps, p);
+ }
+ if(!testViewCopyConstruct()) return 1;
+ if(!test_grow_and_45()) return 1;
+ if(!test_self_xor_45()) return 1;
+ if(!test_self_xor()) return 1;
+ if(!test_directional_resize()) return 1;
+ if(!test_scaling_by_floating()) return 1;
+ if(!test_SQRT1OVER2()) return 1;
+ if(!test_get_trapezoids()) return 1;
+ if(!test_get_rectangles()) return 1;
+ if(!test_45_concept_interact()) return 1;
+ if(!test_45_touch_r()) return 1;
+ if(!test_45_touch_ur()) return 1;
+ if(!test_45_touch()) return 1;
+ if(!test_45_touch_boundaries()) return 1;
+ {
+ Point pts[] = {Point(0,0), Point(5, 5), Point(5, 0)};
+ Polygon45 p45(pts, pts+3);
+ pts[1] = Point(0, 5);
+ Polygon45 p452(pts, pts+3);
+ if(!test_two_polygons(p45,p452)) return 1;
+ pts[2] = Point(5,5);
+ p45.set(pts, pts+3);
+ if(!test_two_polygons(p45,p452)) return 1;
+ pts[0] = Point(5,0);
+ p452.set(pts, pts+3);
+ if(!test_two_polygons(p45, p452)) return 1;
+ Point pts2[] = {Point(0,5), Point(5, 5), Point(5, 0)};
+ Point pts3[] = {Point(0,0), Point(5, 5), Point(5, 0)};
+ p45.set(pts2, pts2 + 3);
+ p452.set(pts3, pts3+3);
+ if(!test_two_polygons(p45, p452)) return 1;
+ Point pts4[] = {Point(0, 5), Point(3, 2), Point(3,5)};
+ Point pts5[] = {Point(0,0), Point(5, 5), Point(5, 0)};
+ p45.set(pts4, pts4+3);
+ p452.set(pts5, pts5+3);
+ if(!test_two_polygons(p45, p452)) return 1;
+ }
+ {
+ std::vector<point_data<int> > pts;
+ pts.push_back(point_data<int>(0, 0));
+ pts.push_back(point_data<int>(10, 0));
+ pts.push_back(point_data<int>(10, 10));
+ pts.push_back(point_data<int>(0, 10));
+ std::vector<point_data<int> > pts2;
+ pts2.push_back(point_data<int>(0, 0));
+ pts2.push_back(point_data<int>(10, 10));
+ pts2.push_back(point_data<int>(0, 20));
+ pts2.push_back(point_data<int>(-10, 10));
+ std::vector<point_data<int> > pts3;
+ pts3.push_back(point_data<int>(0, 0));
+ pts3.push_back(point_data<int>(10, 11));
+ pts3.push_back(point_data<int>(0, 20));
+ pts3.push_back(point_data<int>(-100, 8));
+ polygon_data<int> p, p1; p.set(pts3.begin(), pts3.end());
+ polygon_45_data<int> p45, p451; p45.set(pts2.begin(), pts2.end());
+ polygon_90_data<int> p90, p901; p90.set(pts.begin(), pts.end());
+ polygon_with_holes_data<int> pwh, pwh1; pwh.set(pts3.begin(), pts3.end());
+ polygon_45_with_holes_data<int> p45wh, p45wh1; p45wh.set(pts2.begin(), pts2.end());
+ polygon_90_with_holes_data<int> p90wh, p90wh1; p90wh.set(pts.begin(), pts.end());
+ assign(p, p90);
+ assign(p, p45);
+ assign(p1, p);
+ //illegal: assign(p, p90wh);
+ //illegal: assign(p, p45wh);
+ //illegal: assign(p, pwh);
+
+ assign(p45, p90);
+ assign(p451, p45);
+ //illegal: assign(p45, p);
+ //illegal: assign(p45, p90wh);
+ //illegal: assign(p45, p45wh);
+ //illegal: assign(p45, pwh);
+
+ assign(p901, p90);
+ //illegal: assign(p90, p45);
+ //illegal: assign(p90, p);
+ //illegal: assign(p90, p90wh);
+ //illegal: assign(p90, p45wh);
+ //illegal: assign(p90, pwh);
+
+ assign(pwh, p90);
+ assign(pwh, p45);
+ assign(pwh, p);
+ assign(pwh, p90wh);
+ assign(pwh, p45wh);
+ assign(pwh1, pwh);
+
+ assign(p45wh, p90);
+ assign(p45wh, p45);
+ //illegal: assign(p45wh, p);
+ assign(p45wh, p90wh);
+ assign(p45wh1, p45wh);
+ //illegal: assign(p45wh, pwh);
+
+ assign(p90wh, p90);
+ //illegal: assign(p90wh, p45);
+ //illegal: assign(p90wh, p);
+ assign(p90wh1, p90wh);
+ //illegal: assign(p90wh, p45wh);
+ //illegal: assign(p90wh, pwh);
+ pts.clear();
+ pts.push_back(point_data<int>(0, 0));
+ pts.push_back(point_data<int>(3, 0));
+ pts.push_back(point_data<int>(0, 1));
+ p.set(pts.begin(), pts.end());
+ std::cout << std::endl; std::cout << (area(p90));
+ std::cout << std::endl; std::cout << (area(p45));
+ std::cout << std::endl; std::cout << (area(p));
+ std::cout << std::endl; std::cout << (area(p90wh));
+ std::cout << std::endl; std::cout << (area(p45wh));
+ std::cout << std::endl; std::cout << (area(pwh));
+ std::cout << std::endl;
+ point_data<int> pt(1, 1);
+ std::cout << contains(p, pt) << std::endl;
+ std::cout << contains(p90, pt) << std::endl;
+
+ interval_data<int> ivl = construct<interval_data<int> >(0, 10);
+ std::cout << get(ivl, LOW) << std::endl;
+ set(ivl, HIGH, 20);
+
+ std::cout << perimeter(p) << std::endl;
+ if(winding(p) == LOW) std::cout << "LOW" << std::endl;
+ if(winding(p) == HIGH) std::cout << "HIGH" << std::endl;
+ rectangle_data<polygon_long_long_type> rd;
+ std::cout << extents(rd, p) << std::endl;
+ std::cout << rd << std::endl;
+
+ boolean_op::testBooleanOr<int>();
+
+ std::vector<rectangle_data<int> > rects1, rects2;
+ rects2.push_back(rectangle_data<int>(0, 0, 10, 10));
+ print_is_polygon_90_set_concept((polygon_90_set_data<int>()));
+ print_is_mutable_polygon_90_set_concept((polygon_90_set_data<int>()));
+ print_is_polygon_90_set_concept((polygon_90_data<int>()));
+ print_is_polygon_90_set_concept((std::vector<polygon_90_data<int> >()));
+ assign(rects1, rects2);
+ polygon_90_set_data<int> ps90;
+ assign(ps90, rects2);
+ assign(rects2, ps90);
+ assign(ps90, p90);
+ assign(rects2, p90);
+ std::cout << p90 << std::endl;
+ for(unsigned int i = 0; i < rects2.size(); ++i) {
+ std::cout << rects2[i] << std::endl;
+ }
+ bloat(rects2, 10);
+ shrink(rects2[0], 10);
+ for(unsigned int i = 0; i < rects2.size(); ++i) {
+ std::cout << rects2[i] << std::endl;
+ }
+ move(rects2[0], HORIZONTAL, 30);
+ assign(rects1, rects2 + p90);
+ std::cout << "result of boolean or\n";
+ for(unsigned int i = 0; i < rects1.size(); ++i) {
+ std::cout << rects1[i] << std::endl;
+ }
+ rects1 -= p90;
+ std::cout << "result of boolean not\n";
+ for(unsigned int i = 0; i < rects1.size(); ++i) {
+ std::cout << rects1[i] << std::endl;
+ }
+ rects1 += p90;
+ std::cout << "result of boolean OR\n";
+ for(unsigned int i = 0; i < rects1.size(); ++i) {
+ std::cout << rects1[i] << std::endl;
+ }
+ rects1 *= p90;
+ std::cout << "result of boolean AND\n";
+ for(unsigned int i = 0; i < rects1.size(); ++i) {
+ std::cout << rects1[i] << std::endl;
+ }
+ rects1 ^= rects2;
+ std::cout << "result of boolean XOR\n";
+ for(unsigned int i = 0; i < rects1.size(); ++i) {
+ std::cout << rects1[i] << std::endl;
+ }
+ rects2.clear();
+ get_max_rectangles(rects2, p90);
+ std::cout << "result of max rectangles\n";
+ for(unsigned int i = 0; i < rects2.size(); ++i) {
+ std::cout << rects2[i] << std::endl;
+ }
+ rects2.clear();
+ //operator += and -= don't support polygons, so + and - should not exist
+// rects2 += p90 + 6;
+// std::cout << "result of resize\n";
+// for(unsigned int i = 0; i < rects2.size(); ++i) {
+// std::cout << rects2[i] << std::endl;
+// }
+// std::cout << "result of resize\n";
+ std::vector<polygon_90_with_holes_data<int> > polyswh1, polyswh2;
+// polyswh1 += p90 -2;
+// for(unsigned int i = 0; i < polyswh1.size(); ++i) {
+// std::cout << polyswh1[i] << std::endl;
+// }
+// std::cout << "result of resize\n";
+ std::vector<polygon_90_data<int> > polys1, polys2;
+ polys1 += p90;
+ polys1 -= 2;
+// polys1 += p90 -2;
+ for(unsigned int i = 0; i < polys1.size(); ++i) {
+ std::cout << polys1[i] << std::endl;
+ }
+
+ boolean_op_45<int>::testScan45(std::cout);
+ polygon_45_formation<int>::testPolygon45Formation(std::cout);
+ polygon_45_formation<int>::testPolygon45Tiling(std::cout);
+
+ axis_transformation atr;
+ transform(p, atr);
+ transform(p45, atr);
+ transform(p90, atr);
+ transform(pwh, atr);
+ transform(p45wh, atr);
+ transform(p90wh, atr);
+ scale_up(p, 2);
+ scale_up(p45, 2);
+ scale_up(p90, 2);
+ scale_up(pwh, 2);
+ scale_up(p45wh, 2);
+ scale_up(p90wh, 2);
+ scale_down(p, 2);
+ scale_down(p45, 2);
+ scale_down(p90, 2);
+ scale_down(pwh, 2);
+ scale_down(p45wh, 2);
+ scale_down(p90wh, 2);
+ std::vector<polygon_45_data<int> > p45s1, p45s2;
+ std::cout << equivalence(p45s1, p45s2) << std::endl;
+ std::cout << equivalence(p45, p45wh) << std::endl;
+ std::cout << equivalence(p90, p45wh) << std::endl;
+ gtl::assign(p45s1, p90);
+ p90 = polys1[0];
+ move(p90, orientation_2d(HORIZONTAL), 8);
+ std::cout << p90 << std::endl << p45wh << std::endl;
+ polygon_45_set_data<int> ps45 = p90 + p45wh;
+ assign(p45s1, ps45);
+ std::cout << "result\n";
+ for(unsigned int i = 0; i < p45s1.size(); ++i) {
+ std::cout << p45s1[i] << std::endl;
+ }
+ std::cout << equivalence(p, pwh) << std::endl;
+ std::cout << equivalence(p90, pwh) << std::endl;
+ std::cout << equivalence(p45, pwh) << std::endl;
+ std::cout << equivalence(pwh, pwh) << std::endl;
+ p + pwh;
+ p90 + pwh;
+ p45 + pwh;
+ std::cout << testRectangle() << std::endl;
+ std::cout << testPolygon() << std::endl;
+ std::cout << testPropertyMerge() << std::endl;
+ std::cout << testPolygonAssign() << std::endl;
+ std::cout << testPolygonWithHoles() << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testPolygonArbitraryFormationRect(std::cout)) << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testPolygonArbitraryFormationP1(std::cout)) << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testPolygonArbitraryFormationP2(std::cout)) << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testPolygonArbitraryFormationPolys(std::cout)) << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testPolygonArbitraryFormationSelfTouch1(std::cout)) << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testPolygonArbitraryFormationSelfTouch2(std::cout)) << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testPolygonArbitraryFormationSelfTouch3(std::cout)) << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testSegmentIntersection(std::cout)) << std::endl;
+ std::cout << (property_merge<int, int>::test_insertion(std::cout)) << std::endl;
+ std::cout << (line_intersection<int>::test_verify_scan(std::cout)) << std::endl;
+ std::cout << (line_intersection<int>::test_validate_scan(std::cout)) << std::endl;
+ std::cout << (scanline<int, int>::test_scanline(std::cout)) << std::endl;
+ std::cout << (property_merge<int, int>::test_merge(std::cout)) << std::endl;
+ std::cout << (property_merge<int, int>::test_intersection(std::cout)) << std::endl;
+ std::cout << (polygon_arbitrary_formation<int>::testPolygonArbitraryFormationColinear(std::cout)) << std::endl;
+ std::cout << (property_merge<int, int>::test_manhattan_intersection(std::cout)) << std::endl;
+ std::cout << (test_arbitrary_boolean_op<int>(std::cout)) << std::endl;
+ }
+ {
+ polygon_set_data<int> psd;
+ rectangle_data<int> rect;
+ set_points(rect, point_data<int>(0, 0), point_data<int>(10, 10));
+ psd.insert(rect);
+ polygon_set_data<int> psd2;
+ set_points(rect, point_data<int>(5, 5), point_data<int>(15, 15));
+ psd2.insert(rect);
+ std::vector<polygon_data<int> > pv;
+ polygon_set_data<int> psd3;
+ psd3 = psd + psd2;
+ psd3.get(pv);
+ for(unsigned int i = 0; i < pv.size(); ++i) {
+ std::cout << pv[i] << std::endl;
+ }
+ psd += psd2;
+ pv.clear();
+ psd3.get(pv);
+ for(unsigned int i = 0; i < pv.size(); ++i) {
+ std::cout << pv[i] << std::endl;
+ }
+ }
+ {
+ polygon_90_set_data<int> psd;
+ rectangle_data<int> rect;
+ set_points(rect, point_data<int>(0, 0), point_data<int>(10, 10));
+ psd.insert(rect);
+ polygon_90_set_data<int> psd2;
+ set_points(rect, point_data<int>(5, 5), point_data<int>(15, 15));
+ psd2.insert(rect);
+ std::vector<polygon_90_data<int> > pv;
+ interact(psd, psd2);
+ assign(pv, psd);
+ for(unsigned int i = 0; i < pv.size(); ++i) {
+ std::cout << pv[i] << std::endl;
+ }
+
+ connectivity_extraction_90<int> ce;
+ ce.insert(pv[0]);
+ ce.insert(psd2);
+ std::vector<std::set<int> > graph(2);
+ ce.extract(graph);
+ if(graph[0].size() == 1) std::cout << "connectivity extraction is alive\n";
+
+ //std::vector<rectangle_data<polygon_long_long_type> > lobs;
+ //get_max_rectangles(lobs, psd);
+ //if(lobs.size() == 1) std::cout << "max rectangles is alive\n";
+
+ std::vector<rectangle_data<int> > rv;
+ rv.push_back(rect);
+ set_points(rect, point_data<int>(0, 0), point_data<int>(10, 10));
+ rv.push_back(rect);
+ self_intersect(rv);
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+
+ assign(rv, rv + 1);
+ std::cout << rv.size() << std::endl;
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ assign(rv, rv - 1);
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ rv += 1;
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ rv -= 1;
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ rv.clear();
+ set_points(rect, point_data<int>(0, 0), point_data<int>(10, 10));
+ rv.push_back(rect);
+ set_points(rect, point_data<int>(12, 12), point_data<int>(20, 20));
+ rv.push_back(rect);
+ grow_and(rv, 7);
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ std::cout << area(rv) << std::endl;
+ std::cout << area(rv) << std::endl;
+
+ scale_up(rv, 10);
+ std::cout << area(rv) << std::endl;
+ scale_down(rv, 7);
+ std::cout << area(rv) << std::endl;
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ keep(rv, 290, 300, 7, 24, 7, 24);
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ keep(rv, 300, 310, 7, 24, 7, 24);
+ if(rv.empty()) std::cout << "keep is alive\n";
+ }
+ {
+// typedef int Unit;
+// typedef point_data<int> Point;
+// typedef interval_data<int> Interval;
+// typedef rectangle_data<int> Rectangle;
+// typedef polygon_90_data<int> Polygon;
+// typedef polygon_90_with_holes_data<int> PolygonWithHoles;
+// typedef polygon_45_data<int> Polygon45;
+// typedef polygon_45_with_holes_data<int> Polygon45WithHoles;
+// typedef polygon_90_set_data<int> PolygonSet;
+// //typedef polygon_45_set_data<int> Polygon45Set;
+// typedef axis_transformation AxisTransform;
+// typedef transformation<int> Transform;
+ //test polygon45 area, polygon45 with holes area
+ std::vector<Point> pts;
+ pts.clear();
+ pts.push_back(Point(10, 10));
+ pts.push_back(Point(15, 10));
+ pts.push_back(Point(10, 15));
+ Polygon45 polyHole;
+ polyHole.set(pts.begin(), pts.end());
+ pts.clear();
+ pts.push_back(Point(10, 0));
+ pts.push_back(Point(20, 10));
+ pts.push_back(Point(20, 30));
+ pts.push_back(Point(0, 50));
+ pts.push_back(Point(0, 10));
+ Polygon45WithHoles polyWHoles;
+ polyWHoles.set(pts.begin(), pts.end());
+ polyWHoles.set_holes(&polyHole, (&polyHole)+1);
+ std::cout << polyWHoles << std::endl;
+ std::cout << area(polyWHoles) << std::endl;
+ std::cout << area(polyWHoles) << std::endl;
+ //test polygon45, polygon45with holes transform
+ AxisTransform atr(AxisTransform::EAST_SOUTH);
+ Polygon45WithHoles p45wh(polyWHoles);
+ transform(polyWHoles, atr);
+ std::cout << polyWHoles << std::endl;
+ Transform tr(atr);
+ tr.invert();
+ transform(polyWHoles, tr);
+ std::cout << polyWHoles << std::endl;
+ if(area(polyWHoles) != 687.5) return 1;
+ //test polygon, polygon with holes transform
+ Polygon ph;
+ assign(ph, Rectangle(10, 10, 20, 20));
+ PolygonWithHoles pwh;
+ assign(pwh, Rectangle(0, 0, 100, 100));
+ pwh.set_holes(&ph, (&ph)+1);
+ std::cout << area(pwh) << std::endl;
+ transform(pwh, atr);
+ std::cout << pwh << std::endl;
+ std::cout << area(pwh) << std::endl;
+ transform(pwh, tr);
+ std::cout << pwh << std::endl;
+ std::cout << area(pwh) << std::endl;
+ if(area(pwh) != 9900) return 1;
+
+ //test point scale up / down
+ Point pt(10, 10);
+ scale_up(pt, 25);
+ if(pt != Point(250, 250)) return 1;
+ std::cout << pt << std::endl;
+ scale_down(pt, 25);
+ if(pt != Point(10, 10)) return 1;
+ std::cout << pt << std::endl;
+ scale_down(pt, 25);
+ if(pt != Point(0, 0)) return 1;
+ std::cout << pt << std::endl;
+
+ //test polygon, polygon with holes scale up down
+ PolygonWithHoles tmpPwh(pwh);
+ scale_up(pwh, 25);
+ std::cout << pwh << std::endl;
+ scale_down(pwh, 25);
+ if(area(pwh) != area(tmpPwh)) return 1;
+ std::cout << pwh << std::endl;
+ scale_down(pwh, 25);
+ std::cout << pwh << std::endl;
+ //test polygon45, polygon45 with holes is45
+ std::cout << is_45(polyHole) << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ pts.clear();
+ pts.push_back(Point(10, 10));
+ pts.push_back(Point(15, 10));
+ pts.push_back(Point(10, 16));
+ polyHole.set(pts.begin(), pts.end());
+ std::cout << is_45(polyHole) << std::endl;
+ if(is_45(polyHole) != false) return 1;
+ //test polygon45, polygon45 with holes snap 45
+ snap_to_45(polyHole);
+ std::cout << is_45(polyHole) << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ std::cout << polyHole << std::endl;
+ //test polygon45, polygon45 with holes scalue up down
+ scale_up(polyHole, 10000);
+ std::cout << polyHole << std::endl;
+ scale_down(polyHole, 3);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 5);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 7);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 13);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_up(polyHole, 3);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ pts.clear();
+ pts.push_back(Point(11, 1));
+ pts.push_back(Point(21, 11));
+ pts.push_back(Point(11, 21));
+ pts.push_back(Point(1, 11));
+ polyHole.set(pts.begin(), pts.end());
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 3);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_up(polyHole, 10000);
+ std::cout << polyHole << std::endl;
+ scale_down(polyHole, 3);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 5);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 7);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 13);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_up(polyHole, 3);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+ scale_down(polyHole, 2);
+ std::cout << is_45(polyHole) << " " << polyHole << std::endl;
+ if(is_45(polyHole) != true) return 1;
+
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_up(polyWHoles, 100013);
+ std::cout << polyWHoles << std::endl;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 2);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 2);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 2);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 2);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 2);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 2);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 2);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 3);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+ scale_down(polyWHoles, 2);
+ std::cout << is_45(polyWHoles) << " " << polyWHoles << std::endl;
+ if(is_45(polyWHoles) != true) return 1;
+
+ std::cout << (boolean_op_45<Unit>::testScan45(std::cout)) << std::endl;
+ std::cout << (polygon_45_formation<Unit>::testPolygon45Formation(std::cout)) << std::endl;
+ std::cout << (polygon_45_formation<Unit>::testPolygon45Tiling(std::cout)) << std::endl;
+
+
+ {
+ PolygonSet ps;
+ Rectangle rect;
+ ps.insert(Rectangle(0, 0, 10, 10));
+ std::cout << area(ps) << std::endl;
+ if(area(ps) != 100) return 1;
+ scale_up(ps, 3);
+ std::cout << area(ps) << std::endl;
+ if(area(ps) != 900) return 1;
+ scale_down(ps, 2);
+ std::cout << area(ps) << std::endl;
+ if(area(ps) != 225) return 1;
+ transform(ps, atr);
+ std::vector<Rectangle> rv;
+ rv.clear();
+ ps.get(rv);
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ transform(ps, tr);
+ rv.clear();
+ ps.get(rv);
+ if(rv.size() == 1) {
+ assign(rect, rv.back());
+ std::cout << rect << std::endl;
+ }
+ }
+ //test polygon45set transform
+ pts.clear();
+ pts.push_back(Point(10, 10));
+ pts.push_back(Point(15, 10));
+ pts.push_back(Point(10, 15));
+ polyHole.set(pts.begin(), pts.end());
+ Polygon45Set ps451, ps452;
+ ps451.insert(polyHole);
+ ps452 = ps451;
+ std::cout << (ps451 == ps452) << std::endl;
+ if(ps451 != ps452) return 1;
+ ps451.transform(atr);
+ std::cout << (ps451 == ps452) << std::endl;
+ if(ps451 == ps452) return 1;
+ ps451.transform(tr);
+ std::cout << (ps451 == ps452) << std::endl;
+ if(ps451 != ps452) return 1;
+
+ //test polygon45set area
+ std::cout << area(ps451) << std::endl;
+ if(area(ps451) != 12.5) return 1;
+ //test polygon45set scale up down
+ ps451.scale_up(3);
+ std::cout << area(ps451) << std::endl;
+ if(area(ps451) != 112.5) return 1;
+ ps451.scale_down(2);
+ std::cout << area(ps451) << std::endl;
+ if(area(ps451) != 32) return 1;
+ //test polygonset scalue up down
+ }
+ {
+ std::cout << (testPolygon45SetRect()) << std::endl;
+ testPolygon45SetPerterbation(); //re-enable after non-intersection fix
+ testPolygon45Set();
+ testPolygon45SetDORA(); //re-enable after non-intersection fix
+ polygon_45_set_data<int> ps45_1, ps45_2, ps45_3;
+ ps45_1.insert(rectangle_data<int>(0, 0, 10, 10));
+ ps45_2.insert(rectangle_data<int>(5, 5, 15, 15));
+ std::vector<polygon_45_data<int> > p45s;
+ ps45_3 = ps45_1 | ps45_2;
+ ps45_3.get(p45s);
+ if(p45s.size()) std::cout << p45s[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ p45s.clear();
+ ps45_3 = ps45_1 + ps45_2;
+ ps45_3.get(p45s);
+ if(p45s.size()) std::cout << p45s[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ p45s.clear();
+ ps45_3 = ps45_1 * ps45_2;
+ ps45_3.get(p45s);
+ if(p45s.size()) std::cout << p45s[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ p45s.clear();
+ ps45_3 = ps45_1 - ps45_2;
+ ps45_3.get(p45s);
+ if(p45s.size()) std::cout << p45s[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ p45s.clear();
+ ps45_3 = ps45_1 ^ ps45_2;
+ ps45_3.get(p45s);
+ if(p45s.size() == 2) std::cout << p45s[0] << " " << p45s[1] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ std::vector<point_data<int> > pts;
+ pts.clear();
+ pts.push_back(point_data<int>(7, 0));
+ pts.push_back(point_data<int>(20, 13));
+ pts.push_back(point_data<int>(0, 13));
+ pts.push_back(point_data<int>(0, 0));
+ polygon_45_data<int> p45_1(pts.begin(), pts.end());
+ ps45_3.clear();
+ ps45_3.insert(p45_1);
+ p45s.clear();
+ ps45_3.get(p45s);
+ if(p45s.size()) std::cout << p45s[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ ps45_3 += 1;
+ p45s.clear();
+ ps45_3.get(p45s);
+ if(p45s.size()) std::cout << p45s[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ ps45_3 -= 1;
+ p45s.clear();
+ ps45_3.get(p45s);
+ if(p45s.size()) std::cout << p45s[0] << std::endl;
+ else {
+ std::cout << "test failed\n";
+ return 1;
+ }
+ }
+ {
+ polygon_90_set_data<int> p90sd;
+ p90sd.insert(rectangle_data<int>(0, 0, 10, 10));
+ std::vector<rectangle_data<int> > rects;
+ std::vector<polygon_90_data<int> > polys90;
+ std::vector<polygon_90_with_holes_data<int> > pwhs90;
+ assign(rects, p90sd);
+ assign(polys90, p90sd);
+ assign(pwhs90, p90sd);
+ std::cout << equivalence(rects, polys90) << std::endl;
+ std::cout << equivalence(pwhs90, polys90) << std::endl;
+ pwhs90.clear();
+ assign(pwhs90, polys90);
+ std::cout << equivalence(pwhs90, polys90) << std::endl;
+ }
+ {
+ polygon_45_set_data<int> p45sd;
+ p45sd.insert(rectangle_data<int>(0, 0, 10, 10));
+ std::vector<rectangle_data<int> > rects;
+ std::vector<polygon_45_data<int> > polys45;
+ std::vector<polygon_45_with_holes_data<int> > pwhs45;
+ get_trapezoids(polys45, p45sd);
+ assign(polys45, p45sd);
+ assign(pwhs45, p45sd);
+ std::cout << equivalence(pwhs45, polys45) << std::endl;
+ pwhs45.clear();
+ assign(pwhs45, polys45);
+ std::cout << equivalence(pwhs45, polys45) << std::endl;
+ }
+ {
+ polygon_set_data<int> psd;
+ psd.insert(rectangle_data<int>(0, 0, 10, 10));
+ std::vector<polygon_data<int> > polys;
+ std::vector<polygon_with_holes_data<int> > pwhs;
+ assign(polys, psd);
+ assign(pwhs, psd);
+ std::cout << equivalence(pwhs, polys) << std::endl;
+ pwhs.clear();
+ assign(pwhs, polys);
+ std::cout << equivalence(pwhs, polys) << std::endl;
+ }
+ {
+ polygon_90_set_data<int> ps1(HORIZONTAL), ps2(VERTICAL);
+ ps1 += rectangle_data<int>(0, 0, 10, 120);
+ assign(ps1, ps2);
+ std::cout << equivalence(ps1, ps2) << std::endl;
+ }
+ {
+ std::vector<rectangle_data<polygon_long_long_type> > lobs, input;
+ input.push_back(rectangle_data<polygon_long_long_type>(0, 0, 10, 10));
+ input.push_back(rectangle_data<polygon_long_long_type>(10, 5, 15, 15));
+ get_max_rectangles(lobs, input);
+ if(lobs.size() == 3) std::cout << "max rectangles is correct\n";
+ }
+ {
+ polygon_set_data<int> ps1, ps2, ps3;
+ ps1.insert(rectangle_data<int>(0, 0, 10, 10));
+ ps2.insert(rectangle_data<int>(0, 0, 15, 5));
+ ps3.insert(rectangle_data<int>(0, 0, 20, 2));
+ std::cout << area(ps1 + ps2) << std::endl;
+ keep(ps1, 0, 100, 0, 100, 0, 100);
+ if(empty(ps1)) return 1;
+ rectangle_data<int> bbox;
+ extents(bbox, ps1);
+ std::cout << bbox << std::endl;
+ //resize(ps1, 1);
+ //shrink(ps1, 1);
+ //bloat(ps1, 1);
+ scale_up(ps1, 2);
+ scale_down(ps1, 2);
+ axis_transformation atr;
+ transform(ps1, atr);
+ std::cout << area(ps1) << std::endl;
+ if(area(ps1) != 100) return 1;
+ clear(ps1);
+ if(!empty(ps1)) return 1;
+ ps1 = ps2 * ps3;
+ ps1 *= ps2;
+ ps1 - ps2;
+ ps1 -= ps2;
+ ps1 ^ ps2;
+ ps1 ^= ps2;
+ ps1 | ps2;
+ ps1 |= ps2;
+ }
+ {
+ polygon_45_set_data<int> ps45_1, ps45_2;
+ ps45_1.insert(rectangle_data<int>(0, 0, 10, 10));
+ keep(ps45_1, 0, 1000, 0, 1000, 0, 1000);
+ std::cout << area(ps45_1) << std::endl;
+ std::cout << empty(ps45_1) << std::endl;
+ rectangle_data<int> bbox;
+ extents(bbox, ps45_1);
+ std::cout << bbox << std::endl;
+ resize(ps45_1, 1);
+ shrink(ps45_1, 1);
+ bloat(ps45_1, 1);
+ scale_up(ps45_1, 2);
+ scale_down(ps45_1, 2);
+ axis_transformation atr;
+ transform(ps45_1, atr);
+ std::cout << area(ps45_1) << std::endl;
+ if(area(ps45_1) != 144) return 1;
+ clear(ps45_1);
+ if(!empty(ps45_1)) return 1;
+ }
+ {
+ std::vector<polygon_45_data<int> > p45v;
+ p45v + p45v;
+ p45v *= p45v;
+ p45v += p45v;
+ p45v - p45v;
+ p45v -= p45v;
+ p45v ^ p45v;
+ p45v ^= p45v;
+ p45v | p45v;
+ p45v |= p45v;
+ p45v + 1;
+ p45v += 1;
+ p45v - 1;
+ p45v -= 1;
+ p45v + (p45v + p45v);
+ }
+ {
+ polygon_45_set_data<int> ps45;
+ polygon_90_set_data<int> ps90;
+ std::vector<polygon_90_with_holes_data<int> > p90whv;
+ ps45.insert(ps90);
+ ps45.insert(p90whv);
+ ps45.insert(p90whv + p90whv);
+
+ ps45.insert(polygon_90_with_holes_data<int>());
+ polygon_with_holes_data<int> pwh;
+ snap_to_45(pwh);
+ }
+ {
+ polygon_90_set_data<int> ps90_1, ps90_2;
+ ps90_1.insert(rectangle_data<int>(0, 0, 10, 10));
+ keep(ps90_1, 0, 1000, 0, 1000, 0, 1000);
+ std::cout << area(ps90_1) << std::endl;
+ std::cout << empty(ps90_1) << std::endl;
+ rectangle_data<int> bbox;
+ extents(bbox, ps90_1);
+ std::cout << bbox << std::endl;
+ resize(ps90_1, 1);
+ shrink(ps90_1, 1);
+ bloat(ps90_1, 1);
+ scale_up(ps90_1, 2);
+ scale_down(ps90_1, 2);
+ scale(ps90_1, anisotropic_scale_factor<double>(2, 2));
+ scale(ps90_1, anisotropic_scale_factor<double>(0.5, 0.5));
+ axis_transformation atr;
+ transform(ps90_1, atr);
+ std::cout << area(ps90_1) << std::endl;
+ if(area(ps90_1) != 144) return 1;
+ clear(ps90_1);
+ if(!empty(ps90_1)) return 1;
+ }
+ if(!nonInteger45StessTest()) return 1;
+ {
+ using namespace gtl;
+ typedef polygon_45_property_merge<int, int> p45pm;
+ p45pm::MergeSetData msd;
+ polygon_45_set_data<int> ps;
+ ps += rectangle_data<int>(0, 0, 10, 10);
+ p45pm::populateMergeSetData(msd, ps.begin(), ps.end(), 444);
+ ps.clear();
+ ps += rectangle_data<int>(5, 5, 15, 15);
+ p45pm::populateMergeSetData(msd, ps.begin(), ps.end(), 333);
+ std::map<std::set<int>, polygon_45_set_data<int> > result;
+ p45pm::performMerge(result, msd);
+ int i = 0;
+ for(std::map<std::set<int>, polygon_45_set_data<int> >::iterator itr = result.begin();
+ itr != result.end(); ++itr) {
+ for(std::set<int>::const_iterator itr2 = (*itr).first.begin();
+ itr2 != (*itr).first.end(); ++itr2) {
+ std::cout << *itr2 << " ";
+ } std::cout << " : ";
+ std::cout << area((*itr).second) << std::endl;
+ if(i == 1) {
+ if(area((*itr).second) != 100) return 1;
+ } else
+ if(area((*itr).second) != 300) return 1;
+ ++i;
+ }
+
+
+ property_merge_45<int, int> pm;
+ pm.insert(rectangle_data<int>(0, 0, 10, 10), 444);
+ pm.insert(rectangle_data<int>(5, 5, 15, 15), 333);
+ std::map<std::set<int>, polygon_45_set_data<int> > mp;
+ pm.merge(mp);
+ i = 0;
+ for(std::map<std::set<int>, polygon_45_set_data<int> >::iterator itr = mp.begin();
+ itr != mp.end(); ++itr) {
+ for(std::set<int>::const_iterator itr2 = (*itr).first.begin();
+ itr2 != (*itr).first.end(); ++itr2) {
+ std::cout << *itr2 << " ";
+ } std::cout << " : ";
+ std::cout << area((*itr).second) << std::endl;
+ if(i == 1) {
+ if(area((*itr).second) != 25) return 1;
+ } else
+ if(area((*itr).second) != 75) return 1;
+ ++i;
+ }
+ std::map<std::vector<int>, polygon_45_set_data<int> > mp2;
+ pm.merge(mp2);
+ i = 0;
+ for(std::map<std::vector<int>, polygon_45_set_data<int> >::iterator itr = mp2.begin();
+ itr != mp2.end(); ++itr) {
+ for(std::vector<int>::const_iterator itr2 = (*itr).first.begin();
+ itr2 != (*itr).first.end(); ++itr2) {
+ std::cout << *itr2 << " ";
+ } std::cout << " : ";
+ std::cout << area((*itr).second) << std::endl;
+ if(i == 1) {
+ if(area((*itr).second) != 25) return 1;
+ } else
+ if(area((*itr).second) != 75) return 1;
+ ++i;
+ }
+ }
+ {
+ std::cout << trapezoid_arbitrary_formation<int>::testTrapezoidArbitraryFormationRect(std::cout) << std::endl;
+ std::cout << trapezoid_arbitrary_formation<int>::testTrapezoidArbitraryFormationP1(std::cout) << std::endl;
+ std::cout << trapezoid_arbitrary_formation<int>::testTrapezoidArbitraryFormationP2(std::cout) << std::endl;
+ std::cout << trapezoid_arbitrary_formation<int>::testTrapezoidArbitraryFormationPolys(std::cout) << std::endl;
+ std::cout << polygon_arbitrary_formation<int>::testPolygonArbitraryFormationSelfTouch1(std::cout) << std::endl;
+ std::cout << trapezoid_arbitrary_formation<int>::testTrapezoidArbitraryFormationSelfTouch1(std::cout) << std::endl;
+ typedef rectangle_data<int> Rectangle;
+ polygon_set_data<int> ps;
+ ps += Rectangle(0, 1, 10, 11);
+ ps += Rectangle(5, 6, 15, 16);
+ std::vector<polygon_data<int> > polys;
+ ps.get_trapezoids(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ ps.transform(axis_transformation(axis_transformation::FLIP_X));
+ polys.clear();
+ ps.get_trapezoids(polys);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ polys.clear();
+ ps.get_trapezoids(polys, HORIZONTAL);
+ for(unsigned int i = 0; i < polys.size(); ++i) {
+ std::cout << polys[i] << std::endl;
+ }
+ }
+
+ if(!test_aa_touch()) {
+ std::cout << "test_aa_touch failed\n";
+ return 1;
+ }
+ if(!test_aa_touch_ur()) {
+ std::cout << "test_aa_touch_ur failed\n";
+ return 1;
+ }
+ if(!test_aa_touch_ur()) {
+ std::cout << "test_aa_touch_ur failed\n";
+ return 1;
+ }
+ if(!test_aa_touch_r()) {
+ std::cout << "test_aa_touch_r failed\n";
+ return 1;
+ }
+ if(!test_aa_touch_boundaries()) {
+ std::cout << "test_aa_touch_boundaries failed\n";
+ return 1;
+ }
+ if(!test_aa_concept_interact()) {
+ std::cout << "test_aa_concept_interact failed\n";
+ return 1;
+ }
+
+ {
+ polygon_set_data<int> ps;
+ polygon_90_set_data<int> ps90;
+ rectangle_data<int> rect(0, 1, 10, 100);
+ std::vector<polygon_data<int> > rupolys, rupolys45;
+ ps.insert(rect);
+ ps90.insert(rect);
+ ps.bloat(10);
+ ps90.bloat(10, 10, 10, 10);
+ rupolys.clear();
+ rupolys45.clear();
+ ps.get(rupolys);
+ ps90.get(rupolys45);
+ std::cout << rupolys[0] << std::endl;
+ std::cout << rupolys45[0] << std::endl;
+ if(!equivalence(ps, ps90)) {
+ std::cout << "test manhattan vs general resize up failed\n";
+ return 1;
+ }
+ ps.shrink(10);
+ ps90.shrink(10, 10, 10, 10);
+ if(!equivalence(ps, rect)) {
+ std::cout << "test manhattan vs general resize down failed\n";
+ return 1;
+ }
+ rectangle_data<int> rect2(3, 4, 6, 80);
+ ps -= rect2;
+ ps90 -= rect2;
+ ps.bloat(1);
+ ps90.bloat(1, 1, 1, 1);
+ if(!equivalence(ps, ps90)) {
+ std::cout << "test manhattan vs general with hole resize up failed\n";
+ return 1;
+ }
+ ps.shrink(1);
+ ps90.shrink(1, 1, 1, 1);
+ if(!equivalence(ps, ps90)) {
+ std::cout << "test manhattan vs general with hole resize down failed\n";
+ return 1;
+ }
+ ps.clear();
+ polygon_45_data<int> poly;
+ std::vector<point_data<int> > pts;
+ pts.push_back(point_data<int>(0, 0));
+ pts.push_back(point_data<int>(10, 0));
+ pts.push_back(point_data<int>(0, 10));
+ polygon_45_set_data<int> ps45;
+ set_points(poly, pts.begin(), pts.end());
+ ps.insert(poly);
+ ps45.insert(poly);
+ ps.bloat(9);
+ ps45.resize(9);
+ rupolys.clear();
+ rupolys45.clear();
+ ps.get(rupolys);
+ ps45.get(rupolys45);
+ std::cout << rupolys[0] << std::endl;
+ std::cout << rupolys45[0] << std::endl;
+ pts.clear();
+ pts.push_back(point_data<int>(32, -9));
+ pts.push_back(point_data<int>(-9, 32));
+ pts.push_back(point_data<int>(-9, -9));
+ set_points(poly, pts.begin(), pts.end());
+ if(!equivalence(ps, poly)) {
+ std::cout << "test general resize up failed\n";
+ return 1;
+ }
+ // this test is waived due to rounding differences between 45 and general resizing
+ // general resizing is computing floating point coordinates for the intersection
+ // and rounding those to closest while 45 is computing the normal point and rounding
+ // that to closest, it turns out to result in different intersection point
+ // we want the general to be more accurate to avoid artifacts
+ //if(!equivalence(ps, ps45)) {
+ // std::cout << "test 45 vs general resize up failed\n";
+ // return 1;
+ //}
+ ps.shrink(9);
+ ps45.resize(-9);
+ if(!equivalence(ps, ps45)) {
+ std::cout << "test 45 vs general resize down failed\n";
+ return 1;
+ }
+ pts.clear();
+ pts.push_back(point_data<int>(1, 1));
+ pts.push_back(point_data<int>(7, 1));
+ pts.push_back(point_data<int>(1, 7));
+ set_points(poly, pts.begin(), pts.end());
+ ps.insert(poly, true);
+ ps45.insert(poly, true);
+ ps.bloat(1);
+ ps45.resize(1);
+ rupolys.clear();
+ rupolys45.clear();
+ ps.get(rupolys);
+ ps45.get(rupolys45);
+ std::cout << rupolys[0] << std::endl;
+ std::cout << rupolys45[0] << std::endl;
+ pts.clear();
+ pts.push_back(point_data<int>(12, -1));
+ pts.push_back(point_data<int>(5, 6));
+ pts.push_back(point_data<int>(5, 2));
+ pts.push_back(point_data<int>(2, 2));
+ pts.push_back(point_data<int>(2, 5));
+ pts.push_back(point_data<int>(5, 2));
+ pts.push_back(point_data<int>(5, 6));
+ pts.push_back(point_data<int>(-1, 12));
+ pts.push_back(point_data<int>(-1, -1));
+ pts.push_back(point_data<int>(12, -1));
+ set_points(poly, pts.begin(), pts.end());
+ //waived
+ //if(!equivalence(ps, poly)) {
+ // std::cout << "test general resize up with holes failed\n";
+ // return 1;
+ //}
+ //waived
+ //if(!equivalence(ps, ps45)) {
+ // std::cout << "test 45 vs general resize up with holes failed\n";
+ // return 1;
+ //}
+ ps.shrink(1);
+ ps45.resize(-1);
+ if(!equivalence(ps, ps45)) {
+ std::cout << "test 45 vs general resize down with holes failed\n";
+ return 1;
+ }
+ ps.shrink(10);
+ ps45.resize(-10);
+ if(!equivalence(ps, ps45)) {
+ std::cout << "test 45 vs general resize down 2 with holes failed\n";
+ return 1;
+ }
+ }
+
+ {
+
+ Point pts[] = {construct<Point>(1565, 5735),
+ construct<Point>(915, 5735),
+ construct<Point>(915, 7085),
+ construct<Point>(1565, 7085) };
+ Polygon poly;
+ set_points(poly, pts, pts+4);
+ bool ret=gtl::contains(poly,gtl::construct<Point>(920, 7080));
+ if(!ret) {
+ std::cout << "contains failed!" << std::endl;
+ return 1;
+ }
+ polygon_data<int> poly_aa;
+ set_points(poly_aa, pts, pts+4);
+ ret=gtl::contains(poly,gtl::construct<Point>(920, 7080));
+ if(!ret) {
+ std::cout << "contains 90 failed!" << std::endl;
+ return 1;
+ }
+ polygon_with_holes_data<int> pwh;
+ polygon_90_with_holes_data<int> p90wh;
+ Point pts2[] = {construct<Point>(565, 15735),
+ construct<Point>(15, 15735),
+ construct<Point>(15, 17085),
+ construct<Point>(565, 17085) };
+ set_points(pwh, pts2, pts2+4);
+ set_points(p90wh, pts2, pts2+4);
+ pwh.set_holes(&poly_aa, (&poly_aa)+1);
+ p90wh.set_holes(&poly, (&poly)+1);
+ ret=gtl::contains(pwh,gtl::construct<Point>(920, 7080));
+ if(ret) {
+ std::cout << "contains wh failed!" << std::endl;
+ return 1;
+ }
+ ret=gtl::contains(p90wh,gtl::construct<Point>(920, 7080));
+ if(ret) {
+ std::cout << "contains 90wh failed!" << std::endl;
+ return 1;
+ }
+ std::reverse(pts, pts+4);
+ set_points(poly, pts, pts+4);
+ ret=gtl::contains(poly,gtl::construct<Point>(920, 7080));
+ if(!ret) {
+ std::cout << "reverse contains failed!" << std::endl;
+ return 1;
+ }
+ }
+ {
+// //MULTIPOLYGON
+// (
+// ((200 400,100 400,100 300,200 400)),
+// ((300 100,200 100,200 0,300 0,300 100)),
+// ((600 700,500 700,500 600,600 700)),
+// ((700 300,600 300,600 200,700 300)),
+// ((800 500,700 600,700 500,800 500)),
+// ((900 800,800 700,900 700,900 800)),
+// ((1000 200,900 100,1000 100,1000 200)),
+// ((1000 800,900 900,900 800,1000 800))),
+ int mp1 [7][2*4] = {
+ {200,400,100,400,100,300,200,400},
+ {600,700,500,700,500,600,600,700},
+ {700,300,600,300,600,200,700,300},
+ {800,500,700,600,700,500,800,500},
+ {900,800,800,700,900,700,900,800},
+ {1000,200,900,100,1000,100,1000,200},
+ {1000,800,900,900,900,800,1000,800}
+ };
+ int mp11 [2*5] = {300,100,200,100,200,0,300,0,300,100};
+ polygon_45_set_data<int> pset1;
+ polygon_45_set_data<int> pset2;
+ for(int i = 0; i < 7; ++i) {
+ addpoly(pset1, mp1[i], 4);
+ }
+ addpoly(pset1, mp11, 5);
+// //MULTIPOLYGON
+// (
+// ((200 800,100 800,100 700,200 700,200 800)),
+// ((400 200,300 100,400 100,400 200)),
+// ((400 800,300 700,400 700,400 800)),
+// ((700 100,600 0,700 0,700 100)),
+// ((700 200,600 200,600 100,700 200)),
+// ((900 200,800 200,800 0,900 0,900 200)),
+// ((1000 300,900 200,1000 200,1000 300)))
+ int mp2 [5][2*4] = {
+ {400,200,300,100,400,100,400,200},
+ {400,800,300,700,400,700,400,800},
+ {700,100,600,0,700,0,700,100},
+ {700,200,600,200,600,100,700,200},
+ {1000,300,900,200,1000,200,1000,300},
+ };
+ int mp21 [2*5] = {200,800,100,800,100,700,200,700,200,800};
+ int mp22 [2*5] = {900,200,800,200,800,0,900,0,900,200};
+ for(int i = 0; i < 5; ++i) {
+ addpoly(pset2, mp2[i], 4);
+ }
+ addpoly(pset2, mp21, 5);
+ addpoly(pset2, mp22, 5);
+ polygon_45_set_data<int> orr = pset1 + pset2;
+ polygon_45_set_data<int> inr = pset1 & pset2;
+ std::cout << area(orr)<<std::endl;;
+ std::cout << area(inr)<<std::endl;;
+ std::vector<polygon_45_with_holes_data<int> > polys;
+ assign(polys, orr);
+ std::cout << area(polys) << std::endl;
+ polygon_set_data<int> testbug;
+ testbug.insert(orr);
+ std::cout << area(testbug) << std::endl;
+ polygon_set_data<int> testbug2;
+ for(size_t i = 0; i < polys.size(); ++i) {
+ for(size_t j = 0; j < polys.size(); ++j) {
+ testbug2.clear();
+ testbug2.insert(polys[i]);
+ testbug2.insert(polys[j]);
+ std::cout << i << " " << j << std::endl;
+ std::cout << polys[i] << std::endl;
+ std::cout << polys[j] << std::endl;
+ if(area(testbug2) == 0.0) {
+ std::cout << area(testbug2) << std::endl;
+ std::cout << "Self touch 45 through general interface failed!\n";
+ return 1;
+ }
+ }
+ }
+ }
+
+ {
+ polygon_set_data<int> t_eq;
+ t_eq.insert(rectangle_data<int>(0, 0, 5, 10));
+ t_eq.insert(rectangle_data<int>(0, 5, 5, 10));
+ std::cout << t_eq <<std::endl;
+ polygon_set_data<int> t_eq2;
+ t_eq2 += rectangle_data<int>(0, 0, 5, 10);
+ std::cout << area(t_eq) <<std::endl;
+ std::cout << area(t_eq2) <<std::endl;
+ std::cout << t_eq <<std::endl;
+ std::cout << t_eq2 <<std::endl;
+ if(t_eq != t_eq2) {
+ std::cout << "equivalence failed" << std::endl;
+ return 1;
+ }
+ }
+
+ {
+ using namespace boost::polygon;
+ typedef point_data<int> Point;
+ typedef segment_data<int> Dls;
+ Point pt1(0, 0);
+ Point pt2(10, 10);
+ Point pt3(20, 20);
+ Point pt4(20, 0);
+ Dls dls1(pt1, pt2);
+ Dls dls2(pt1, pt3);
+ Dls dls3(pt1, pt4);
+ Dls dls4(pt2, pt1);
+ typedef std::vector<segment_data<int> > Dlss;
+ Dlss dlss, result;
+ dlss.push_back(dls1);
+ dlss.push_back(dls2);
+ dlss.push_back(dls3);
+ dlss.push_back(dls4);
+ rectangle_data<int> rect;
+ envelope_segments(rect, dlss.begin(), dlss.end());
+ assert_s(area(rect) == 400.0, "envelope");
+ intersect_segments(result, dlss.begin(), dlss.end());
+ dlss.swap(result);
+ for (Dlss::iterator itr = dlss.begin(); itr != dlss.end(); ++itr) {
+ std::cout << *itr << std::endl;
+ }
+ assert_s(dlss.size() == 5, "intersection");
+ Dls dls5(Point(0,5), Point(5,0));
+ dlss.push_back(dls5);
+ std::cout << std::endl;
+ result.clear();
+ intersect_segments(result, dlss.begin(), dlss.end());
+ dlss.swap(result);
+ for (Dlss::iterator itr = dlss.begin(); itr != dlss.end(); ++itr) {
+ std::cout << *itr << std::endl;
+ }
+ assert_s(dlss.size() == 11, "intersection2");
+ }
+
+ {
+ using namespace boost::polygon;
+ std::vector<std::pair<std::size_t, segment_data<int> > > segs;
+ segment_data<int> sarray[2];
+ sarray[0] = segment_data<int>(point_data<int>(0,0), point_data<int>(10,10));
+ sarray[1] = segment_data<int>(point_data<int>(10,0), point_data<int>(0,10));
+ intersect_segments(segs, sarray, sarray+2);
+ std::cout << segs.size() << std::endl;
+ assert_s(segs.size() == 4, "intersection3");
+ }
+
+
+ /*New polygon_formation tests*/
+ if(test_new_polygon_formation(0,NULL)){
+ std::cerr << "[test_new_polygon_formation] failed" << std::endl;
+ return 1;
+ }
+
+ if(test_new_polygon_formation_marginal_threshold(0,NULL)){
+ std::cerr << "[test_new_polygon_formation_marginal_threshold] failed"
+ << std::endl;
+ return 1;
+ }
+
+ std::cout << "ALL TESTS COMPLETE\n";
+ return 0;
+}
diff --git a/src/boost/libs/polygon/test/polygon_90_data_test.cpp b/src/boost/libs/polygon/test/polygon_90_data_test.cpp
new file mode 100644
index 000000000..2b61d41e7
--- /dev/null
+++ b/src/boost/libs/polygon/test/polygon_90_data_test.cpp
@@ -0,0 +1,52 @@
+// Boost.Polygon library polygon_90_data_test.cpp file
+
+// Copyright Andrii Sydorchuk 2015.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/polygon.hpp>
+#include <iostream>
+#include <vector>
+
+using namespace boost::polygon;
+
+void polygon_90_data_test()
+{
+ typedef polygon_90_data<int> polygon_type;
+ typedef polygon_traits_90<polygon_type>::point_type point_type;
+ typedef polygon_type::iterator_type iterator_type;
+
+ std::vector<point_type> data;
+ data.push_back(point_type(0, 0)); // 1
+ data.push_back(point_type(10, 0)); // 2
+ data.push_back(point_type(10, 10)); // 3
+ data.push_back(point_type(0, 10)); // 4
+
+ polygon_type polygon;
+ polygon.set(data.begin(), data.end());
+
+ std::cout << "Interesting: " << std::endl;
+ for (polygon_type::compact_iterator_type it = polygon.begin_compact(); it != polygon.end_compact(); ++it) {
+ std::cout << *it << " ";
+ }
+ std::cout << std::endl;
+
+ iterator_type it = polygon.begin();
+ for (int i = 0; i < 2; i++) {
+ it++;
+ }
+
+ iterator_type it_3rd = it;
+ it++;
+ BOOST_TEST(it != it_3rd);
+}
+
+int main()
+{
+ polygon_90_data_test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/polygon_interval_test.cpp b/src/boost/libs/polygon/test/polygon_interval_test.cpp
new file mode 100644
index 000000000..070d34f76
--- /dev/null
+++ b/src/boost/libs/polygon/test/polygon_interval_test.cpp
@@ -0,0 +1,271 @@
+// Boost.Polygon library polygon_interval_test.cpp file
+
+// Copyright Andrii Sydorchuk 2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/interval_concept.hpp>
+#include <boost/polygon/interval_data.hpp>
+#include <boost/polygon/interval_traits.hpp>
+
+using namespace boost::polygon;
+
+void interval_data_test()
+{
+ typedef interval_data<int> interval_type;
+ interval_type interval1(1, 2);
+ interval_type interval2;
+ interval2 = interval1;
+
+ BOOST_TEST_EQ(interval1.low(), 1);
+ BOOST_TEST_EQ(interval1.high(), 2);
+ BOOST_TEST_EQ(interval1.get(LOW), 1);
+ BOOST_TEST_EQ(interval1.get(HIGH), 2);
+ BOOST_TEST(interval1 == interval2);
+ BOOST_TEST(!(interval1 != interval2));
+ BOOST_TEST(!(interval1 < interval2));
+ BOOST_TEST(!(interval1 > interval2));
+ BOOST_TEST(interval1 <= interval2);
+ BOOST_TEST(interval1 >= interval2);
+
+ interval1.low(2);
+ interval1.high(1);
+ BOOST_TEST_EQ(interval1.low(), 2);
+ BOOST_TEST_EQ(interval1.high(), 1);
+ BOOST_TEST(!(interval1 == interval2));
+ BOOST_TEST(interval1 != interval2);
+
+ interval2.set(LOW, 2);
+ interval2.set(HIGH, 1);
+ BOOST_TEST(interval1 == interval2);
+}
+
+void interval_traits_test()
+{
+ typedef interval_data<int> interval_type;
+
+ interval_type interval = interval_mutable_traits<interval_type>::construct(1, 2);
+ BOOST_TEST_EQ(interval_traits<interval_type>::get(interval, LOW), 1);
+ BOOST_TEST_EQ(interval_traits<interval_type>::get(interval, HIGH), 2);
+
+ interval_mutable_traits<interval_type>::set(interval, LOW, 3);
+ interval_mutable_traits<interval_type>::set(interval, HIGH, 4);
+ BOOST_TEST_EQ(interval_traits<interval_type>::get(interval, LOW), 3);
+ BOOST_TEST_EQ(interval_traits<interval_type>::get(interval, HIGH), 4);
+}
+
+template <typename T>
+struct Interval {
+ T left;
+ T right;
+};
+
+namespace boost {
+namespace polygon {
+ template <typename T>
+ struct geometry_concept< Interval<T> > {
+ typedef interval_concept type;
+ };
+
+ template <typename T>
+ struct interval_traits< Interval<T> > {
+ typedef T coordinate_type;
+
+ static coordinate_type get(const Interval<T>& interval, direction_1d dir) {
+ return (dir == LOW) ? interval.left : interval.right;
+ }
+ };
+
+ template <typename T>
+ struct interval_mutable_traits< Interval<T> > {
+ typedef T coordinate_type;
+
+ static void set(Interval<T>& interval, direction_1d dir, T value) {
+ (dir == LOW) ? interval.left = value : interval.right = value;
+ }
+
+ static Interval<T> construct(coordinate_type left, coordinate_type right) {
+ Interval<T> interval;
+ interval.left = left;
+ interval.right = right;
+ return interval;
+ }
+ };
+} // polygon
+} // boost
+
+void interval_concept_test1()
+{
+ typedef Interval<int> interval_type;
+
+ interval_type interval1 = construct<interval_type>(2, 1);
+ BOOST_TEST_EQ(interval1.left, 1);
+ BOOST_TEST_EQ(interval1.right, 2);
+
+ set(interval1, LOW, 3);
+ set(interval1, HIGH, 4);
+ BOOST_TEST_EQ(get(interval1, LOW), 3);
+ BOOST_TEST_EQ(get(interval1, HIGH), 4);
+
+ interval_type interval2 = copy_construct<interval_type>(interval1);
+ BOOST_TEST(equivalence(interval1, interval2));
+
+ low(interval2, 1);
+ high(interval2, 2);
+ BOOST_TEST_EQ(low(interval2), 1);
+ BOOST_TEST_EQ(high(interval2), 2);
+
+ assign(interval1, interval2);
+ BOOST_TEST(equivalence(interval1, interval2));
+}
+
+void interval_concept_test2()
+{
+ typedef Interval<int> interval_type;
+
+ interval_type interval1 = construct<interval_type>(1, 3);
+ BOOST_TEST_EQ(center(interval1), 2);
+ BOOST_TEST_EQ(delta(interval1), 2);
+
+ flip(interval1, -1);
+ BOOST_TEST_EQ(low(interval1), -5);
+ BOOST_TEST_EQ(high(interval1), -3);
+
+ scale_up(interval1, 2);
+ BOOST_TEST_EQ(low(interval1), -10);
+ BOOST_TEST_EQ(high(interval1), -6);
+
+ scale_down(interval1, 2);
+ BOOST_TEST_EQ(low(interval1), -5);
+ BOOST_TEST_EQ(high(interval1), -3);
+
+ move(interval1, 5);
+ BOOST_TEST_EQ(low(interval1), 0);
+ BOOST_TEST_EQ(high(interval1), 2);
+
+ convolve(interval1, 1);
+ BOOST_TEST_EQ(low(interval1), 1);
+ BOOST_TEST_EQ(high(interval1), 3);
+
+ deconvolve(interval1, 2);
+ BOOST_TEST_EQ(low(interval1), -1);
+ BOOST_TEST_EQ(high(interval1), 1);
+
+ interval_type interval2 = construct<interval_type>(-1, 2);
+ convolve(interval1, interval2);
+ BOOST_TEST_EQ(low(interval1), -2);
+ BOOST_TEST_EQ(high(interval1), 3);
+
+ deconvolve(interval1, interval2);
+ BOOST_TEST_EQ(low(interval1), -1);
+ BOOST_TEST_EQ(high(interval1), 1);
+
+ reflected_convolve(interval1, interval2);
+ BOOST_TEST_EQ(low(interval1), -3);
+ BOOST_TEST_EQ(high(interval1), 2);
+
+ reflected_deconvolve(interval1, interval2);
+ BOOST_TEST_EQ(low(interval1), -1);
+ BOOST_TEST_EQ(high(interval1), 1);
+}
+
+void interval_concept_test3()
+{
+ typedef Interval<int> interval_type;
+
+ interval_type interval1 = construct<interval_type>(1, 3);
+ BOOST_TEST_EQ(euclidean_distance(interval1, -2), 3);
+ BOOST_TEST_EQ(euclidean_distance(interval1, 2), 0);
+ BOOST_TEST_EQ(euclidean_distance(interval1, 4), 1);
+
+ interval_type interval2 = construct<interval_type>(-1, 0);
+ BOOST_TEST_EQ(euclidean_distance(interval1, interval2), 1);
+ BOOST_TEST(!intersects(interval1, interval2));
+ BOOST_TEST(!boundaries_intersect(interval1, interval2));
+ BOOST_TEST(!intersect(interval2, interval1));
+ BOOST_TEST_EQ(low(interval2), -1);
+ BOOST_TEST_EQ(high(interval2), 0);
+
+ interval_type interval3 = construct<interval_type>(-1, 6);
+ BOOST_TEST_EQ(euclidean_distance(interval1, interval3), 0);
+ BOOST_TEST(intersects(interval1, interval3));
+ BOOST_TEST(!boundaries_intersect(interval1, interval3));
+ BOOST_TEST(intersect(interval3, interval1));
+ BOOST_TEST_EQ(low(interval3), 1);
+ BOOST_TEST_EQ(high(interval3), 3);
+
+ interval_type interval4 = construct<interval_type>(5, 6);
+ BOOST_TEST_EQ(euclidean_distance(interval1, interval4), 2);
+ BOOST_TEST(!intersects(interval1, interval4));
+ BOOST_TEST(!boundaries_intersect(interval1, interval4));
+ BOOST_TEST(!intersect(interval4, interval1));
+ BOOST_TEST_EQ(low(interval4), 5);
+ BOOST_TEST_EQ(high(interval4), 6);
+
+ interval_type interval5 = construct<interval_type>(3, 5);
+ BOOST_TEST_EQ(euclidean_distance(interval1, interval5), 0);
+ BOOST_TEST(!intersects(interval1, interval5, false));
+ BOOST_TEST(boundaries_intersect(interval1, interval5));
+ BOOST_TEST(intersect(interval5, interval1));
+ BOOST_TEST_EQ(low(interval5), 3);
+ BOOST_TEST_EQ(high(interval5), 3);
+}
+
+void interval_concept_test4()
+{
+ typedef Interval<int> interval_type;
+
+ interval_type interval1 = construct<interval_type>(1, 3);
+ interval_type interval2 = construct<interval_type>(3, 5);
+ BOOST_TEST(!abuts(interval1, interval2, LOW));
+ BOOST_TEST(abuts(interval1, interval2, HIGH));
+ BOOST_TEST(abuts(interval1, interval2));
+
+ bloat(interval1, 1);
+ BOOST_TEST_EQ(low(interval1), 0);
+ BOOST_TEST_EQ(high(interval1), 4);
+ BOOST_TEST(!abuts(interval1, interval2));
+
+ bloat(interval1, LOW, 1);
+ BOOST_TEST_EQ(low(interval1), -1);
+ BOOST_TEST_EQ(high(interval1), 4);
+
+ shrink(interval1, LOW, 1);
+ BOOST_TEST_EQ(low(interval1), 0);
+ BOOST_TEST_EQ(high(interval1), 4);
+
+ shrink(interval1, 1);
+ BOOST_TEST_EQ(low(interval1), 1);
+ BOOST_TEST_EQ(high(interval1), 3);
+
+ BOOST_TEST(encompass(interval1, 4));
+ BOOST_TEST_EQ(low(interval1), 1);
+ BOOST_TEST_EQ(high(interval1), 4);
+
+ BOOST_TEST(encompass(interval1, interval2));
+ BOOST_TEST_EQ(low(interval1), 1);
+ BOOST_TEST_EQ(high(interval1), 5);
+
+ interval1 = get_half(interval1, LOW);
+ BOOST_TEST_EQ(low(interval1), 1);
+ BOOST_TEST_EQ(high(interval1), 3);
+
+ BOOST_TEST(join_with(interval1, interval2));
+ BOOST_TEST_EQ(low(interval1), 1);
+ BOOST_TEST_EQ(high(interval1), 5);
+}
+
+int main()
+{
+ interval_data_test();
+ interval_traits_test();
+ interval_concept_test1();
+ interval_concept_test2();
+ interval_concept_test3();
+ interval_concept_test4();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/polygon_point_test.cpp b/src/boost/libs/polygon/test/polygon_point_test.cpp
new file mode 100644
index 000000000..ce57f5b11
--- /dev/null
+++ b/src/boost/libs/polygon/test/polygon_point_test.cpp
@@ -0,0 +1,205 @@
+// Boost.Polygon library polygon_point_test.cpp file
+
+// Copyright Andrii Sydorchuk 2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/point_concept.hpp>
+#include <boost/polygon/point_data.hpp>
+#include <boost/polygon/point_traits.hpp>
+
+using namespace boost::polygon;
+
+void point_data_test()
+{
+ typedef point_data<int> point_type;
+
+ point_type point1(1, 2);
+ point_type point2;
+ point2 = point1;
+ BOOST_TEST_EQ(point1.x(), 1);
+ BOOST_TEST_EQ(point1.y(), 2);
+ BOOST_TEST_EQ(point2.x(), 1);
+ BOOST_TEST_EQ(point2.y(), 2);
+ BOOST_TEST(point1 == point2);
+ BOOST_TEST(!(point1 != point2));
+ BOOST_TEST(!(point1 < point2));
+ BOOST_TEST(!(point1 > point2));
+ BOOST_TEST(point1 <= point2);
+ BOOST_TEST(point1 >= point2);
+
+ point2.x(2);
+ point2.y(1);
+ BOOST_TEST_EQ(point2.x(), 2);
+ BOOST_TEST_EQ(point2.y(), 1);
+ BOOST_TEST(!(point1 == point2));
+ BOOST_TEST(point1 != point2);
+ BOOST_TEST(point1 < point2);
+ BOOST_TEST(!(point1 > point2));
+ BOOST_TEST(point1 <= point2);
+ BOOST_TEST(!(point1 >= point2));
+
+ point2.set(HORIZONTAL, 1);
+ point2.set(VERTICAL, 2);
+ BOOST_TEST(point1 == point2);
+}
+
+void point_traits_test()
+{
+ typedef point_data<int> point_type;
+
+ point_type point = point_mutable_traits<point_type>::construct(1, 2);
+ BOOST_TEST_EQ(point_traits<point_type>::get(point, HORIZONTAL), 1);
+ BOOST_TEST_EQ(point_traits<point_type>::get(point, VERTICAL), 2);
+
+ point_mutable_traits<point_type>::set(point, HORIZONTAL, 3);
+ point_mutable_traits<point_type>::set(point, VERTICAL, 4);
+ BOOST_TEST_EQ(point_traits<point_type>::get(point, HORIZONTAL), 3);
+ BOOST_TEST_EQ(point_traits<point_type>::get(point, VERTICAL), 4);
+}
+
+template <typename T>
+struct Point {
+ T x;
+ T y;
+};
+
+namespace boost {
+namespace polygon {
+ template <typename T>
+ struct geometry_concept< Point<T> > {
+ typedef point_concept type;
+ };
+
+ template <typename T>
+ struct point_traits< Point<T> > {
+ typedef T coordinate_type;
+
+ static coordinate_type get(const Point<T>& point, orientation_2d orient) {
+ return (orient == HORIZONTAL) ? point.x : point.y;
+ }
+ };
+
+ template <typename T>
+ struct point_mutable_traits< Point<T> > {
+ typedef T coordinate_type;
+
+ static void set(Point<T>& point, orientation_2d orient, T value) {
+ (orient == HORIZONTAL) ? point.x = value : point.y = value;
+ }
+
+ static Point<T> construct(coordinate_type x, coordinate_type y) {
+ Point<T> point;
+ point.x = x;
+ point.y = y;
+ return point;
+ }
+ };
+} // polygon
+} // boost
+
+void point_concept_test1()
+{
+ typedef Point<int> point_type;
+
+ point_type point1 = construct<point_type>(1, 2);
+ BOOST_TEST_EQ(point1.x, 1);
+ BOOST_TEST_EQ(point1.y, 2);
+
+ set(point1, HORIZONTAL, 3);
+ set(point1, VERTICAL, 4);
+ BOOST_TEST_EQ(get(point1, HORIZONTAL), 3);
+ BOOST_TEST_EQ(get(point1, VERTICAL), 4);
+
+ point_type point2;
+ assign(point2, point1);
+ BOOST_TEST(equivalence(point1, point2));
+
+ x(point2, 1);
+ y(point2, 2);
+ BOOST_TEST_EQ(x(point2), 1);
+ BOOST_TEST_EQ(y(point2), 2);
+}
+
+void point_concept_test2()
+{
+ typedef Point<int> point_type;
+
+ point_type point1 = construct<point_type>(1, 2);
+ point_type point2 = construct<point_type>(5, 5);
+ BOOST_TEST_EQ(euclidean_distance(point1, point2, HORIZONTAL), 4);
+ BOOST_TEST_EQ(euclidean_distance(point1, point2, VERTICAL), 3);
+ BOOST_TEST_EQ(manhattan_distance(point1, point2), 7);
+ BOOST_TEST_EQ(euclidean_distance(point1, point2), 5.0);
+}
+
+void point_concept_test3()
+{
+ typedef Point<int> point_type;
+
+ point_type point = construct<point_type>(1, 2);
+ point_type shift = construct<point_type>(4, 3);
+ convolve(point, shift);
+ BOOST_TEST_EQ(x(point), 5);
+ BOOST_TEST_EQ(y(point), 5);
+
+ deconvolve(point, shift);
+ BOOST_TEST_EQ(x(point), 1);
+ BOOST_TEST_EQ(y(point), 2);
+
+ scale_up(point, 5);
+ BOOST_TEST_EQ(x(point), 5);
+ BOOST_TEST_EQ(y(point), 10);
+
+ scale_down(point, 5);
+ BOOST_TEST_EQ(x(point), 1);
+ BOOST_TEST_EQ(y(point), 2);
+
+ move(point, HORIZONTAL, 2);
+ move(point, VERTICAL, 3);
+ BOOST_TEST_EQ(x(point), 3);
+ BOOST_TEST_EQ(y(point), 5);
+}
+
+template<typename T>
+struct Transformer {
+ void scale(T& x, T& y) const {
+ x *= 2;
+ y *= 2;
+ }
+
+ void transform(T& x, T& y) const {
+ T tmp = x;
+ x = y;
+ y = tmp;
+ }
+};
+
+void point_concept_test4()
+{
+ typedef Point<int> point_type;
+
+ point_type point = construct<point_type>(1, 2);
+ scale(point, Transformer<int>());
+ BOOST_TEST_EQ(x(point), 2);
+ BOOST_TEST_EQ(y(point), 4);
+
+ transform(point, Transformer<int>());
+ BOOST_TEST_EQ(x(point), 4);
+ BOOST_TEST_EQ(y(point), 2);
+}
+
+int main()
+{
+ point_data_test();
+ point_traits_test();
+ point_concept_test1();
+ point_concept_test2();
+ point_concept_test3();
+ point_concept_test4();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/polygon_rectangle_formation_test.cpp b/src/boost/libs/polygon/test/polygon_rectangle_formation_test.cpp
new file mode 100644
index 000000000..82640640b
--- /dev/null
+++ b/src/boost/libs/polygon/test/polygon_rectangle_formation_test.cpp
@@ -0,0 +1,44 @@
+// Boost.Polygon library polygon_rectangle_formation_test.cpp file
+
+// Copyright Andrii Sydorchuk 2015.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/polygon.hpp>
+
+using namespace boost::polygon;
+
+void rectangle_formation_test1()
+{
+ typedef polygon_90_with_holes_data<int> polygon_type;
+ typedef polygon_traits<polygon_type>::point_type point_type;
+
+ polygon_type poly;
+ point_type points[] = {
+ boost::polygon::construct<point_type>(0, 0),
+ boost::polygon::construct<point_type>(0, 10),
+ boost::polygon::construct<point_type>(10, 10),
+ boost::polygon::construct<point_type>(10, 0),
+ };
+ boost::polygon::set_points(poly, points, points + 4);
+
+ std::vector< rectangle_data<int> > rects;
+ boost::polygon::get_rectangles(rects, poly);
+
+ BOOST_TEST_EQ(1, rects.size());
+ const rectangle_data<int>& rect = rects[0];
+ BOOST_TEST_EQ(0, rect.get(WEST));
+ BOOST_TEST_EQ(10, rect.get(EAST));
+ BOOST_TEST_EQ(10, rect.get(NORTH));
+ BOOST_TEST_EQ(0, rect.get(SOUTH));
+}
+
+int main()
+{
+ rectangle_formation_test1();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/polygon_rectangle_test.cpp b/src/boost/libs/polygon/test/polygon_rectangle_test.cpp
new file mode 100644
index 000000000..66a586df0
--- /dev/null
+++ b/src/boost/libs/polygon/test/polygon_rectangle_test.cpp
@@ -0,0 +1,45 @@
+// Boost.Polygon library polygon_rectangle_test.cpp file
+
+// Copyright Andrii Sydorchuk 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/rectangle_concept.hpp>
+#include <boost/polygon/rectangle_data.hpp>
+#include <boost/polygon/rectangle_traits.hpp>
+
+using namespace boost::polygon;
+
+template <typename interval_type>
+void CHECK_INTERVAL_EQUAL(const interval_type& i1, const interval_type& i2) {
+ BOOST_TEST_EQ(get(i1, LOW), get(i2, LOW));
+ BOOST_TEST_EQ(get(i1, HIGH), get(i2, HIGH));
+}
+
+template <typename rectangle_type>
+void CHECK_RECT_EQUAL(const rectangle_type& r1, const rectangle_type& r2) {
+ CHECK_INTERVAL_EQUAL(horizontal(r1), horizontal(r2));
+ CHECK_INTERVAL_EQUAL(vertical(r1), vertical(r2));
+}
+
+void rectangle_concept_test1()
+{
+ typedef rectangle_data<int> rectangle_type;
+
+ rectangle_type rectangle1 = construct<rectangle_type>(-1, -1, 1, 1);
+ scale_up(rectangle1, 2);
+ CHECK_RECT_EQUAL(construct<rectangle_type>(-2, -2, 2, 2), rectangle1);
+
+ scale_down(rectangle1, 2);
+ CHECK_RECT_EQUAL(construct<rectangle_type>(-1, -1, 1, 1), rectangle1);
+}
+
+int main()
+{
+ rectangle_concept_test1();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/polygon_segment_test.cpp b/src/boost/libs/polygon/test/polygon_segment_test.cpp
new file mode 100644
index 000000000..a9042f5e8
--- /dev/null
+++ b/src/boost/libs/polygon/test/polygon_segment_test.cpp
@@ -0,0 +1,485 @@
+// Boost.Polygon library polygon_segment_test.cpp file
+
+// Copyright Andrii Sydorchuk 2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/segment_concept.hpp>
+#include <boost/polygon/segment_data.hpp>
+#include <boost/polygon/segment_traits.hpp>
+
+using namespace boost::polygon;
+
+void segment_data_test()
+{
+ typedef point_data<int> point_type;
+ typedef segment_data<int> segment_type;
+ point_type point1(1, 2);
+ point_type point2(3, 4);
+ segment_type segment1(point1, point2);
+ segment_type segment2;
+ segment2 = segment1;
+
+ BOOST_TEST(segment1.low() == point1);
+ BOOST_TEST(segment1.high() == point2);
+ BOOST_TEST(segment1.get(LOW) == point1);
+ BOOST_TEST(segment1.get(HIGH) == point2);
+ BOOST_TEST(segment1 == segment2);
+ BOOST_TEST(!(segment1 != segment2));
+ BOOST_TEST(!(segment1 < segment2));
+ BOOST_TEST(!(segment1 > segment1));
+ BOOST_TEST(segment1 <= segment2);
+ BOOST_TEST(segment1 >= segment2);
+
+ segment1.low(point2);
+ segment1.high(point1);
+ BOOST_TEST(segment1.low() == point2);
+ BOOST_TEST(segment1.high() == point1);
+ BOOST_TEST(!(segment1 == segment2));
+ BOOST_TEST(segment1 != segment2);
+
+ segment2.set(LOW, point2);
+ segment2.set(HIGH, point1);
+ BOOST_TEST(segment1 == segment2);
+}
+
+void segment_traits_test()
+{
+ typedef point_data<int> point_type;
+ typedef segment_data<int> segment_type;
+
+ point_type point1(1, 2);
+ point_type point2(3, 4);
+ segment_type segment =
+ segment_mutable_traits<segment_type>::construct(point1, point2);
+
+ BOOST_TEST(segment_traits<segment_type>::get(segment, LOW) == point1);
+ BOOST_TEST(segment_traits<segment_type>::get(segment, HIGH) == point2);
+
+ segment_mutable_traits<segment_type>::set(segment, LOW, point2);
+ segment_mutable_traits<segment_type>::set(segment, HIGH, point1);
+ BOOST_TEST(segment_traits<segment_type>::get(segment, LOW) == point2);
+ BOOST_TEST(segment_traits<segment_type>::get(segment, HIGH) == point1);
+}
+
+template <typename T>
+struct Segment {
+ typedef T coordinate_type;
+ typedef point_data<int> point_type;
+ point_type p0;
+ point_type p1;
+};
+
+namespace boost {
+namespace polygon {
+ template <typename T>
+ struct geometry_concept< Segment<T> > {
+ typedef segment_concept type;
+ };
+
+ template <typename T>
+ struct segment_traits< Segment<T> > {
+ typedef T coordinate_type;
+ typedef point_data<int> point_type;
+
+ static point_type get(const Segment<T>& segment, direction_1d dir) {
+ return dir.to_int() ? segment.p1 : segment.p0;
+ }
+ };
+
+ template <typename T>
+ struct segment_mutable_traits< Segment<T> > {
+ typedef T coordinate_type;
+ typedef point_data<int> point_type;
+
+ static void set(
+ Segment<T>& segment, direction_1d dir, const point_type& point) {
+ dir.to_int() ? segment.p1 = point : segment.p0 = point;;
+ }
+
+ static Segment<T> construct(
+ const point_type& point1, const point_type& point2) {
+ Segment<T> segment;
+ segment.p0 = point1;
+ segment.p1 = point2;
+ return segment;
+ }
+ };
+}
+}
+
+void segment_concept_test1()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ point_type point1(1, 2);
+ point_type point2(3, 4);
+ point_type point3(2, 3);
+ segment_type segment1 = construct<segment_type>(point1, point2);
+ BOOST_TEST(segment1.p0 == point1);
+ BOOST_TEST(segment1.p1 == point2);
+ BOOST_TEST(get(segment1, LOW) == point1);
+ BOOST_TEST(low(segment1) == point1);
+ BOOST_TEST(get(segment1, HIGH) == point2);
+ BOOST_TEST(high(segment1) == point2);
+ BOOST_TEST(center(segment1) == point3);
+
+ set(segment1, LOW, point2);
+ set(segment1, HIGH, point1);
+ BOOST_TEST(segment1.p0 == point2);
+ BOOST_TEST(segment1.p1 == point1);
+ BOOST_TEST(get(segment1, LOW) == point2);
+ BOOST_TEST(get(segment1, HIGH) == point1);
+ low(segment1, point1);
+ high(segment1, point2);
+ BOOST_TEST(segment1.p0 == point1);
+ BOOST_TEST(segment1.p1 == point2);
+
+ segment_data<int> segment2 = copy_construct< segment_data<int> >(segment1);
+ BOOST_TEST(segment1.p0 == segment2.low());
+ BOOST_TEST(segment1.p1 == segment2.high());
+ BOOST_TEST(equivalence(segment1, segment2));
+
+ segment_data<int> segment3 = construct< segment_data<int> >(point2, point1);
+ assign(segment1, segment3);
+ BOOST_TEST(segment1.p0 == point2);
+ BOOST_TEST(segment1.p1 == point1);
+ BOOST_TEST(!equivalence(segment1, segment2));
+}
+
+void segment_concept_test2()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ point_type point1(1, 2);
+ point_type point2(2, 4);
+ point_type point3(0, 0);
+ point_type point4(5, 10);
+ point_type point5(1, 3);
+ point_type point6(2, 3);
+ point_type point7(100, 201);
+ point_type point8(100, 200);
+ point_type point9(100, 199);
+ segment_type segment1 = construct<segment_type>(point1, point2);
+ segment_type segment2 = construct<segment_type>(point2, point1);
+ segment_type segment3 = construct<segment_type>(point1, point5);
+
+ BOOST_TEST(orientation(segment1, point1) == 0);
+ BOOST_TEST(orientation(segment1, point2) == 0);
+ BOOST_TEST(orientation(segment1, point3) == 0);
+ BOOST_TEST(orientation(segment1, point4) == 0);
+ BOOST_TEST(orientation(segment1, point5) == 1);
+ BOOST_TEST(orientation(segment2, point5) == -1);
+ BOOST_TEST(orientation(segment1, point6) == -1);
+ BOOST_TEST(orientation(segment2, point6) == 1);
+ BOOST_TEST(orientation(segment1, point7) == 1);
+ BOOST_TEST(orientation(segment2, point7) == -1);
+ BOOST_TEST(orientation(segment1, point8) == 0);
+ BOOST_TEST(orientation(segment1, point9) == -1);
+ BOOST_TEST(orientation(segment2, point9) == 1);
+ BOOST_TEST(orientation(segment3, point6) == -1);
+ BOOST_TEST(orientation(segment3, point3) == 1);
+}
+
+void segment_concept_test3()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ segment_type segment1 = construct<segment_type>(
+ point_type(0, 0), point_type(1, 2));
+ segment_type segment2 = construct<segment_type>(
+ point_type(0, 0), point_type(2, 4));
+ segment_type segment3 = construct<segment_type>(
+ point_type(0, 0), point_type(2, 3));
+ segment_type segment4 = construct<segment_type>(
+ point_type(0, 0), point_type(2, 5));
+ segment_type segment5 = construct<segment_type>(
+ point_type(0, 2), point_type(2, 0));
+
+ BOOST_TEST(orientation(segment1, segment2) == 0);
+ BOOST_TEST(orientation(segment1, segment3) == -1);
+ BOOST_TEST(orientation(segment3, segment1) == 1);
+ BOOST_TEST(orientation(segment1, segment4) == 1);
+ BOOST_TEST(orientation(segment4, segment1) == -1);
+ BOOST_TEST(orientation(segment1, segment5) == -1);
+ BOOST_TEST(orientation(segment5, segment1) == 1);
+}
+
+void segment_concept_test4()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ point_type point1(1, 2);
+ point_type point2(3, 6);
+ point_type point3(2, 4);
+ point_type point4(4, 8);
+ point_type point5(0, 0);
+ segment_type segment = construct<segment_type>(point1, point2);
+
+ BOOST_TEST(contains(segment, point1, true));
+ BOOST_TEST(contains(segment, point2, true));
+ BOOST_TEST(!contains(segment, point1, false));
+ BOOST_TEST(!contains(segment, point2, false));
+ BOOST_TEST(contains(segment, point3, false));
+ BOOST_TEST(!contains(segment, point4, true));
+ BOOST_TEST(!contains(segment, point5, true));
+}
+
+void segment_concept_test5()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ point_type point1(0, 0);
+ point_type point2(10, 0);
+ point_type point3(5, 0);
+ point_type point4(-1, 0);
+ point_type point5(11, 0);
+ segment_type segment = construct<segment_type>(point1, point2);
+
+ BOOST_TEST(contains(segment, point1, true));
+ BOOST_TEST(contains(segment, point2, true));
+ BOOST_TEST(!contains(segment, point1, false));
+ BOOST_TEST(!contains(segment, point2, false));
+ BOOST_TEST(contains(segment, point3, false));
+ BOOST_TEST(!contains(segment, point4, true));
+ BOOST_TEST(!contains(segment, point5, true));
+}
+
+void segment_concept_test6()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ point_type point1(0, 0);
+ point_type point2(1, 2);
+ point_type point3(2, 4);
+ point_type point4(3, 6);
+ point_type point5(4, 8);
+ point_type point6(5, 10);
+ segment_type segment1 = construct<segment_type>(point2, point5);
+ segment_type segment2 = construct<segment_type>(point3, point4);
+ segment_type segment3 = construct<segment_type>(point1, point3);
+ segment_type segment4 = construct<segment_type>(point4, point6);
+
+ BOOST_TEST(contains(segment1, segment2, false));
+ BOOST_TEST(!contains(segment2, segment1, true));
+ BOOST_TEST(!contains(segment1, segment3, true));
+ BOOST_TEST(!contains(segment1, segment4, true));
+ BOOST_TEST(contains(segment1, segment1, true));
+ BOOST_TEST(!contains(segment1, segment1, false));
+}
+
+template<typename T>
+struct Transformer {
+ void scale(T& x, T& y) const {
+ x *= 2;
+ y *= 2;
+ }
+
+ void transform(T& x, T& y) const {
+ T tmp = x;
+ x = y;
+ y = tmp;
+ }
+};
+
+void segment_concept_test7()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ point_type point1(1, 2);
+ point_type point2(4, 6);
+ segment_type segment1 = construct<segment_type>(point1, point2);
+
+ scale_up(segment1, 3);
+ BOOST_TEST(low(segment1) == point_type(3, 6));
+ BOOST_TEST(high(segment1) == point_type(12, 18));
+
+ scale_down(segment1, 3);
+ BOOST_TEST(low(segment1) == point1);
+ BOOST_TEST(high(segment1) == point2);
+ BOOST_TEST(length(segment1) == 5);
+
+ move(segment1, HORIZONTAL, 1);
+ move(segment1, VERTICAL, 2);
+ BOOST_TEST(low(segment1) == point_type(2, 4));
+ BOOST_TEST(high(segment1) == point_type(5, 8));
+ BOOST_TEST(length(segment1) == 5);
+
+ convolve(segment1, point_type(1, 2));
+ BOOST_TEST(low(segment1) == point_type(3, 6));
+ BOOST_TEST(high(segment1) == point_type(6, 10));
+
+ deconvolve(segment1, point_type(2, 4));
+ BOOST_TEST(low(segment1) == point1);
+ BOOST_TEST(high(segment1) == point2);
+
+ scale(segment1, Transformer<int>());
+ BOOST_TEST(low(segment1) == point_type(2, 4));
+ BOOST_TEST(high(segment1) == point_type(8, 12));
+ transform(segment1, Transformer<int>());
+ BOOST_TEST(low(segment1) == point_type(4, 2));
+ BOOST_TEST(high(segment1) == point_type(12, 8));
+}
+
+void segment_concept_test8()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ segment_type segment1 = construct<segment_type>(
+ point_type(0, 0), point_type(1, 2));
+ segment_type segment2 = construct<segment_type>(
+ point_type(1, 2), point_type(2, 4));
+ segment_type segment3 = construct<segment_type>(
+ point_type(2, 4), point_type(0, 4));
+ segment_type segment4 = construct<segment_type>(
+ point_type(0, 4), point_type(0, 0));
+
+ BOOST_TEST(abuts(segment1, segment2, HIGH));
+ BOOST_TEST(abuts(segment2, segment3, HIGH));
+ BOOST_TEST(abuts(segment3, segment4, HIGH));
+ BOOST_TEST(abuts(segment4, segment1, HIGH));
+
+ BOOST_TEST(!abuts(segment1, segment2, LOW));
+ BOOST_TEST(!abuts(segment2, segment3, LOW));
+ BOOST_TEST(!abuts(segment3, segment4, LOW));
+ BOOST_TEST(!abuts(segment4, segment1, LOW));
+
+ BOOST_TEST(abuts(segment2, segment1));
+ BOOST_TEST(abuts(segment3, segment2));
+ BOOST_TEST(abuts(segment4, segment3));
+ BOOST_TEST(abuts(segment1, segment4));
+
+ BOOST_TEST(!abuts(segment1, segment3));
+ BOOST_TEST(!abuts(segment2, segment4));
+}
+
+void segment_concept_test9()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ segment_type segment1 = construct<segment_type>(
+ point_type(0, 0), point_type(2, 2));
+ segment_type segment2 = construct<segment_type>(
+ point_type(1, 1), point_type(3, 3));
+ segment_type segment3 = construct<segment_type>(
+ point_type(2, 2), point_type(-1, -1));
+ segment_type segment4 = construct<segment_type>(
+ point_type(1, 3), point_type(3, 1));
+ segment_type segment5 = construct<segment_type>(
+ point_type(2, 2), point_type(1, 3));
+
+ BOOST_TEST(intersects(segment1, segment2, false));
+ BOOST_TEST(intersects(segment1, segment2, true));
+ BOOST_TEST(intersects(segment1, segment3, false));
+ BOOST_TEST(intersects(segment1, segment3, true));
+ BOOST_TEST(intersects(segment2, segment3, false));
+ BOOST_TEST(intersects(segment2, segment3, true));
+ BOOST_TEST(intersects(segment4, segment3, false));
+ BOOST_TEST(intersects(segment4, segment3, true));
+ BOOST_TEST(intersects(segment4, segment2, false));
+ BOOST_TEST(intersects(segment4, segment2, true));
+ BOOST_TEST(!intersects(segment3, segment5, false));
+ BOOST_TEST(intersects(segment3, segment5, true));
+}
+
+void segment_concept_test10()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ segment_type segment1 = construct<segment_type>(
+ point_type(0, 0), point_type(0, 2));
+ segment_type segment2 = construct<segment_type>(
+ point_type(0, 1), point_type(0, 3));
+ segment_type segment3 = construct<segment_type>(
+ point_type(0, 1), point_type(0, 2));
+ segment_type segment4 = construct<segment_type>(
+ point_type(0, 2), point_type(0, 3));
+ segment_type segment5 = construct<segment_type>(
+ point_type(0, 2), point_type(2, 2));
+ segment_type segment6 = construct<segment_type>(
+ point_type(0, 1), point_type(1, 1));
+
+ BOOST_TEST(intersects(segment1, segment1, false));
+ BOOST_TEST(intersects(segment1, segment1, true));
+ BOOST_TEST(intersects(segment1, segment2, false));
+ BOOST_TEST(intersects(segment1, segment2, true));
+ BOOST_TEST(intersects(segment1, segment3, false));
+ BOOST_TEST(intersects(segment1, segment3, true));
+ BOOST_TEST(intersects(segment2, segment3, false));
+ BOOST_TEST(intersects(segment2, segment3, true));
+ BOOST_TEST(!intersects(segment1, segment4, false));
+ BOOST_TEST(intersects(segment1, segment4, true));
+ BOOST_TEST(!intersects(segment1, segment5, false));
+ BOOST_TEST(intersects(segment1, segment5, true));
+ BOOST_TEST(intersects(segment1, segment6, false));
+ BOOST_TEST(intersects(segment1, segment6, true));
+}
+
+void segment_concept_test11()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ point_type point1(1, 2);
+ point_type point2(7, 10);
+ segment_type segment1 = construct<segment_type>(point1, point2);
+
+ BOOST_TEST(euclidean_distance(segment1, point1) == 0.0);
+ BOOST_TEST(euclidean_distance(segment1, point2) == 0.0);
+ BOOST_TEST(euclidean_distance(segment1, point_type(10, 14)) == 5.0);
+ BOOST_TEST(euclidean_distance(segment1, point_type(-3, -1)) == 5.0);
+ BOOST_TEST(euclidean_distance(segment1, point_type(0, 9)) == 5.0);
+ BOOST_TEST(euclidean_distance(segment1, point_type(8, 3)) == 5.0);
+}
+
+void segment_concept_test12()
+{
+ typedef point_data<int> point_type;
+ typedef Segment<int> segment_type;
+
+ segment_type segment1 = construct<segment_type>(
+ point_type(0, 0), point_type(3, 4));
+ segment_type segment2 = construct<segment_type>(
+ point_type(2, 0), point_type(0, 2));
+ segment_type segment3 = construct<segment_type>(
+ point_type(1, -7), point_type(10, 5));
+ segment_type segment4 = construct<segment_type>(
+ point_type(7, 7), point_type(10, 11));
+
+ BOOST_TEST(euclidean_distance(segment1, segment2) == 0.0);
+ BOOST_TEST(euclidean_distance(segment1, segment3) == 5.0);
+ BOOST_TEST(euclidean_distance(segment1, segment4) == 5.0);
+}
+
+int main()
+{
+ segment_data_test();
+ segment_traits_test();
+ segment_concept_test1();
+ segment_concept_test2();
+ segment_concept_test3();
+ segment_concept_test4();
+ segment_concept_test5();
+ segment_concept_test6();
+ segment_concept_test7();
+ segment_concept_test8();
+ segment_concept_test9();
+ segment_concept_test10();
+ segment_concept_test11();
+ segment_concept_test12();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/polygon_set_data_test.cpp b/src/boost/libs/polygon/test/polygon_set_data_test.cpp
new file mode 100644
index 000000000..df4fa4ac4
--- /dev/null
+++ b/src/boost/libs/polygon/test/polygon_set_data_test.cpp
@@ -0,0 +1,114 @@
+// Boost.Polygon library polygon_set_data_test.cpp file
+
+// Copyright Andrii Sydorchuk 2015.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/polygon.hpp>
+#include <vector>
+
+using namespace boost::polygon;
+using namespace boost::polygon::operators;
+
+void polygon_set_data_test1()
+{
+ typedef point_data<int> point_type;
+ typedef polygon_with_holes_data<int> polygon_with_holes_type;
+ typedef polygon_set_data<int> polygon_set_type;
+
+ polygon_set_type pset;
+ std::vector<point_type> outbox;
+ outbox.push_back(point_type(0, 0));
+ outbox.push_back(point_type(100, 0));
+ outbox.push_back(point_type(100, 100));
+ outbox.push_back(point_type(0, 100));
+ pset.insert_vertex_sequence(outbox.begin(), outbox.end(), COUNTERCLOCKWISE, false);
+ std::vector<point_type> inbox;
+ inbox.push_back(point_type(20, 20));
+ inbox.push_back(point_type(80, 20));
+ inbox.push_back(point_type(80, 80));
+ inbox.push_back(point_type(20, 80));
+ pset.insert_vertex_sequence(inbox.begin(), inbox.end(), COUNTERCLOCKWISE, true);
+
+ BOOST_TEST(!pset.empty());
+ BOOST_TEST(!pset.sorted());
+ BOOST_TEST(pset.dirty());
+ BOOST_TEST_EQ(8, pset.size());
+
+ std::vector<polygon_with_holes_type> vpoly;
+ pset.get(vpoly);
+ BOOST_TEST_EQ(1, vpoly.size());
+
+ polygon_with_holes_type poly = vpoly[0];
+ BOOST_TEST_EQ(5, poly.size());
+ BOOST_TEST_EQ(1, poly.size_holes());
+}
+
+void polygon_set_data_test2()
+{
+ typedef point_data<int> point_type;
+ typedef polygon_data<int> polygon_type;
+ typedef polygon_set_data<int> polygon_set_type;
+
+ std::vector<point_type> data;
+ data.push_back(point_type(2,0));
+ data.push_back(point_type(4,0));
+ data.push_back(point_type(4,3));
+ data.push_back(point_type(0,3));
+ data.push_back(point_type(0,0));
+ data.push_back(point_type(2,0));
+ data.push_back(point_type(2,1));
+ data.push_back(point_type(1,1));
+ data.push_back(point_type(1,2));
+ data.push_back(point_type(3,2));
+ data.push_back(point_type(3,1));
+ data.push_back(point_type(2,1));
+ data.push_back(point_type(2,0));
+
+ polygon_type polygon;
+ set_points(polygon, data.begin(), data.end());
+
+ polygon_set_type pset;
+ pset.insert(polygon);
+
+ std::vector<polygon_type> traps;
+ get_trapezoids(traps, pset, HORIZONTAL);
+
+ BOOST_TEST_EQ(4, traps.size());
+}
+
+void polygon_set_data_test3()
+{
+ typedef point_data<int> point_type;
+ typedef polygon_data<int> polygon_type;
+ typedef polygon_set_data<int> polygon_set_type;
+
+ std::vector<point_type> data;
+ data.push_back(point_type(0,0));
+ data.push_back(point_type(6,0));
+ data.push_back(point_type(6,4));
+ data.push_back(point_type(4,6));
+ data.push_back(point_type(0,6));
+ data.push_back(point_type(0,0));
+ data.push_back(point_type(4,4));
+ data.push_back(point_type(5,4));
+
+ polygon_type polygon(data.begin(), data.end());
+ polygon_set_type pset;
+ pset += polygon;
+
+ BOOST_TEST_EQ(32.0, area(polygon));
+ BOOST_TEST_EQ(32.0, area(polygon));
+}
+
+int main()
+{
+ polygon_set_data_test1();
+ polygon_set_data_test2();
+ polygon_set_data_test3();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/voronoi_builder_test.cpp b/src/boost/libs/polygon/test/voronoi_builder_test.cpp
new file mode 100644
index 000000000..192c21713
--- /dev/null
+++ b/src/boost/libs/polygon/test/voronoi_builder_test.cpp
@@ -0,0 +1,681 @@
+// Boost.Polygon library voronoi_builder_test.cpp file
+
+// Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include "voronoi_test_helper.hpp"
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/polygon.hpp>
+#include <boost/polygon/voronoi.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <limits>
+#include <list>
+#include <vector>
+#include <ctime>
+
+using boost::polygon::voronoi_builder;
+using boost::polygon::voronoi_diagram;
+
+typedef voronoi_diagram<double> vd_type;
+typedef vd_type::coordinate_type coordinate_type;
+typedef vd_type::edge_type voronoi_edge_type;
+typedef vd_type::const_cell_iterator const_cell_iterator;
+typedef vd_type::const_vertex_iterator const_vertex_iterator;
+
+#define CHECK_OUTPUT_SIZE(output, cells, vertices, edges) \
+ BOOST_TEST_EQ(output.num_cells(), (std::size_t)cells); \
+ BOOST_TEST_EQ(output.num_vertices(), (std::size_t)vertices); \
+ BOOST_TEST_EQ(output.num_edges(), (std::size_t)edges)
+
+#define VERIFY_OUTPUT(output) \
+ BOOST_TEST(voronoi_test_helper::verify_output(output, \
+ voronoi_test_helper::CELL_CONVEXITY)); \
+ BOOST_TEST(voronoi_test_helper::verify_output(output, \
+ voronoi_test_helper::INCIDENT_EDGES_CCW_ORDER)); \
+ BOOST_TEST(voronoi_test_helper::verify_output(output, \
+ voronoi_test_helper::NO_HALF_EDGE_INTERSECTIONS))
+
+#define VERIFY_NO_HALF_EDGE_INTERSECTIONS(output) \
+ BOOST_TEST(voronoi_test_helper::verify_output(output, \
+ voronoi_test_helper::NO_HALF_EDGE_INTERSECTIONS))
+
+// Sites: (0, 0).
+void single_site_test()
+{
+ std::vector< point_data<int> > points;
+ points.push_back(point_data<int>(0, 0));
+ vd_type test_output;
+ construct_voronoi(points.begin(), points.end(), &test_output);
+ VERIFY_OUTPUT(test_output);
+
+ BOOST_TEST(test_output.cells().size() == 1);
+ CHECK_OUTPUT_SIZE(test_output, 1, 0, 0);
+
+ const_cell_iterator it = test_output.cells().begin();
+ BOOST_TEST(it->incident_edge() == NULL);
+}
+
+// Sites: (0, 0), (0, 1).
+void collinear_sites_test1()
+{
+ std::vector< point_data<int> > points;
+ points.push_back(point_data<int>(0, 0));
+ points.push_back(point_data<int>(0, 1));
+ vd_type test_output;
+ construct_voronoi(points.begin(), points.end(), &test_output);
+ VERIFY_OUTPUT(test_output);
+ CHECK_OUTPUT_SIZE(test_output, 2, 0, 2);
+
+ const_cell_iterator cell_it = test_output.cells().begin();
+ cell_it++;
+
+ const voronoi_edge_type* edge1_1 = cell_it->incident_edge();
+ const voronoi_edge_type* edge1_2 = edge1_1->twin();
+
+ BOOST_TEST(edge1_1->twin() == edge1_2);
+ BOOST_TEST(edge1_2->twin() == edge1_1);
+
+ BOOST_TEST(edge1_1->next() == edge1_1);
+ BOOST_TEST(edge1_1->prev() == edge1_1);
+ BOOST_TEST(edge1_1->rot_next() == edge1_2);
+ BOOST_TEST(edge1_1->rot_prev() == edge1_2);
+
+ BOOST_TEST(edge1_2->next() == edge1_2);
+ BOOST_TEST(edge1_2->prev() == edge1_2);
+ BOOST_TEST(edge1_2->rot_next() == edge1_1);
+ BOOST_TEST(edge1_2->rot_prev() == edge1_1);
+}
+
+// Sites: (0, 0), (1, 1), (2, 2).
+void collinear_sites_test2()
+{
+ std::vector< point_data<int> > points;
+ points.push_back(point_data<int>(0, 0));
+ points.push_back(point_data<int>(1, 1));
+ points.push_back(point_data<int>(2, 2));
+ vd_type test_output;
+ construct_voronoi(points.begin(), points.end(), &test_output);
+ VERIFY_OUTPUT(test_output);
+ CHECK_OUTPUT_SIZE(test_output, 3, 0, 4);
+
+ const_cell_iterator cell_it = test_output.cells().begin();
+ const voronoi_edge_type* edge1_1 = cell_it->incident_edge();
+ const voronoi_edge_type* edge1_2 = edge1_1->twin();
+ cell_it++;
+ cell_it++;
+ const voronoi_edge_type* edge2_2 = cell_it->incident_edge();
+ const voronoi_edge_type* edge2_1 = edge2_2->twin();
+
+ BOOST_TEST(edge1_1->twin() == edge1_2 && edge1_2->twin() == edge1_1);
+ BOOST_TEST(edge2_1->twin() == edge2_2 && edge2_2->twin() == edge2_1);
+
+ BOOST_TEST(edge1_1->next() == edge1_1 && edge1_1->prev() == edge1_1);
+ BOOST_TEST(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1);
+ BOOST_TEST(edge2_1->next() == edge1_2 && edge2_1->prev() == edge1_2);
+ BOOST_TEST(edge2_2->next() == edge2_2 && edge2_2->prev() == edge2_2);
+
+ BOOST_TEST(edge1_1->rot_next() == edge1_2 && edge1_1->rot_prev() == edge2_1);
+ BOOST_TEST(edge1_2->rot_next() == edge2_2 && edge1_2->rot_prev() == edge1_1);
+ BOOST_TEST(edge2_1->rot_next() == edge1_1 && edge2_1->rot_prev() == edge2_2);
+ BOOST_TEST(edge2_2->rot_next() == edge2_1 && edge2_2->rot_prev() == edge1_2);
+
+ BOOST_TEST(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1);
+ BOOST_TEST(edge2_1->next() == edge1_2 && edge2_1->prev() == edge1_2);
+}
+
+// Sites: (0, 0), (0, 4), (2, 1).
+void triangle_test1()
+{
+ point_data<int> point1(0, 0);
+ point_data<int> point2(0, 4);
+ point_data<int> point3(2, 1);
+ std::vector< point_data<int> > points;
+ points.push_back(point1);
+ points.push_back(point2);
+ points.push_back(point3);
+ vd_type test_output;
+ construct_voronoi(points.begin(), points.end(), &test_output);
+ VERIFY_OUTPUT(test_output);
+ CHECK_OUTPUT_SIZE(test_output, 3, 1, 6);
+
+ const_vertex_iterator it = test_output.vertices().begin();
+ BOOST_TEST_EQ(it->x(), 0.25);
+ BOOST_TEST_EQ(it->y(), 2.0);
+
+ const voronoi_edge_type* edge1_1 = it->incident_edge();
+ const voronoi_edge_type* edge1_2 = edge1_1->twin();
+ BOOST_TEST(edge1_1->cell()->source_index() == 1);
+ BOOST_TEST(edge1_2->cell()->source_index() == 2);
+
+ const voronoi_edge_type* edge2_1 = edge1_1->rot_prev();
+ const voronoi_edge_type* edge2_2 = edge2_1->twin();
+ BOOST_TEST(edge2_1->cell()->source_index() == 2);
+ BOOST_TEST(edge2_2->cell()->source_index() == 0);
+
+ const voronoi_edge_type* edge3_1 = edge2_1->rot_prev();
+ const voronoi_edge_type* edge3_2 = edge3_1->twin();
+ BOOST_TEST(edge3_1->cell()->source_index() == 0);
+ BOOST_TEST(edge3_2->cell()->source_index() == 1);
+
+ BOOST_TEST(edge1_2->twin() == edge1_1);
+ BOOST_TEST(edge2_2->twin() == edge2_1);
+ BOOST_TEST(edge3_2->twin() == edge3_1);
+
+ BOOST_TEST(edge1_1->prev() == edge3_2 && edge1_1->next() == edge3_2);
+ BOOST_TEST(edge2_1->prev() == edge1_2 && edge2_1->next() == edge1_2);
+ BOOST_TEST(edge3_1->prev() == edge2_2 && edge3_1->next() == edge2_2);
+
+ BOOST_TEST(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1);
+ BOOST_TEST(edge2_2->next() == edge3_1 && edge2_2->prev() == edge3_1);
+ BOOST_TEST(edge3_2->next() == edge1_1 && edge3_2->prev() == edge1_1);
+
+ BOOST_TEST(edge1_1->rot_next() == edge3_1);
+ BOOST_TEST(edge3_1->rot_next() == edge2_1);
+ BOOST_TEST(edge2_1->rot_next() == edge1_1);
+
+ BOOST_TEST(edge1_2->rot_next() == edge2_2);
+ BOOST_TEST(edge2_2->rot_next() == edge3_2);
+ BOOST_TEST(edge3_2->rot_next() == edge1_2);
+}
+
+// Sites: (0, 1), (2, 0), (2, 4).
+void triangle_test2()
+{
+ point_data<int> point1(0, 1);
+ point_data<int> point2(2, 0);
+ point_data<int> point3(2, 4);
+ std::vector< point_data<int> > points;
+ points.push_back(point1);
+ points.push_back(point2);
+ points.push_back(point3);
+ vd_type test_output;
+ construct_voronoi(points.begin(), points.end(), &test_output);
+ VERIFY_OUTPUT(test_output);
+ CHECK_OUTPUT_SIZE(test_output, 3, 1, 6);
+
+ const_vertex_iterator it = test_output.vertices().begin();
+ BOOST_TEST_EQ(it->x(), 1.75);
+ BOOST_TEST_EQ(it->y(), 2.0);
+
+ const voronoi_edge_type* edge1_1 = it->incident_edge();
+ const voronoi_edge_type* edge1_2 = edge1_1->twin();
+ BOOST_TEST(edge1_1->cell()->source_index() == 2);
+ BOOST_TEST(edge1_2->cell()->source_index() == 1);
+
+ const voronoi_edge_type* edge2_1 = edge1_1->rot_prev();
+ const voronoi_edge_type* edge2_2 = edge2_1->twin();
+ BOOST_TEST(edge2_1->cell()->source_index() == 1);
+ BOOST_TEST(edge2_2->cell()->source_index() == 0);
+
+ const voronoi_edge_type* edge3_1 = edge2_1->rot_prev();
+ const voronoi_edge_type* edge3_2 = edge3_1->twin();
+ BOOST_TEST(edge3_1->cell()->source_index() == 0);
+ BOOST_TEST(edge3_2->cell()->source_index() == 2);
+
+ BOOST_TEST(edge1_2->twin() == edge1_1);
+ BOOST_TEST(edge2_2->twin() == edge2_1);
+ BOOST_TEST(edge3_2->twin() == edge3_1);
+
+ BOOST_TEST(edge1_1->prev() == edge3_2 && edge1_1->next() == edge3_2);
+ BOOST_TEST(edge2_1->prev() == edge1_2 && edge2_1->next() == edge1_2);
+ BOOST_TEST(edge3_1->prev() == edge2_2 && edge3_1->next() == edge2_2);
+
+ BOOST_TEST(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1);
+ BOOST_TEST(edge2_2->next() == edge3_1 && edge2_2->prev() == edge3_1);
+ BOOST_TEST(edge3_2->next() == edge1_1 && edge3_2->prev() == edge1_1);
+
+ BOOST_TEST(edge1_1->rot_next() == edge3_1);
+ BOOST_TEST(edge3_1->rot_next() == edge2_1);
+ BOOST_TEST(edge2_1->rot_next() == edge1_1);
+
+ BOOST_TEST(edge1_2->rot_next() == edge2_2);
+ BOOST_TEST(edge2_2->rot_next() == edge3_2);
+ BOOST_TEST(edge3_2->rot_next() == edge1_2);
+}
+
+// Sites: (0, 0), (0, 1), (1, 0), (1, 1).
+void square_test1()
+{
+ point_data<int> point1(0, 0);
+ point_data<int> point2(0, 1);
+ point_data<int> point3(1, 0);
+ point_data<int> point4(1, 1);
+ std::vector< point_data<int> > points;
+ points.push_back(point1);
+ points.push_back(point2);
+ points.push_back(point3);
+ points.push_back(point4);
+ vd_type test_output;
+ construct_voronoi(points.begin(), points.end(), &test_output);
+ VERIFY_OUTPUT(test_output);
+ CHECK_OUTPUT_SIZE(test_output, 4, 1, 8);
+
+ // Check voronoi vertex.
+ const_vertex_iterator it = test_output.vertices().begin();
+ BOOST_TEST_EQ(it->x(), 0.5);
+ BOOST_TEST_EQ(it->y(), 0.5);
+
+ // Check voronoi edges.
+ const voronoi_edge_type* edge1_1 = it->incident_edge();
+ const voronoi_edge_type* edge1_2 = edge1_1->twin();
+ BOOST_TEST(edge1_1->cell()->source_index() == 3);
+ BOOST_TEST(edge1_2->cell()->source_index() == 2);
+
+ const voronoi_edge_type* edge2_1 = edge1_1->rot_prev();
+ const voronoi_edge_type* edge2_2 = edge2_1->twin();
+ BOOST_TEST(edge2_1->cell()->source_index() == 2);
+ BOOST_TEST(edge2_2->cell()->source_index() == 0);
+
+ const voronoi_edge_type* edge3_1 = edge2_1->rot_prev();
+ const voronoi_edge_type* edge3_2 = edge3_1->twin();
+ BOOST_TEST(edge3_1->cell()->source_index() == 0);
+ BOOST_TEST(edge3_2->cell()->source_index() == 1);
+
+ const voronoi_edge_type* edge4_1 = edge3_1->rot_prev();
+ const voronoi_edge_type* edge4_2 = edge4_1->twin();
+ BOOST_TEST(edge4_1->cell()->source_index() == 1);
+ BOOST_TEST(edge4_2->cell()->source_index() == 3);
+
+ BOOST_TEST(edge1_2->twin() == edge1_1);
+ BOOST_TEST(edge2_2->twin() == edge2_1);
+ BOOST_TEST(edge3_2->twin() == edge3_1);
+ BOOST_TEST(edge4_2->twin() == edge4_1);
+
+ BOOST_TEST(edge1_1->prev() == edge4_2 && edge1_1->next() == edge4_2);
+ BOOST_TEST(edge2_1->prev() == edge1_2 && edge2_1->next() == edge1_2);
+ BOOST_TEST(edge3_1->prev() == edge2_2 && edge3_1->next() == edge2_2);
+ BOOST_TEST(edge4_1->prev() == edge3_2 && edge4_1->next() == edge3_2);
+
+ BOOST_TEST(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1);
+ BOOST_TEST(edge2_2->next() == edge3_1 && edge2_2->prev() == edge3_1);
+ BOOST_TEST(edge3_2->next() == edge4_1 && edge3_2->prev() == edge4_1);
+ BOOST_TEST(edge4_2->next() == edge1_1 && edge4_2->prev() == edge1_1);
+
+ BOOST_TEST(edge1_1->rot_next() == edge4_1);
+ BOOST_TEST(edge4_1->rot_next() == edge3_1);
+ BOOST_TEST(edge3_1->rot_next() == edge2_1);
+ BOOST_TEST(edge2_1->rot_next() == edge1_1);
+
+ BOOST_TEST(edge1_2->rot_next() == edge2_2);
+ BOOST_TEST(edge2_2->rot_next() == edge3_2);
+ BOOST_TEST(edge3_2->rot_next() == edge4_2);
+ BOOST_TEST(edge4_2->rot_next() == edge1_2);
+}
+
+#ifdef NDEBUG
+void grid_test()
+{
+ vd_type test_output_small, test_output_large;
+ std::vector< point_data<int> > point_vec_small, point_vec_large;
+ int grid_size[] = {10, 33, 101};
+ int max_value[] = {10, 33, 101};
+ int array_length = sizeof(grid_size) / sizeof(int);
+ for (int k = 0; k < array_length; k++) {
+ test_output_small.clear();
+ test_output_large.clear();
+ point_vec_small.clear();
+ point_vec_large.clear();
+ int koef = (std::numeric_limits<int>::max)() / max_value[k];
+ for (int i = 0; i < grid_size[k]; i++) {
+ for (int j = 0; j < grid_size[k]; j++) {
+ point_vec_small.push_back(point_data<int>(i, j));
+ point_vec_large.push_back(point_data<int>(koef * i, koef * j));
+ }
+ }
+ construct_voronoi(point_vec_small.begin(), point_vec_small.end(), &test_output_small);
+ construct_voronoi(point_vec_large.begin(), point_vec_large.end(), &test_output_large);
+ VERIFY_OUTPUT(test_output_small);
+ VERIFY_OUTPUT(test_output_large);
+ unsigned int num_cells = grid_size[k] * grid_size[k];
+ unsigned int num_vertices = num_cells - 2 * grid_size[k] + 1;
+ unsigned int num_edges = 4 * num_cells - 4 * grid_size[k];
+ CHECK_OUTPUT_SIZE(test_output_small, num_cells, num_vertices, num_edges);
+ CHECK_OUTPUT_SIZE(test_output_large, num_cells, num_vertices, num_edges);
+ }
+}
+#endif
+
+#ifdef NDEBUG
+void random_test()
+{
+ boost::mt19937 gen(static_cast<unsigned int>(time(NULL)));
+ vd_type test_output_small, test_output_large;
+ std::vector< point_data<int> > point_vec_small, point_vec_large;
+ int num_points[] = {10, 100, 1000, 10000};
+ int num_runs[] = {1000, 100, 10, 1};
+ int mod_koef[] = {10, 100, 100, 1000};
+ int max_value[] = {5, 50, 50, 5000};
+ int array_length = sizeof(num_points) / sizeof(int);
+ for (int k = 0; k < array_length; k++) {
+ int koef = (std::numeric_limits<int>::max)() / max_value[k];
+ for (int i = 0; i < num_runs[k]; i++) {
+ test_output_small.clear();
+ test_output_large.clear();
+ point_vec_small.clear();
+ point_vec_large.clear();
+ for (int j = 0; j < num_points[k]; j++) {
+ int x = gen() % mod_koef[k] - mod_koef[k] / 2;
+ int y = gen() % mod_koef[k] - mod_koef[k] / 2;
+ point_vec_small.push_back(point_data<int>(x, y));
+ point_vec_large.push_back(point_data<int>(koef * x, koef * y));
+ }
+ construct_voronoi(point_vec_small.begin(), point_vec_small.end(), &test_output_small);
+ construct_voronoi(point_vec_large.begin(), point_vec_large.end(), &test_output_large);
+ VERIFY_OUTPUT(test_output_small);
+ VERIFY_OUTPUT(test_output_large);
+ BOOST_TEST_EQ(test_output_small.num_cells(), test_output_large.num_cells());
+ BOOST_TEST_EQ(test_output_small.num_vertices(), test_output_large.num_vertices());
+ BOOST_TEST_EQ(test_output_small.num_edges(), test_output_large.num_edges());
+ }
+ }
+}
+#endif
+
+void segment_sites_test1()
+{
+ vd_type test_output;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(0, 0);
+ point_data<int> point2(1, 1);
+ segments.push_back(segment_data<int>(point1, point2));
+ construct_voronoi(segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 3, 0, 4);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+void segment_sites_test2()
+{
+ vd_type test_output;
+ std::vector< point_data<int> > points;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(0, 0);
+ point_data<int> point2(4, 4);
+ point_data<int> point3(3, 1);
+ point_data<int> point4(1, 3);
+ segments.push_back(segment_data<int>(point1, point2));
+ points.push_back(point3);
+ points.push_back(point4);
+ construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 5, 4, 16);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+void segment_sites_test3()
+{
+ vd_type test_output;
+ std::vector< point_data<int> > points;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(4, 0);
+ point_data<int> point2(0, 4);
+ point_data<int> point3(3, 3);
+ point_data<int> point4(1, 1);
+ segments.push_back(segment_data<int>(point1, point2));
+ points.push_back(point3);
+ points.push_back(point4);
+ construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 5, 4, 16);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+void segment_sites_test4()
+{
+ vd_type test_output;
+ std::vector< point_data<int> > points;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(4, 0);
+ point_data<int> point2(0, 4);
+ point_data<int> point3(3, 2);
+ point_data<int> point4(2, 3);
+ segments.push_back(segment_data<int>(point1, point2));
+ points.push_back(point3);
+ points.push_back(point4);
+ construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 5, 3, 14);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+void segment_site_test5()
+{
+ vd_type test_output;
+ std::vector< point_data<int> > points;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(0, 0);
+ point_data<int> point2(0, 8);
+ point_data<int> point3(-2, -2);
+ point_data<int> point4(-2, 4);
+ point_data<int> point5(-2, 10);
+ segments.push_back(segment_data<int>(point1, point2));
+ points.push_back(point3);
+ points.push_back(point4);
+ points.push_back(point5);
+ construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 6, 4, 18);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+void segment_site_test6()
+{
+ vd_type test_output;
+ std::vector< point_data<int> > points;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(-1, 1);
+ point_data<int> point2(1, 0);
+ point_data<int> point3(1, 2);
+ segments.push_back(segment_data<int>(point2, point3));
+ points.push_back(point1);
+ construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 4, 2, 10);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+void segment_site_test7()
+{
+ vd_type test_output;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(0, 0);
+ point_data<int> point2(4, 0);
+ point_data<int> point3(0, 4);
+ point_data<int> point4(4, 4);
+ segments.push_back(segment_data<int>(point1, point2));
+ segments.push_back(segment_data<int>(point2, point3));
+ segments.push_back(segment_data<int>(point3, point4));
+ construct_voronoi(segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 7, 6, 24);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+void segment_site_test8()
+{
+ vd_type test_output;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(0, 0);
+ point_data<int> point2(4, 0);
+ point_data<int> point3(4, 4);
+ point_data<int> point4(0, 4);
+ segments.push_back(segment_data<int>(point1, point2));
+ segments.push_back(segment_data<int>(point2, point3));
+ segments.push_back(segment_data<int>(point3, point4));
+ segments.push_back(segment_data<int>(point4, point1));
+ construct_voronoi(segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 8, 5, 24);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+void segment_site_test9()
+{
+ vd_type test_output;
+ std::vector< segment_data<int> > segments;
+ point_data<int> point1(0, 0);
+ point_data<int> point2(2, 0);
+ point_data<int> point3(4, 0);
+ segments.push_back(segment_data<int>(point1, point2));
+ segments.push_back(segment_data<int>(point2, point3));
+ construct_voronoi(segments.begin(), segments.end(), &test_output);
+ CHECK_OUTPUT_SIZE(test_output, 5, 0, 8);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+#ifdef NDEBUG
+void segment_grid_test()
+{
+ vd_type test_output_small, test_output_large;
+ std::vector< segment_data<int> > segments_small, segments_large;
+ int grid_size[] = {10, 27, 53};
+ int max_value[] = {100, 330, 1000};
+ int array_length = sizeof(grid_size) / sizeof(int);
+ for (int k = 0; k < array_length; k++) {
+ test_output_small.clear();
+ test_output_large.clear();
+ segments_small.clear();
+ segments_large.clear();
+ int cur_sz = grid_size[k];
+ int koef = (std::numeric_limits<int>::max)() / max_value[k];
+ for (int i = 0; i < cur_sz + 1; i++)
+ for (int j = 0; j < cur_sz; j++) {
+ point_data<int> point1_1(10 * i, 10 * j);
+ point_data<int> point1_2(koef * 10 * i, koef * 10 * j);
+ point_data<int> point2_1(10 * i, 10 * j + 10);
+ point_data<int> point2_2(koef * 10 * i, koef * (10 * j + 10));
+ segments_small.push_back(segment_data<int>(point1_1, point2_1));
+ segments_large.push_back(segment_data<int>(point1_2, point2_2));
+ point_data<int> point3_1(10 * j, 10 * i);
+ point_data<int> point3_2(koef * 10 * j, koef * 10 * i);
+ point_data<int> point4_1(10 * j + 10, 10 * i);
+ point_data<int> point4_2(koef * (10 * j + 10), koef * 10 * i);
+ segments_small.push_back(segment_data<int>(point3_1, point4_1));
+ segments_large.push_back(segment_data<int>(point3_2, point4_2));
+ }
+ construct_voronoi(segments_small.begin(), segments_small.end(), &test_output_small);
+ construct_voronoi(segments_large.begin(), segments_large.end(), &test_output_large);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output_small);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output_large);
+ BOOST_TEST_EQ(test_output_small.num_cells(), test_output_large.num_cells());
+ BOOST_TEST_EQ(test_output_small.num_vertices(), test_output_large.num_vertices());
+ BOOST_TEST_EQ(test_output_small.num_edges(), test_output_large.num_edges());
+ }
+}
+#endif
+
+#ifdef NDEBUG
+void segment_random_test1()
+{
+ boost::mt19937 gen(static_cast<unsigned int>(time(NULL)));
+ vd_type test_output;
+ std::vector< point_data<int> > points;
+ std::vector< segment_data<int> > segments;
+ int num_runs = 1000;
+ int num_segments = 10;
+ points.push_back(point_data<int>(-100, -100));
+ points.push_back(point_data<int>(-100, 100));
+ points.push_back(point_data<int>(100, -100));
+ points.push_back(point_data<int>(100, 100));
+ for (int i = 0; i < num_runs; i++) {
+ test_output.clear();
+ segments.clear();
+ for (int j = 0; j < num_segments; j++) {
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+ while (x1 == x2 && y1 == y2) {
+ x1 = (gen() % 100) - 50;
+ y1 = (gen() % 100) - 50;
+ x2 = (gen() % 100) - 50;
+ y2 = (gen() % 100) - 50;
+ }
+ point_data<int> point1(x1, y1);
+ point_data<int> point2(x2, y2);
+ segments.push_back(segment_data<int>(point1, point2));
+ }
+ voronoi_test_helper::clean_segment_set(segments);
+ construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+ }
+}
+#endif
+
+#ifdef NDEBUG
+void segment_random_test2()
+{
+ boost::mt19937 gen(static_cast<unsigned int>(time(NULL)));
+ vd_type test_output_small, test_output_large;
+ std::vector< segment_data<int> > segments_small, segments_large;
+ int num_segments[] = {5, 25, 125, 625};
+ int num_runs[] = {1000, 100, 10, 1};
+ int mod_koef1[] = {10, 100, 200, 300};
+ int mod_koef2[] = {10, 20, 50, 100};
+ int max_value[] = {10, 60, 125, 200};
+ int array_length = sizeof(num_segments) / sizeof(int);
+ for (int k = 0; k < array_length; k++) {
+ int koef = (std::numeric_limits<int>::max)() / max_value[k];
+ for (int i = 0; i < num_runs[k]; i++) {
+ test_output_small.clear();
+ test_output_large.clear();
+ segments_small.clear();
+ segments_large.clear();
+ for (int j = 0; j < num_segments[k]; j++) {
+ int x1 = (gen() % mod_koef1[k]) - mod_koef1[k] / 2;
+ int y1 = (gen() % mod_koef1[k]) - mod_koef1[k] / 2;
+ int dx = 0, dy = 0;
+ while (dx == 0 && dy == 0) {
+ dx = (gen() % mod_koef2[k]) - mod_koef2[k] / 2;
+ dy = (gen() % mod_koef2[k]) - mod_koef2[k] / 2;
+ }
+ int x2 = x1 + dx;
+ int y2 = y1 + dy;
+ point_data<int> point1_small(x1, y1);
+ point_data<int> point2_small(x2, y2);
+ segments_small.push_back(segment_data<int>(point1_small, point2_small));
+ }
+ voronoi_test_helper::clean_segment_set(segments_small);
+ for (std::vector< segment_data<int> >::iterator it = segments_small.begin();
+ it != segments_small.end(); ++it) {
+ int x1 = it->low().x() * koef;
+ int y1 = it->low().y() * koef;
+ int x2 = it->high().x() * koef;
+ int y2 = it->high().y() * koef;
+ point_data<int> point1_large(x1, y1);
+ point_data<int> point2_large(x2, y2);
+ segments_large.push_back(segment_data<int>(point1_large, point2_large));
+ }
+ construct_voronoi(segments_small.begin(), segments_small.end(), &test_output_small);
+ construct_voronoi(segments_large.begin(), segments_large.end(), &test_output_large);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output_small);
+ VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output_large);
+ BOOST_TEST_EQ(test_output_small.num_cells(), test_output_large.num_cells());
+ BOOST_TEST_EQ(test_output_small.num_vertices(), test_output_large.num_vertices());
+ BOOST_TEST_EQ(test_output_small.num_edges(), test_output_large.num_edges());
+ }
+ }
+}
+#endif
+
+int main()
+{
+ single_site_test();
+ collinear_sites_test1();
+ collinear_sites_test2();
+ triangle_test1();
+ triangle_test2();
+ square_test1();
+#ifdef NDEBUG
+ grid_test();
+ random_test();
+#endif
+ segment_sites_test1();
+ segment_sites_test2();
+ segment_sites_test3();
+ segment_sites_test4();
+ segment_site_test5();
+ segment_site_test6();
+ segment_site_test7();
+ segment_site_test8();
+ segment_site_test9();
+#ifdef NDEBUG
+ segment_grid_test();
+ segment_random_test1();
+ segment_random_test2();
+#endif
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/voronoi_ctypes_test.cpp b/src/boost/libs/polygon/test/voronoi_ctypes_test.cpp
new file mode 100644
index 000000000..6087e7244
--- /dev/null
+++ b/src/boost/libs/polygon/test/voronoi_ctypes_test.cpp
@@ -0,0 +1,334 @@
+// Boost.Polygon library voronoi_ctypes_test.cpp file
+
+// Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/detail/voronoi_ctypes.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <vector>
+#include <ctime>
+
+using namespace boost::polygon::detail;
+
+type_converter_fpt to_fpt;
+
+void ulp_comparison_test1()
+{
+ ulp_comparison<double> ulp_cmp;
+ uint64 a = 22;
+ uint64 b = 27;
+ fpt64 da, db;
+ std::memcpy(&da, &a, sizeof(uint64));
+ std::memcpy(&db, &b, sizeof(uint64));
+ BOOST_TEST_EQ(ulp_cmp(da, db, 1), ulp_cmp.LESS);
+ BOOST_TEST_EQ(ulp_cmp(db, da, 1), ulp_cmp.MORE);
+ BOOST_TEST_EQ(ulp_cmp(da, db, 4), ulp_cmp.LESS);
+ BOOST_TEST_EQ(ulp_cmp(da, db, 5), ulp_cmp.EQUAL);
+ BOOST_TEST_EQ(ulp_cmp(da, db, 6), ulp_cmp.EQUAL);
+}
+
+void ulp_comparison_test2()
+{
+ ulp_comparison<fpt64> ulp_cmp;
+ uint64 a = 0ULL;
+ uint64 b = 0x8000000000000002ULL;
+ fpt64 da, db;
+ std::memcpy(&da, &a, sizeof(uint64));
+ std::memcpy(&db, &b, sizeof(uint64));
+ BOOST_TEST_EQ(ulp_cmp(da, db, 1), ulp_cmp.MORE);
+ BOOST_TEST_EQ(ulp_cmp(db, da, 1), ulp_cmp.LESS);
+ BOOST_TEST_EQ(ulp_cmp(da, db, 2), ulp_cmp.EQUAL);
+ BOOST_TEST_EQ(ulp_cmp(da, db, 3), ulp_cmp.EQUAL);
+}
+
+void extended_exponent_fpt_test1()
+{
+ boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+ fpt64 b = 0.0;
+ efpt64 eeb(b);
+ for (int i = 0; i < 1000; ++i) {
+ fpt64 a = to_fpt(static_cast<int64>(gen()));
+ efpt64 eea(a);
+ efpt64 neg = -eea;
+ efpt64 sum = eea + eeb;
+ efpt64 dif = eea - eeb;
+ efpt64 mul = eea * eeb;
+ BOOST_TEST_EQ(to_fpt(neg), -a);
+ BOOST_TEST_EQ(to_fpt(sum), a + b);
+ BOOST_TEST_EQ(to_fpt(dif), a - b);
+ BOOST_TEST_EQ(to_fpt(mul), a * b);
+ }
+}
+
+void extended_exponent_fpt_test2()
+{
+ boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+ fpt64 a = 0.0;
+ efpt64 eea(a);
+ for (int i = 0; i < 1000; ++i) {
+ fpt64 b = to_fpt(static_cast<int64>(gen()));
+ if (b == 0.0)
+ continue;
+ efpt64 eeb(b);
+ efpt64 neg = -eea;
+ efpt64 sum = eea + eeb;
+ efpt64 dif = eea - eeb;
+ efpt64 mul = eea * eeb;
+ efpt64 div = eea / eeb;
+ BOOST_TEST_EQ(to_fpt(neg), -a);
+ BOOST_TEST_EQ(to_fpt(sum), a + b);
+ BOOST_TEST_EQ(to_fpt(dif), a - b);
+ BOOST_TEST_EQ(to_fpt(mul), a * b);
+ BOOST_TEST_EQ(to_fpt(div), a / b);
+ }
+}
+
+void extended_exponent_fpt_test3()
+{
+ boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+ for (int i = 0; i < 1000; ++i) {
+ fpt64 a = to_fpt(static_cast<int64>(gen()));
+ fpt64 b = to_fpt(static_cast<int64>(gen()));
+ if (b == 0.0)
+ continue;
+ efpt64 eea(a);
+ efpt64 eeb(b);
+ efpt64 neg = -eea;
+ efpt64 sum = eea + eeb;
+ efpt64 dif = eea - eeb;
+ efpt64 mul = eea * eeb;
+ efpt64 div = eea / eeb;
+ BOOST_TEST_EQ(to_fpt(neg), -a);
+ BOOST_TEST_EQ(to_fpt(sum), a + b);
+ BOOST_TEST_EQ(to_fpt(dif), a - b);
+ BOOST_TEST_EQ(to_fpt(mul), a * b);
+ BOOST_TEST_EQ(to_fpt(div), a / b);
+ }
+}
+
+void extended_exponent_fpt_test4()
+{
+ for (int exp = 0; exp < 64; ++exp)
+ for (int i = 1; i < 100; ++i) {
+ fpt64 a = i;
+ fpt64 b = to_fpt(1LL << exp);
+ efpt64 eea(a);
+ efpt64 eeb(b);
+ efpt64 neg = -eea;
+ efpt64 sum = eea + eeb;
+ efpt64 dif = eea - eeb;
+ efpt64 mul = eea * eeb;
+ efpt64 div = eea / eeb;
+ BOOST_TEST_EQ(to_fpt(neg), -a);
+ BOOST_TEST_EQ(to_fpt(sum), a + b);
+ BOOST_TEST_EQ(to_fpt(dif), a - b);
+ BOOST_TEST_EQ(to_fpt(mul), a * b);
+ BOOST_TEST_EQ(to_fpt(div), a / b);
+ }
+}
+
+void extended_exponent_fpt_test5()
+{
+ for (int i = 0; i < 100; ++i) {
+ efpt64 a(to_fpt(i * i));
+ efpt64 b = a.sqrt();
+ BOOST_TEST_EQ(to_fpt(b), to_fpt(i));
+ }
+}
+
+void extended_exponent_fpt_test6()
+{
+ for (int i = -10; i <= 10; ++i) {
+ efpt64 a(to_fpt(i));
+ BOOST_TEST_EQ(is_pos(a), i > 0);
+ BOOST_TEST_EQ(is_neg(a), i < 0);
+ BOOST_TEST_EQ(is_zero(a), !i);
+ }
+}
+
+void extended_int_test1()
+{
+ typedef extended_int<1> eint32;
+ eint32 e1(0), e2(32), e3(-32);
+ BOOST_TEST_EQ(e1.count(), 0);
+ BOOST_TEST_EQ(e1.size(), 0U);
+ BOOST_TEST_EQ(e2.count(), 1);
+ BOOST_TEST_EQ(e2.chunks()[0], 32U);
+ BOOST_TEST_EQ(e2.size(), 1U);
+ BOOST_TEST_EQ(e3.count(), -1);
+ BOOST_TEST_EQ(e3.chunks()[0], 32U);
+ BOOST_TEST_EQ(e3.size(), 1U);
+}
+
+void extended_int_test2()
+{
+ typedef extended_int<2> eint64;
+ int64 val64 = 0x7fffffffffffffffLL;
+ eint64 e1(0), e2(32), e3(-32), e4(val64), e5(-val64);
+ BOOST_TEST_EQ(e1.count(), 0);
+ BOOST_TEST_EQ(e2.count(), 1);
+ BOOST_TEST_EQ(e2.chunks()[0], 32U);
+ BOOST_TEST_EQ(e3.count(), -1);
+ BOOST_TEST_EQ(e3.chunks()[0], 32U);
+ BOOST_TEST_EQ(e4.count(), 2);
+ BOOST_TEST_EQ(e4.chunks()[0], 0xffffffff);
+ BOOST_TEST_EQ(e4.chunks()[1], val64 >> 32);
+ BOOST_TEST_EQ(e5.count(), -2);
+ BOOST_TEST_EQ(e5.chunks()[0], 0xffffffff);
+ BOOST_TEST_EQ(e5.chunks()[1], val64 >> 32);
+}
+
+void extended_int_test3()
+{
+ typedef extended_int<2> eint64;
+ std::vector<uint32> chunks;
+ chunks.push_back(1);
+ chunks.push_back(2);
+ eint64 e1(chunks, true), e2(chunks, false);
+ BOOST_TEST_EQ(e1.count(), 2);
+ BOOST_TEST_EQ(e1.chunks()[0], 2U);
+ BOOST_TEST_EQ(e1.chunks()[1], 1U);
+ BOOST_TEST_EQ(e2.count(), -2);
+ BOOST_TEST_EQ(e2.chunks()[0], 2U);
+ BOOST_TEST_EQ(e2.chunks()[1], 1U);
+}
+
+void extended_int_test4()
+{
+ typedef extended_int<2> eint64;
+ std::vector<uint32> chunks;
+ chunks.push_back(1);
+ chunks.push_back(2);
+ eint64 e1(chunks, true), e2(chunks, false);
+ BOOST_TEST_EQ(e1 == e2, false);
+ BOOST_TEST_EQ(e1 == -e2, true);
+ BOOST_TEST_EQ(e1 != e2, true);
+ BOOST_TEST_EQ(e1 != -e2, false);
+ BOOST_TEST_EQ(e1 < e2, false);
+ BOOST_TEST_EQ(e1 < -e2, false);
+ BOOST_TEST_EQ(e1 <= e2, false);
+ BOOST_TEST_EQ(e1 <= -e2, true);
+ BOOST_TEST_EQ(e1 > e2, true);
+ BOOST_TEST_EQ(e1 > -e2, false);
+ BOOST_TEST_EQ(e1 >= e2, true);
+ BOOST_TEST_EQ(e1 >= -e2, true);
+}
+
+void extended_int_test5()
+{
+ typedef extended_int<2> eint64;
+ boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+ for (int i = 0; i < 1000; ++i) {
+ int64 i1 = static_cast<int64>(gen());
+ int64 i2 = static_cast<int64>(gen());
+ eint64 e1(i1), e2(i2);
+ BOOST_TEST_EQ(e1 == e2, i1 == i2);
+ BOOST_TEST_EQ(e1 != e2, i1 != i2);
+ BOOST_TEST_EQ(e1 > e2, i1 > i2);
+ BOOST_TEST_EQ(e1 >= e2, i1 >= i2);
+ BOOST_TEST_EQ(e1 < e2, i1 < i2);
+ BOOST_TEST_EQ(e1 <= e2, i1 <= i2);
+ }
+}
+
+void extended_int_test6()
+{
+ typedef extended_int<1> eint32;
+ eint32 e1(32);
+ eint32 e2 = -e1;
+ BOOST_TEST_EQ(e2.count(), -1);
+ BOOST_TEST_EQ(e2.size(), 1U);
+ BOOST_TEST_EQ(e2.chunks()[0], 32U);
+}
+
+void extended_int_test7()
+{
+ typedef extended_int<2> eint64;
+ boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+ for (int i = 0; i < 1000; ++i) {
+ int64 i1 = static_cast<int64>(gen()) >> 2;
+ int64 i2 = static_cast<int64>(gen()) >> 2;
+ eint64 e1(i1), e2(i2), e3(i1 + i2), e4(i1 - i2);
+ BOOST_TEST(e1 + e2 == e3);
+ BOOST_TEST(e1 - e2 == e4);
+ }
+}
+
+void extended_int_test8()
+{
+ typedef extended_int<2> eint64;
+ boost::mt19937 gen(static_cast<uint32>(time(NULL)));
+ for (int i = 0; i < 1000; ++i) {
+ int64 i1 = static_cast<int32>(gen());
+ int64 i2 = static_cast<int32>(gen());
+ eint64 e1(i1), e2(i2), e3(i1 * i2);
+ BOOST_TEST(e1 * e2 == e3);
+ }
+}
+
+void extended_int_test9()
+{
+ typedef extended_int<1> eint32;
+ for (int i = -10; i <= 10; ++i) {
+ for (int j = -10; j <= 10; ++j) {
+ eint32 e1(i), e2(j), e3(i+j), e4(i-j), e5(i*j);
+ BOOST_TEST(e1 + e2 == e3);
+ BOOST_TEST(e1 - e2 == e4);
+ BOOST_TEST(e1 * e2 == e5);
+ }
+ }
+}
+
+void extended_int_test10()
+{
+ typedef extended_int<2> eint64;
+ boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+ for (int i = 0; i < 100; ++i) {
+ int64 i1 = static_cast<int64>(gen()) >> 20;
+ int64 i2 = i1 >> 32;
+ eint64 e1(i1), e2(i2);
+ BOOST_TEST(to_fpt(e1) == static_cast<fpt64>(i1));
+ BOOST_TEST(to_fpt(e2) == static_cast<fpt64>(i2));
+ }
+}
+
+void extened_int_test11()
+{
+ typedef extended_int<64> eint2048;
+ eint2048 two(2), value(1);
+ for (int i = 0; i < 1024; ++i)
+ value = value * two;
+ BOOST_TEST_EQ(value.count(), 33);
+ for (std::size_t i = 1; i < value.size(); ++i)
+ BOOST_TEST_EQ(value.chunks()[i-1], 0U);
+ BOOST_TEST_EQ(value.chunks()[32], 1U);
+}
+
+int main()
+{
+ ulp_comparison_test1();
+ ulp_comparison_test2();
+ extended_exponent_fpt_test1();
+ extended_exponent_fpt_test2();
+ extended_exponent_fpt_test3();
+ extended_exponent_fpt_test4();
+ extended_exponent_fpt_test5();
+ extended_exponent_fpt_test6();
+ extended_int_test1();
+ extended_int_test2();
+ extended_int_test3();
+ extended_int_test4();
+ extended_int_test5();
+ extended_int_test6();
+ extended_int_test7();
+ extended_int_test8();
+ extended_int_test9();
+ extended_int_test10();
+ extened_int_test11();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/voronoi_diagram_test.cpp b/src/boost/libs/polygon/test/voronoi_diagram_test.cpp
new file mode 100644
index 000000000..6646a1755
--- /dev/null
+++ b/src/boost/libs/polygon/test/voronoi_diagram_test.cpp
@@ -0,0 +1,125 @@
+// Boost.Polygon library voronoi_diagram_test.cpp file
+
+// Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/voronoi_diagram.hpp>
+#include <boost/polygon/voronoi_geometry_type.hpp>
+
+using namespace boost::polygon;
+
+typedef voronoi_cell<double> voronoi_cell_type;
+typedef voronoi_vertex<double> voronoi_vertex_type;
+typedef voronoi_edge<double> voronoi_edge_type;
+typedef voronoi_diagram<double> voronoi_diagram_type;
+
+void voronoi_cell_test()
+{
+ voronoi_cell_type cell(1, SOURCE_CATEGORY_INITIAL_SEGMENT);
+ cell.color(27);
+ BOOST_TEST(!cell.contains_point());
+ BOOST_TEST(cell.contains_segment());
+ BOOST_TEST(cell.is_degenerate());
+ BOOST_TEST(cell.source_index() == 1);
+ BOOST_TEST(cell.source_category() == SOURCE_CATEGORY_INITIAL_SEGMENT);
+ BOOST_TEST(cell.incident_edge() == NULL);
+ BOOST_TEST(cell.color() == 27);
+
+ voronoi_edge_type edge(true, true);
+ cell.incident_edge(&edge);
+ BOOST_TEST(!cell.is_degenerate());
+ BOOST_TEST(cell.incident_edge() == &edge);
+}
+
+void voronoi_vertex_test()
+{
+ voronoi_vertex_type vertex(1, 2);
+ vertex.color(27);
+ BOOST_TEST(vertex.is_degenerate());
+ BOOST_TEST(vertex.x() == 1);
+ BOOST_TEST(vertex.y() == 2);
+ BOOST_TEST(vertex.incident_edge() == NULL);
+ BOOST_TEST(vertex.color() == 27);
+
+ voronoi_edge_type edge(true, true);
+ vertex.incident_edge(&edge);
+ BOOST_TEST(!vertex.is_degenerate());
+ BOOST_TEST(vertex.incident_edge() == &edge);
+}
+
+void voronoi_edge_test()
+{
+ voronoi_edge_type edge1(false, false);
+ edge1.color(13);
+ BOOST_TEST(!edge1.is_primary());
+ BOOST_TEST(edge1.is_secondary());
+ BOOST_TEST(!edge1.is_linear());
+ BOOST_TEST(edge1.is_curved());
+ BOOST_TEST(!edge1.is_finite());
+ BOOST_TEST(edge1.is_infinite());
+ BOOST_TEST(edge1.color() == 13);
+
+ voronoi_edge_type edge2(true, true);
+ edge2.color(14);
+ BOOST_TEST(edge2.is_primary());
+ BOOST_TEST(!edge2.is_secondary());
+ BOOST_TEST(edge2.is_linear());
+ BOOST_TEST(!edge2.is_curved());
+ BOOST_TEST(!edge2.is_finite());
+ BOOST_TEST(edge2.is_infinite());
+ BOOST_TEST(edge2.color() == 14);
+
+ edge1.twin(&edge2);
+ edge2.twin(&edge1);
+ BOOST_TEST(edge1.twin() == &edge2);
+ BOOST_TEST(edge2.twin() == &edge1);
+
+ edge1.next(&edge2);
+ edge1.prev(&edge2);
+ edge2.next(&edge1);
+ edge2.prev(&edge1);
+ BOOST_TEST(edge1.next() == &edge2);
+ BOOST_TEST(edge1.prev() == &edge2);
+ BOOST_TEST(edge1.rot_next() == &edge1);
+ BOOST_TEST(edge1.rot_prev() == &edge1);
+
+ voronoi_cell_type cell(1, SOURCE_CATEGORY_INITIAL_SEGMENT);
+ edge1.cell(&cell);
+ BOOST_TEST(edge1.cell() == &cell);
+
+ voronoi_vertex_type vertex0(1, 2);
+ edge1.vertex0(&vertex0);
+ BOOST_TEST(edge1.vertex0() == &vertex0);
+ BOOST_TEST(edge2.vertex1() == &vertex0);
+
+ voronoi_vertex_type vertex1(2, 1);
+ edge2.vertex0(&vertex1);
+ BOOST_TEST(edge1.vertex1() == &vertex1);
+ BOOST_TEST(edge2.vertex0() == &vertex1);
+
+ BOOST_TEST(edge1.is_finite());
+ BOOST_TEST(edge2.is_finite());
+}
+
+void voronoi_diagram_test()
+{
+ voronoi_diagram_type vd;
+ BOOST_TEST(vd.num_cells() == 0);
+ BOOST_TEST(vd.num_vertices() == 0);
+ BOOST_TEST(vd.num_edges() == 0);
+ vd.clear();
+}
+
+int main()
+{
+ voronoi_cell_test();
+ voronoi_vertex_test();
+ voronoi_edge_test();
+ voronoi_diagram_test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/voronoi_geometry_type_test.cpp b/src/boost/libs/polygon/test/voronoi_geometry_type_test.cpp
new file mode 100644
index 000000000..82dd9fe44
--- /dev/null
+++ b/src/boost/libs/polygon/test/voronoi_geometry_type_test.cpp
@@ -0,0 +1,34 @@
+// Boost.Polygon library voronoi_geometry_type_test.cpp file
+
+// Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/voronoi_geometry_type.hpp>
+
+using namespace boost::polygon;
+
+void source_category_test1()
+{
+ BOOST_TEST(belongs(SOURCE_CATEGORY_SINGLE_POINT, GEOMETRY_CATEGORY_POINT));
+ BOOST_TEST(belongs(SOURCE_CATEGORY_SEGMENT_START_POINT, GEOMETRY_CATEGORY_POINT));
+ BOOST_TEST(belongs(SOURCE_CATEGORY_SEGMENT_END_POINT, GEOMETRY_CATEGORY_POINT));
+ BOOST_TEST(!belongs(SOURCE_CATEGORY_INITIAL_SEGMENT, GEOMETRY_CATEGORY_POINT));
+ BOOST_TEST(!belongs(SOURCE_CATEGORY_REVERSE_SEGMENT, GEOMETRY_CATEGORY_POINT));
+
+ BOOST_TEST(!belongs(SOURCE_CATEGORY_SINGLE_POINT, GEOMETRY_CATEGORY_SEGMENT));
+ BOOST_TEST(!belongs(SOURCE_CATEGORY_SEGMENT_START_POINT, GEOMETRY_CATEGORY_SEGMENT));
+ BOOST_TEST(!belongs(SOURCE_CATEGORY_SEGMENT_END_POINT, GEOMETRY_CATEGORY_SEGMENT));
+ BOOST_TEST(belongs(SOURCE_CATEGORY_INITIAL_SEGMENT, GEOMETRY_CATEGORY_SEGMENT));
+ BOOST_TEST(belongs(SOURCE_CATEGORY_REVERSE_SEGMENT, GEOMETRY_CATEGORY_SEGMENT));
+}
+
+int main()
+{
+ source_category_test1();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/voronoi_predicates_test.cpp b/src/boost/libs/polygon/test/voronoi_predicates_test.cpp
new file mode 100644
index 000000000..1f5b3fb34
--- /dev/null
+++ b/src/boost/libs/polygon/test/voronoi_predicates_test.cpp
@@ -0,0 +1,636 @@
+// Boost.Polygon library voronoi_predicates_test.cpp file
+
+// Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/detail/voronoi_ctypes.hpp>
+#include <boost/polygon/detail/voronoi_predicates.hpp>
+#include <boost/polygon/detail/voronoi_structures.hpp>
+#include <boost/polygon/voronoi_geometry_type.hpp>
+#include <limits>
+#include <map>
+
+using namespace boost::polygon::detail;
+using namespace boost::polygon;
+
+ulp_comparison<double> ulp_cmp;
+
+typedef voronoi_predicates< voronoi_ctype_traits<int> > VP;
+typedef point_2d<int> point_type;
+typedef site_event<int> site_type;
+typedef circle_event<double> circle_type;
+VP::event_comparison_predicate<site_type, circle_type> event_comparison;
+
+typedef beach_line_node_key<site_type> key_type;
+typedef VP::distance_predicate<site_type> distance_predicate_type;
+typedef VP::node_comparison_predicate<key_type> node_comparison_type;
+typedef std::map<key_type, int, node_comparison_type> beach_line_type;
+typedef beach_line_type::iterator bieach_line_iterator;
+distance_predicate_type distance_predicate;
+node_comparison_type node_comparison;
+
+typedef VP::circle_existence_predicate<site_type> CEP_type;
+typedef VP::mp_circle_formation_functor<site_type, circle_type> MP_CFF_type;
+typedef VP::lazy_circle_formation_functor<site_type, circle_type> lazy_CFF_type;
+VP::circle_formation_predicate<site_type, circle_type, CEP_type, MP_CFF_type> mp_predicate;
+VP::circle_formation_predicate<site_type, circle_type, CEP_type, lazy_CFF_type> lazy_predicate;
+
+#define CHECK_ORIENTATION(P1, P2, P3, R1, R2) \
+ BOOST_TEST_EQ(VP::ot::eval(P1, P2, P3) == R1, true); \
+ BOOST_TEST_EQ(VP::ot::eval(P1, P3, P2) == R2, true); \
+ BOOST_TEST_EQ(VP::ot::eval(P2, P1, P3) == R2, true); \
+ BOOST_TEST_EQ(VP::ot::eval(P2, P3, P1) == R1, true); \
+ BOOST_TEST_EQ(VP::ot::eval(P3, P1, P2) == R1, true); \
+ BOOST_TEST_EQ(VP::ot::eval(P3, P2, P1) == R2, true)
+
+#define CHECK_EVENT_COMPARISON(A, B, R1, R2) \
+ BOOST_TEST_EQ(event_comparison(A, B), R1); \
+ BOOST_TEST_EQ(event_comparison(B, A), R2)
+
+#define CHECK_DISTANCE_PREDICATE(S1, S2, P3, RES) \
+ BOOST_TEST_EQ(distance_predicate(S1, S2, P3), RES)
+
+#define CHECK_NODE_COMPARISON(node, nodes, res, sz) \
+ for (int i = 0; i < sz; ++i) { \
+ BOOST_TEST_EQ(node_comparison(node, nodes[i]), res[i]); \
+ BOOST_TEST_EQ(node_comparison(nodes[i], node), !res[i]); \
+ }
+
+#define CHECK_CIRCLE(circle, c_x, c_y, l_x) \
+ BOOST_TEST_EQ(ulp_cmp(c1.x(), c_x, 10), ulp_comparison<double>::EQUAL); \
+ BOOST_TEST_EQ(ulp_cmp(c1.y(), c_y, 10), ulp_comparison<double>::EQUAL); \
+ BOOST_TEST_EQ(ulp_cmp(c1.lower_x(), l_x, 10), ulp_comparison<double>::EQUAL)
+
+#define CHECK_CIRCLE_EXISTENCE(s1, s2, s3, RES) \
+ { circle_type c1; \
+ BOOST_TEST_EQ(lazy_predicate(s1, s2, s3, c1), RES); }
+
+#define CHECK_CIRCLE_FORMATION_PREDICATE(s1, s2, s3, c_x, c_y, l_x) \
+ { circle_type c1, c2; \
+ BOOST_TEST_EQ(mp_predicate(s1, s2, s3, c1), true); \
+ BOOST_TEST_EQ(lazy_predicate(s1, s2, s3, c2), true); \
+ CHECK_CIRCLE(c1, c_x, c_y, l_x); \
+ CHECK_CIRCLE(c2, c_x, c_y, l_x); }
+
+void orientation_test()
+{
+ int min_int = (std::numeric_limits<int>::min)();
+ int max_int = (std::numeric_limits<int>::max)();
+ point_type point1(min_int, min_int);
+ point_type point2(0, 0);
+ point_type point3(max_int, max_int);
+ point_type point4(min_int, max_int);
+ point_type point5(max_int-1, max_int);
+ CHECK_ORIENTATION(point1, point2, point3, VP::ot::COLLINEAR, VP::ot::COLLINEAR);
+ CHECK_ORIENTATION(point1, point4, point3, VP::ot::RIGHT, VP::ot::LEFT);
+ CHECK_ORIENTATION(point1, point5, point3, VP::ot::RIGHT, VP::ot::LEFT);
+}
+
+void event_comparison_test1()
+{
+ site_type site(1, 2);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 2), false, true);
+ CHECK_EVENT_COMPARISON(site, site_type(1, 3), true, false);
+ CHECK_EVENT_COMPARISON(site, site_type(1, 2), false, false);
+}
+
+void event_comparison_test2()
+{
+ site_type site(0, 0, 0, 2);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 2), true, false);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 0), false, true);
+ CHECK_EVENT_COMPARISON(site, site_type(0, -2, 0, -1), false, true);
+ CHECK_EVENT_COMPARISON(site, site_type(0, -2, 1, 1), true, false);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 0, 1, 1), true, false);
+}
+
+void event_comparison_test3()
+{
+ site_type site(0, 0, 10, 10);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 0), false, true);
+ CHECK_EVENT_COMPARISON(site, site_type(0, -1), false, true);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 1), false, true);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 1, 0, 10), false, true);
+ CHECK_EVENT_COMPARISON(site, site_type(0, -10, 0, -1), false, true);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 0, 10, 9), true, false);
+ CHECK_EVENT_COMPARISON(site, site_type(0, 0, 9, 10), false, true);
+}
+
+void event_comparison_test4()
+{
+ circle_type circle(1, 2, 3);
+ CHECK_EVENT_COMPARISON(circle, circle_type(1, 2, 3), false, false);
+ CHECK_EVENT_COMPARISON(circle, circle_type(1, 3, 3), true, false);
+ CHECK_EVENT_COMPARISON(circle, circle_type(1, 2, 4), true, false);
+ CHECK_EVENT_COMPARISON(circle, circle_type(0, 2, 2), false, true);
+ CHECK_EVENT_COMPARISON(circle, circle_type(-1, 2, 3), false, false);
+}
+
+void event_comparison_test5()
+{
+ circle_type circle(1, 2, 3);
+ CHECK_EVENT_COMPARISON(circle, site_type(0, 100), false, true);
+ CHECK_EVENT_COMPARISON(circle, site_type(3, 0), false, false);
+ CHECK_EVENT_COMPARISON(circle, site_type(3, 2), false, false);
+ CHECK_EVENT_COMPARISON(circle, site_type(3, 3), false, false);
+ CHECK_EVENT_COMPARISON(circle, site_type(4, 2), true, false);
+}
+
+void distance_predicate_test1()
+{
+ site_type site1(-5, 0);
+ site1.sorted_index(1);
+ site_type site2(-8, 9);
+ site2.sorted_index(0);
+ site_type site3(-2, 1);
+ site3.sorted_index(2);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 5), false);
+ CHECK_DISTANCE_PREDICATE(site3, site1, point_type(0, 5), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 4), false);
+ CHECK_DISTANCE_PREDICATE(site3, site1, point_type(0, 4), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 6), true);
+ CHECK_DISTANCE_PREDICATE(site3, site1, point_type(0, 6), true);
+}
+
+void distance_predicate_test2()
+{
+ site_type site1(-4, 0, -4, 20);
+ site1.sorted_index(0);
+ site_type site2(-2, 10);
+ site2.sorted_index(1);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, 11), false);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, 9), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 11), true);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 9), true);
+}
+
+void distance_predicate_test3()
+{
+ site_type site1(-5, 5, 2, -2);
+ site1.sorted_index(0);
+ site1.inverse();
+ site_type site2(-2, 4);
+ site2.sorted_index(1);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, -1), false);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, -1), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 1), false);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, 1), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 4), true);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, 4), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 5), true);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, 5), false);
+}
+
+void distance_predicate_test4()
+{
+ site_type site1(-5, 5, 2, -2);
+ site1.sorted_index(0);
+ site_type site2(-2, -4);
+ site2.sorted_index(2);
+ site_type site3(-4, 1);
+ site3.sorted_index(1);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, 1), true);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, 1), true);
+ CHECK_DISTANCE_PREDICATE(site1, site3, point_type(0, 1), true);
+ CHECK_DISTANCE_PREDICATE(site3, site1, point_type(0, 1), true);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, -2), true);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, -2), false);
+ CHECK_DISTANCE_PREDICATE(site1, site3, point_type(0, -2), true);
+ CHECK_DISTANCE_PREDICATE(site3, site1, point_type(0, -2), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, -8), true);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, -8), false);
+ CHECK_DISTANCE_PREDICATE(site1, site3, point_type(0, -8), true);
+ CHECK_DISTANCE_PREDICATE(site3, site1, point_type(0, -8), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(0, -9), true);
+ CHECK_DISTANCE_PREDICATE(site2, site1, point_type(0, -9), false);
+ CHECK_DISTANCE_PREDICATE(site1, site3, point_type(0, -9), true);
+ CHECK_DISTANCE_PREDICATE(site3, site1, point_type(0, -9), false);
+}
+
+void distance_predicate_test5()
+{
+ site_type site1(-5, 5, 2, -2);
+ site1.sorted_index(0);
+ site_type site2 = site1;
+ site2.inverse();
+ site_type site3(-2, 4);
+ site3.sorted_index(3);
+ site_type site4(-2, -4);
+ site4.sorted_index(2);
+ site_type site5(-4, 1);
+ site5.sorted_index(1);
+ CHECK_DISTANCE_PREDICATE(site3, site2, point_type(0, 1), false);
+ CHECK_DISTANCE_PREDICATE(site3, site2, point_type(0, 4), false);
+ CHECK_DISTANCE_PREDICATE(site3, site2, point_type(0, 5), false);
+ CHECK_DISTANCE_PREDICATE(site3, site2, point_type(0, 7), true);
+ CHECK_DISTANCE_PREDICATE(site4, site1, point_type(0, -2), false);
+ CHECK_DISTANCE_PREDICATE(site5, site1, point_type(0, -2), false);
+ CHECK_DISTANCE_PREDICATE(site4, site1, point_type(0, -8), false);
+ CHECK_DISTANCE_PREDICATE(site5, site1, point_type(0, -8), false);
+ CHECK_DISTANCE_PREDICATE(site4, site1, point_type(0, -9), false);
+ CHECK_DISTANCE_PREDICATE(site5, site1, point_type(0, -9), false);
+ CHECK_DISTANCE_PREDICATE(site4, site1, point_type(0, -18), false);
+ CHECK_DISTANCE_PREDICATE(site5, site1, point_type(0, -18), false);
+ CHECK_DISTANCE_PREDICATE(site4, site1, point_type(0, -1), true);
+ CHECK_DISTANCE_PREDICATE(site5, site1, point_type(0, -1), true);
+}
+
+void distance_predicate_test6()
+{
+ site_type site1(-5, 0, 2, 7);
+ site_type site2 = site1;
+ site2.inverse();
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(2, 7), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(1, 5), false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(-1, 5), true);
+}
+
+void distance_predicate_test7()
+{
+ site_type site1(-5, 5, 2, -2);
+ site1.sorted_index(1);
+ site1.inverse();
+ site_type site2(-5, 5, 0, 6);
+ site2.sorted_index(0);
+ site_type site3(-2, 4, 0, 4);
+ site3.sorted_index(2);
+ point_type site4(0, 2);
+ point_type site5(0, 5);
+ point_type site6(0, 6);
+ point_type site7(0, 8);
+ CHECK_DISTANCE_PREDICATE(site1, site2, site4, false);
+ CHECK_DISTANCE_PREDICATE(site1, site2, site5, true);
+ CHECK_DISTANCE_PREDICATE(site1, site2, site6, true);
+ CHECK_DISTANCE_PREDICATE(site1, site2, site7, true);
+ CHECK_DISTANCE_PREDICATE(site1, site3, site4, false);
+ CHECK_DISTANCE_PREDICATE(site1, site3, site5, true);
+ CHECK_DISTANCE_PREDICATE(site1, site3, site6, true);
+ CHECK_DISTANCE_PREDICATE(site1, site3, site7, true);
+ site3.inverse();
+ CHECK_DISTANCE_PREDICATE(site3, site1, site4, false);
+ CHECK_DISTANCE_PREDICATE(site3, site1, site5, false);
+ CHECK_DISTANCE_PREDICATE(site3, site1, site6, false);
+ CHECK_DISTANCE_PREDICATE(site3, site1, site7, true);
+}
+
+void distance_predicate_test8()
+{
+ site_type site1(-5, 3, -2, 2);
+ site1.sorted_index(0);
+ site1.inverse();
+ site_type site2(-5, 5, -2, 2);
+ site2.sorted_index(1);
+ CHECK_DISTANCE_PREDICATE(site1, site2, point_type(-4, 2), false);
+}
+
+void node_comparison_test1()
+{
+ beach_line_type beach_line;
+ site_type site1(0, 0);
+ site1.sorted_index(0);
+ site_type site2(0, 2);
+ site2.sorted_index(1);
+ site_type site3(1, 0);
+ site3.sorted_index(2);
+ beach_line[key_type(site1, site2)] = 2;
+ beach_line[key_type(site1, site3)] = 0;
+ beach_line[key_type(site3, site1)] = 1;
+ int cur_index = 0;
+ for (bieach_line_iterator it = beach_line.begin();
+ it != beach_line.end(); ++it, ++cur_index) {
+ BOOST_TEST_EQ(it->second, cur_index);
+ }
+}
+
+void node_comparison_test2()
+{
+ beach_line_type beach_line;
+ site_type site1(0, 1);
+ site1.sorted_index(0);
+ site_type site2(2, 0);
+ site2.sorted_index(1);
+ site_type site3(2, 4);
+ site3.sorted_index(2);
+ beach_line[key_type(site1, site2)] = 0;
+ beach_line[key_type(site2, site1)] = 1;
+ beach_line[key_type(site1, site3)] = 2;
+ beach_line[key_type(site3, site1)] = 3;
+ int cur_index = 0;
+ for (bieach_line_iterator it = beach_line.begin();
+ it != beach_line.end(); ++it, ++cur_index) {
+ BOOST_TEST_EQ(it->second, cur_index);
+ }
+}
+
+void node_comparison_test3()
+{
+ key_type node(site_type(1, 0).sorted_index(1), site_type(0, 2).sorted_index(0));
+ key_type nodes[] = {
+ key_type(site_type(2, -10).sorted_index(2)),
+ key_type(site_type(2, -1).sorted_index(2)),
+ key_type(site_type(2, 0).sorted_index(2)),
+ key_type(site_type(2, 1).sorted_index(2)),
+ key_type(site_type(2, 2).sorted_index(2)),
+ key_type(site_type(2, 3).sorted_index(2)),
+ };
+ bool res[] = {false, false, false, false, true, true};
+ CHECK_NODE_COMPARISON(node, nodes, res, 6);
+}
+
+void node_comparison_test4()
+{
+ key_type node(site_type(0, 1).sorted_index(0), site_type(1, 0).sorted_index(1));
+ key_type nodes[] = {
+ key_type(site_type(2, -3).sorted_index(2)),
+ key_type(site_type(2, -2).sorted_index(2)),
+ key_type(site_type(2, -1).sorted_index(2)),
+ key_type(site_type(2, 0).sorted_index(2)),
+ key_type(site_type(2, 1).sorted_index(2)),
+ key_type(site_type(2, 3).sorted_index(2)),
+ };
+ bool res[] = {false, true, true, true, true, true};
+ CHECK_NODE_COMPARISON(node, nodes, res, 6);
+}
+
+void node_comparison_test5()
+{
+ key_type node(site_type(0, 0).sorted_index(0), site_type(1, 2).sorted_index(1));
+ key_type nodes[] = {
+ key_type(site_type(2, -10).sorted_index(2)),
+ key_type(site_type(2, 0).sorted_index(2)),
+ key_type(site_type(2, 1).sorted_index(2)),
+ key_type(site_type(2, 2).sorted_index(2)),
+ key_type(site_type(2, 5).sorted_index(2)),
+ key_type(site_type(2, 20).sorted_index(2)),
+ };
+ bool res[] = {false, false, true, true, true, true};
+ CHECK_NODE_COMPARISON(node, nodes, res, 6);
+}
+
+void node_comparison_test6()
+{
+ key_type node(site_type(1, 1).sorted_index(1), site_type(0, 0).sorted_index(0));
+ key_type nodes[] = {
+ key_type(site_type(2, -3).sorted_index(2)),
+ key_type(site_type(2, -2).sorted_index(2)),
+ key_type(site_type(2, 0).sorted_index(2)),
+ key_type(site_type(2, 1).sorted_index(2)),
+ key_type(site_type(2, 2).sorted_index(2)),
+ key_type(site_type(2, 3).sorted_index(2)),
+ key_type(site_type(2, 5).sorted_index(2)),
+ };
+ bool res[] = {false, false, false, false, false, false, true};
+ CHECK_NODE_COMPARISON(node, nodes, res, 7);
+}
+
+void node_comparison_test7()
+{
+ key_type node(site_type(0, 0).sorted_index(0), site_type(0, 2).sorted_index(1));
+ key_type nodes[] = {
+ key_type(site_type(1, 0).sorted_index(2)),
+ key_type(site_type(1, 1).sorted_index(2)),
+ key_type(site_type(1, 2).sorted_index(2)),
+ };
+ bool res[] = {false, false, true};
+ CHECK_NODE_COMPARISON(node, nodes, res, 3);
+}
+
+void node_comparison_test8()
+{
+ key_type node(site_type(0, 0).sorted_index(0), site_type(1, 1).sorted_index(2));
+ key_type nodes[] = {
+ key_type(site_type(1, 0).sorted_index(1)),
+ key_type(site_type(1, 1).sorted_index(2)),
+ key_type(site_type(1, 2).sorted_index(3)),
+ key_type(site_type(1, 1).sorted_index(2), site_type(0, 0).sorted_index(0)),
+ };
+ bool res[] = {false, true, true, true};
+ CHECK_NODE_COMPARISON(node, nodes, res, 4);
+}
+
+void circle_formation_predicate_test1()
+{
+ site_type site1(0, 0);
+ site1.sorted_index(1);
+ site_type site2(-8, 0);
+ site2.sorted_index(0);
+ site_type site3(0, 6);
+ site3.sorted_index(2);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, -4.0, 3.0, 1.0);
+}
+
+void circle_formation_predicate_test2()
+{
+ int min_int = (std::numeric_limits<int>::min)();
+ int max_int = (std::numeric_limits<int>::max)();
+ site_type site1(min_int, min_int);
+ site1.sorted_index(0);
+ site_type site2(min_int, max_int);
+ site2.sorted_index(1);
+ site_type site3(max_int-1, max_int-1);
+ site3.sorted_index(2);
+ site_type site4(max_int, max_int);
+ site4.sorted_index(3);
+ CHECK_CIRCLE_EXISTENCE(site1, site2, site4, true);
+ CHECK_CIRCLE_EXISTENCE(site1, site3, site4, false);
+}
+
+void circle_formation_predicate_test3()
+{
+ site_type site1(-4, 0);
+ site1.sorted_index(0);
+ site_type site2(0, 4);
+ site2.sorted_index(4);
+ site_type site3(site1.point0(), site2.point0());
+ site3.sorted_index(1);
+ CHECK_CIRCLE_EXISTENCE(site1, site3, site2, false);
+ site_type site4(-2, 0);
+ site4.sorted_index(2);
+ site_type site5(0, 2);
+ site5.sorted_index(3);
+ CHECK_CIRCLE_EXISTENCE(site3, site4, site5, false);
+ CHECK_CIRCLE_EXISTENCE(site4, site5, site3, false);
+}
+
+void circle_formation_predicate_test4()
+{
+ site_type site1(-4, 0, -4, 20);
+ site1.sorted_index(0);
+ site_type site2(-2, 10);
+ site2.sorted_index(1);
+ site_type site3(4, 10);
+ site3.sorted_index(2);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, 1.0, 6.0, 6.0);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site3, site2, site1, 1.0, 14.0, 6.0);
+}
+
+void circle_formation_predicate_test5()
+{
+ site_type site1(1, 0, 7, 0);
+ site1.sorted_index(2);
+ site1.inverse();
+ site_type site2(-2, 4, 10, 4);
+ site2.sorted_index(0);
+ site_type site3(6, 2);
+ site3.sorted_index(3);
+ site_type site4(1, 0);
+ site4.sorted_index(1);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site3, site1, site2, 4.0, 2.0, 6.0);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site4, site2, site1, 1.0, 2.0, 3.0);
+}
+
+void circle_formation_predicate_test6()
+{
+ site_type site1(-1, 2, 8, -10);
+ site1.sorted_index(1);
+ site1.inverse();
+ site_type site2(-1, 0, 8, 12);
+ site2.sorted_index(0);
+ site_type site3(1, 1);
+ site3.sorted_index(2);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site3, site2, site1, 6.0, 1.0, 11.0);
+}
+
+void circle_formation_predicate_test7()
+{
+ site_type site1(1, 0, 6, 0);
+ site1.sorted_index(2);
+ site1.inverse();
+ site_type site2(-6, 4, 0, 12);
+ site2.sorted_index(0);
+ site_type site3(1, 0);
+ site3.sorted_index(1);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site3, site2, site1, 1.0, 5.0, 6.0);
+}
+
+void circle_formation_predicate_test8()
+{
+ site_type site1(1, 0, 5, 0);
+ site1.sorted_index(2);
+ site1.inverse();
+ site_type site2(0, 12, 8, 6);
+ site2.sorted_index(0);
+ site_type site3(1, 0);
+ site3.sorted_index(1);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site3, site2, site1, 1.0, 5.0, 6.0);
+}
+
+void circle_formation_predicate_test9()
+{
+ site_type site1(0, 0, 4, 0);
+ site1.sorted_index(1);
+ site_type site2(0, 0, 0, 4);
+ site2.sorted_index(0);
+ site_type site3(0, 4, 4, 4);
+ site3.sorted_index(2);
+ site1.inverse();
+ CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, 2.0, 2.0, 4.0);
+}
+
+void circle_formation_predicate_test10()
+{
+ site_type site1(1, 0, 41, 30);
+ site1.sorted_index(1);
+ site_type site2(-39, 30, 1, 60);
+ site2.sorted_index(0);
+ site_type site3(1, 60, 41, 30);
+ site3.sorted_index(2);
+ site1.inverse();
+ CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, 1.0, 30.0, 25.0);
+}
+
+void circle_formation_predicate_test11()
+{
+ site_type site1(0, 0, 0, 10);
+ site1.sorted_index(2);
+ site1.inverse();
+ site_type site2(-8, 10);
+ site2.sorted_index(0);
+ site_type site3(-7, 14, -1, 14);
+ site3.sorted_index(1);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, -4.0, 10.0, 0.0);
+}
+
+void circle_formation_predicate_test12()
+{
+ site_type site1(0, 0, 0, 10);
+ site1.sorted_index(2);
+ site1.inverse();
+ site_type site2(-8, 10);
+ site2.sorted_index(0);
+ site_type site3(-7, 15, -1, 15);
+ site3.sorted_index(1);
+ CHECK_CIRCLE_EXISTENCE(site1, site2, site3, false);
+}
+
+void circle_formation_predicate_test13()
+{
+ site_type site1(0, 0, 0, 10);
+ site1.sorted_index(2);
+ site1.inverse();
+ site_type site2(-7, -4, -1, -4);
+ site2.sorted_index(1);
+ site2.inverse();
+ site_type site3(-8, 0);
+ site3.sorted_index(0);
+ CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, -4.0, 0.0, 0.0);
+}
+
+void circle_formation_predicate_test14()
+{
+ site_type site1(0, 0, 0, 10);
+ site1.sorted_index(2);
+ site1.inverse();
+ site_type site2(-7, -5, -1, -5);
+ site2.sorted_index(1);
+ site2.inverse();
+ site_type site3(-8, 0);
+ site3.sorted_index(0);
+ CHECK_CIRCLE_EXISTENCE(site1, site2, site3, false);
+}
+
+int main()
+{
+ orientation_test();
+ event_comparison_test1();
+ event_comparison_test2();
+ event_comparison_test3();
+ event_comparison_test4();
+ event_comparison_test5();
+ distance_predicate_test1();
+ distance_predicate_test2();
+ distance_predicate_test3();
+ distance_predicate_test4();
+ distance_predicate_test5();
+ distance_predicate_test6();
+ distance_predicate_test7();
+ distance_predicate_test8();
+ node_comparison_test1();
+ node_comparison_test2();
+ node_comparison_test3();
+ node_comparison_test4();
+ node_comparison_test5();
+ node_comparison_test6();
+ node_comparison_test7();
+ node_comparison_test8();
+ circle_formation_predicate_test1();
+ circle_formation_predicate_test2();
+ circle_formation_predicate_test3();
+ circle_formation_predicate_test4();
+ circle_formation_predicate_test5();
+ circle_formation_predicate_test6();
+ circle_formation_predicate_test7();
+ circle_formation_predicate_test8();
+ circle_formation_predicate_test9();
+ circle_formation_predicate_test10();
+ circle_formation_predicate_test11();
+ circle_formation_predicate_test12();
+ circle_formation_predicate_test13();
+ circle_formation_predicate_test14();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/voronoi_robust_fpt_test.cpp b/src/boost/libs/polygon/test/voronoi_robust_fpt_test.cpp
new file mode 100644
index 000000000..918530691
--- /dev/null
+++ b/src/boost/libs/polygon/test/voronoi_robust_fpt_test.cpp
@@ -0,0 +1,405 @@
+// Boost.Polygon library voronoi_robust_fpt_test.cpp file
+
+// Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/detail/voronoi_ctypes.hpp>
+#include <boost/polygon/detail/voronoi_robust_fpt.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <vector>
+#include <cmath>
+#include <ctime>
+
+using boost::polygon::detail::int32;
+using boost::polygon::detail::uint32;
+using boost::polygon::detail::int64;
+using boost::polygon::detail::fpt64;
+using boost::polygon::detail::efpt64;
+using boost::polygon::detail::extended_int;
+using boost::polygon::detail::extended_exponent_fpt;
+using boost::polygon::detail::robust_fpt;
+using boost::polygon::detail::robust_dif;
+using boost::polygon::detail::robust_sqrt_expr;
+using boost::polygon::detail::type_converter_fpt;
+using boost::polygon::detail::type_converter_efpt;
+using boost::polygon::detail::ulp_comparison;
+
+typedef robust_fpt<double> rfpt_type;
+typedef type_converter_fpt to_fpt_type;
+typedef type_converter_efpt to_efpt_type;
+type_converter_fpt to_fpt;
+
+void robust_fpt_constructors_test1()
+{
+ rfpt_type a = rfpt_type();
+ BOOST_TEST_EQ(a.fpv(), 0.0);
+ BOOST_TEST_EQ(a.re(), 0.0);
+ BOOST_TEST_EQ(a.ulp(), 0);
+}
+
+void robust_fpt_constructors_test2()
+{
+ rfpt_type a(10.0, 1.0);
+ BOOST_TEST_EQ(a.fpv(), 10.0);
+ BOOST_TEST_EQ(a.re(), 1.0);
+ BOOST_TEST_EQ(a.ulp(), 1.0);
+}
+
+void robust_fpt_constructors_test3()
+{
+ rfpt_type a(10.0);
+ BOOST_TEST_EQ(a.fpv(), 10.0);
+ BOOST_TEST_EQ(a.re(), 0.0);
+ BOOST_TEST_EQ(a.ulp(), 0.0);
+}
+
+void robust_fpt_constructors_test4()
+{
+ rfpt_type a(10.0, 3.0);
+ BOOST_TEST_EQ(a.fpv(), 10.0);
+ BOOST_TEST_EQ(a.re(), 3.0);
+ BOOST_TEST_EQ(a.ulp(), 3.0);
+
+ rfpt_type b(10.0, 2.75);
+ BOOST_TEST_EQ(b.fpv(), 10.0);
+ BOOST_TEST_EQ(b.re(), 2.75);
+ BOOST_TEST_EQ(b.ulp(), 2.75);
+}
+
+void robust_fpt_sum_test1()
+{
+ rfpt_type a(2.0, 5.0);
+ rfpt_type b(3.0, 4.0);
+ rfpt_type c = a + b;
+ BOOST_TEST_EQ(c.fpv(), 5.0);
+ BOOST_TEST_EQ(c.re(), 6.0);
+ BOOST_TEST_EQ(c.ulp(), 6.0);
+
+ c += b;
+ BOOST_TEST_EQ(c.fpv(), 8.0);
+ BOOST_TEST_EQ(c.re(), 7.0);
+ BOOST_TEST_EQ(c.ulp(), 7.0);
+}
+
+void robust_fpt_sum_test2()
+{
+ rfpt_type a(3.0, 2.0);
+ rfpt_type b(-2.0, 3.0);
+ rfpt_type c = a + b;
+ BOOST_TEST_EQ(c.fpv(), 1.0);
+ BOOST_TEST_EQ(c.re(), 13.0);
+ BOOST_TEST_EQ(c.ulp(), 13.0);
+
+ c += b;
+ BOOST_TEST_EQ(c.fpv(), -1.0);
+ BOOST_TEST_EQ(c.re(), 20.0);
+ BOOST_TEST_EQ(c.ulp(), 20.0);
+}
+
+void robust_fpt_dif_test1()
+{
+ rfpt_type a(2.0, 5.0);
+ rfpt_type b(-3.0, 4.0);
+ rfpt_type c = a - b;
+ BOOST_TEST_EQ(c.fpv(), 5.0);
+ BOOST_TEST_EQ(c.re(), 6.0);
+ BOOST_TEST_EQ(c.ulp(), 6.0);
+
+ c -= b;
+ BOOST_TEST_EQ(c.fpv(), 8.0);
+ BOOST_TEST_EQ(c.re(), 7.0);
+ BOOST_TEST_EQ(c.ulp(), 7.0);
+}
+
+void robust_fpt_dif_test2()
+{
+ rfpt_type a(3.0, 2.0);
+ rfpt_type b(2.0, 3.0);
+ rfpt_type c = a - b;
+ BOOST_TEST_EQ(c.fpv(), 1.0);
+ BOOST_TEST_EQ(c.re(), 13.0);
+ BOOST_TEST_EQ(c.ulp(), 13.0);
+
+ c -= b;
+ BOOST_TEST_EQ(c.fpv(), -1.0);
+ BOOST_TEST_EQ(c.re(), 20.0);
+ BOOST_TEST_EQ(c.ulp(), 20.0);
+}
+
+void robust_fpt_mult_test3()
+{
+ rfpt_type a(2.0, 3.0);
+ rfpt_type b(4.0, 1.0);
+ rfpt_type c = a * b;
+ BOOST_TEST_EQ(c.fpv(), 8.0);
+ BOOST_TEST_EQ(c.re(), 5.0);
+ BOOST_TEST_EQ(c.ulp(), 5.0);
+
+ c *= b;
+ BOOST_TEST_EQ(c.fpv(), 32.0);
+ BOOST_TEST_EQ(c.re(), 7.0);
+ BOOST_TEST_EQ(c.ulp(), 7.0);
+}
+
+void robust_fpt_div_test1()
+{
+ rfpt_type a(2.0, 3.0);
+ rfpt_type b(4.0, 1.0);
+ rfpt_type c = a / b;
+ BOOST_TEST_EQ(c.fpv(), 0.5);
+ BOOST_TEST_EQ(c.re(), 5.0);
+ BOOST_TEST_EQ(c.ulp(), 5.0);
+
+ c /= b;
+ BOOST_TEST_EQ(c.fpv(), 0.125);
+ BOOST_TEST_EQ(c.re(), 7.0);
+ BOOST_TEST_EQ(c.ulp(), 7.0);
+}
+
+void robust_dif_constructors_test()
+{
+ robust_dif<int> rd1;
+ BOOST_TEST_EQ(rd1.pos(), 0);
+ BOOST_TEST_EQ(rd1.neg(), 0);
+ BOOST_TEST_EQ(rd1.dif(), 0);
+
+ robust_dif<int> rd2(1);
+ BOOST_TEST_EQ(rd2.pos(), 1);
+ BOOST_TEST_EQ(rd2.neg(), 0);
+ BOOST_TEST_EQ(rd2.dif(), 1);
+
+ robust_dif<int> rd3(-1);
+ BOOST_TEST_EQ(rd3.pos(), 0);
+ BOOST_TEST_EQ(rd3.neg(), 1);
+ BOOST_TEST_EQ(rd3.dif(), -1);
+
+ robust_dif<int> rd4(1, 2);
+ BOOST_TEST_EQ(rd4.pos(), 1);
+ BOOST_TEST_EQ(rd4.neg(), 2);
+ BOOST_TEST_EQ(rd4.dif(), -1);
+}
+
+void robust_dif_operators_test1()
+{
+ robust_dif<int> a(5, 2), b(1, 10);
+ int dif_a = a.dif();
+ int dif_b = b.dif();
+ robust_dif<int> sum = a + b;
+ robust_dif<int> dif = a - b;
+ robust_dif<int> mult = a * b;
+ robust_dif<int> umin = -a;
+ BOOST_TEST_EQ(sum.dif(), dif_a + dif_b);
+ BOOST_TEST_EQ(dif.dif(), dif_a - dif_b);
+ BOOST_TEST_EQ(mult.dif(), dif_a * dif_b);
+ BOOST_TEST_EQ(umin.dif(), -dif_a);
+}
+
+void robust_dif_operators_test2()
+{
+ robust_dif<int> a(5, 2);
+ for (int b = -3; b <= 3; b += 6) {
+ int dif_a = a.dif();
+ int dif_b = b;
+ robust_dif<int> sum = a + b;
+ robust_dif<int> dif = a - b;
+ robust_dif<int> mult = a * b;
+ robust_dif<int> div = a / b;
+ BOOST_TEST_EQ(sum.dif(), dif_a + dif_b);
+ BOOST_TEST_EQ(dif.dif(), dif_a - dif_b);
+ BOOST_TEST_EQ(mult.dif(), dif_a * dif_b);
+ BOOST_TEST_EQ(div.dif(), dif_a / dif_b);
+ }
+}
+
+void robust_dif_operators_test3()
+{
+ robust_dif<int> b(5, 2);
+ for (int a = -3; a <= 3; a += 6) {
+ int dif_a = a;
+ int dif_b = b.dif();
+ robust_dif<int> sum = a + b;
+ robust_dif<int> dif = a - b;
+ robust_dif<int> mult = a * b;
+ BOOST_TEST_EQ(sum.dif(), dif_a + dif_b);
+ BOOST_TEST_EQ(dif.dif(), dif_a - dif_b);
+ BOOST_TEST_EQ(mult.dif(), dif_a * dif_b);
+ }
+}
+
+void robust_dif_operators_test4()
+{
+ std::vector< robust_dif<int> > a4(4, robust_dif<int>(5, 2));
+ std::vector< robust_dif<int> > b4(4, robust_dif<int>(1, 2));
+ std::vector< robust_dif<int> > c4 = a4;
+ c4[0] += b4[0];
+ c4[1] -= b4[1];
+ c4[2] *= b4[2];
+ BOOST_TEST_EQ(c4[0].dif(), a4[0].dif() + b4[0].dif());
+ BOOST_TEST_EQ(c4[1].dif(), a4[1].dif() - b4[1].dif());
+ BOOST_TEST_EQ(c4[2].dif(), a4[2].dif() * b4[2].dif());
+ a4[0] += b4[0].dif();
+ a4[1] -= b4[1].dif();
+ a4[2] *= b4[2].dif();
+ a4[3] /= b4[3].dif();
+ BOOST_TEST_EQ(c4[0].dif(), a4[0].dif());
+ BOOST_TEST_EQ(c4[1].dif(), a4[1].dif());
+ BOOST_TEST_EQ(c4[2].dif(), a4[2].dif());
+ BOOST_TEST_EQ(c4[3].dif() / b4[3].dif(), a4[3].dif());
+}
+
+void robust_sqrt_expr_test1()
+{
+ robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+ int32 A[1] = {10};
+ int32 B[1] = {100};
+ BOOST_TEST_EQ(sqrt_expr.eval1(A, B), 100.0);
+}
+
+void robust_sqrt_expr_test2()
+{
+ robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+ int32 A[2] = {10, 30};
+ int32 B[2] = {400, 100};
+ BOOST_TEST_EQ(sqrt_expr.eval2(A, B), 500.0);
+}
+
+void robust_sqrt_expr_test3()
+{
+ robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+ int32 A[2] = {10, -30};
+ int32 B[2] = {400, 100};
+ BOOST_TEST_EQ(sqrt_expr.eval2(A, B), -100.0);
+}
+
+void robust_sqrt_expr_test4()
+{
+ robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+ int32 A[3] = {10, 30, 20};
+ int32 B[3] = {4, 1, 9};
+ BOOST_TEST_EQ(sqrt_expr.eval3(A, B), 110.0);
+}
+
+void robust_sqrt_expr_test5()
+{
+ robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+ int32 A[3] = {10, 30, -20};
+ int32 B[3] = {4, 1, 9};
+ BOOST_TEST_EQ(sqrt_expr.eval3(A, B), -10.0);
+}
+
+void robust_sqrt_expr_test6()
+{
+ robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+ int32 A[4] = {10, 30, 20, 5};
+ int32 B[4] = {4, 1, 9, 16};
+ BOOST_TEST_EQ(sqrt_expr.eval4(A, B), 130.0);
+}
+
+void robust_sqrt_expr_test7()
+{
+ robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+ int32 A[4] = {10, 30, -20, -5};
+ int32 B[4] = {4, 1, 9, 16};
+ BOOST_TEST_EQ(sqrt_expr.eval4(A, B), -30.0);
+}
+
+void robust_sqrt_expr_test8()
+{
+ typedef extended_int<16> eint512;
+ robust_sqrt_expr<eint512, efpt64, to_efpt_type> sqrt_expr;
+ int32 A[4] = {1000, 3000, -2000, -500};
+ int32 B[4] = {400, 100, 900, 1600};
+ eint512 AA[4], BB[4];
+ for (std::size_t i = 0; i < 4; ++i) {
+ AA[i] = A[i];
+ BB[i] = B[i];
+ }
+ BOOST_TEST_EQ(to_fpt(sqrt_expr.eval4(AA, BB)), -30000.0);
+}
+
+template <typename _int, typename _fpt>
+class sqrt_expr_tester {
+ public:
+ static const std::size_t MX_SQRTS = 4;
+
+ bool run() {
+ static boost::mt19937 gen(static_cast<uint32>(time(NULL)));
+ bool ret_val = true;
+ for (std::size_t i = 0; i < MX_SQRTS; ++i) {
+ a[i] = gen() & 1048575;
+ int64 temp = gen() & 1048575;
+ b[i] = temp * temp;
+ }
+ uint32 mask = (1 << MX_SQRTS);
+ for (std::size_t i = 0; i < mask; i++) {
+ fpt64 expected_val = 0.0;
+ for (std::size_t j = 0; j < MX_SQRTS; j++) {
+ if (i & (1 << j)) {
+ A[j] = a[j];
+ B[j] = b[j];
+ expected_val += static_cast<fpt64>(a[j]) *
+ std::sqrt(static_cast<fpt64>(b[j]));
+ } else {
+ A[j] = -a[j];
+ B[j] = b[j];
+ expected_val -= static_cast<fpt64>(a[j]) *
+ std::sqrt(static_cast<fpt64>(b[j]));
+ }
+ }
+ fpt64 received_val = to_fpt(sqrt_expr_.eval4(A, B));
+ ret_val &= ulp_cmp(expected_val, received_val, 25) ==
+ ulp_comparison<fpt64>::EQUAL;
+ }
+ return ret_val;
+ }
+
+ private:
+ robust_sqrt_expr<_int, _fpt, to_efpt_type> sqrt_expr_;
+ ulp_comparison<fpt64> ulp_cmp;
+ _int A[MX_SQRTS];
+ _int B[MX_SQRTS];
+ int64 a[MX_SQRTS];
+ int64 b[MX_SQRTS];
+};
+
+void mpz_sqrt_evaluator_test()
+{
+ typedef extended_int<16> eint512;
+ sqrt_expr_tester<eint512, efpt64> tester;
+ for (int i = 0; i < 2000; ++i)
+ BOOST_TEST(tester.run());
+}
+
+int main()
+{
+ robust_fpt_constructors_test1();
+ robust_fpt_constructors_test2();
+ robust_fpt_constructors_test3();
+ robust_fpt_constructors_test4();
+ robust_fpt_sum_test1();
+ robust_fpt_sum_test2();
+ robust_fpt_dif_test1();
+ robust_fpt_dif_test2();
+ robust_fpt_mult_test3();
+ robust_fpt_div_test1();
+ robust_dif_constructors_test();
+ robust_dif_operators_test1();
+ robust_dif_operators_test2();
+ robust_dif_operators_test3();
+ robust_dif_operators_test4();
+ robust_sqrt_expr_test1();
+ robust_sqrt_expr_test2();
+ robust_sqrt_expr_test3();
+ robust_sqrt_expr_test4();
+ robust_sqrt_expr_test5();
+ robust_sqrt_expr_test6();
+ robust_sqrt_expr_test7();
+ robust_sqrt_expr_test8();
+ mpz_sqrt_evaluator_test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/voronoi_structures_test.cpp b/src/boost/libs/polygon/test/voronoi_structures_test.cpp
new file mode 100644
index 000000000..1693c317e
--- /dev/null
+++ b/src/boost/libs/polygon/test/voronoi_structures_test.cpp
@@ -0,0 +1,150 @@
+// Boost.Polygon library voronoi_structures_test.cpp file
+
+// Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/polygon/detail/voronoi_structures.hpp>
+#include <boost/polygon/voronoi_geometry_type.hpp>
+#include <functional>
+#include <vector>
+
+using namespace boost::polygon::detail;
+using namespace boost::polygon;
+
+typedef point_2d<int> point_type;
+typedef site_event<int> site_type;
+typedef circle_event<int> circle_type;
+typedef ordered_queue<int, std::greater<int> > ordered_queue_type;
+typedef beach_line_node_key<int> node_key_type;
+typedef beach_line_node_data<int, int> node_data_type;
+
+void point_2d_test1()
+{
+ point_type p(1, 2);
+ BOOST_TEST_EQ(1, p.x());
+ BOOST_TEST_EQ(2, p.y());
+ p.x(3);
+ BOOST_TEST_EQ(3, p.x());
+ p.y(4);
+ BOOST_TEST_EQ(4, p.y());
+}
+
+void site_event_test1()
+{
+ site_type s(1, 2);
+ s.sorted_index(1);
+ s.initial_index(2);
+ s.source_category(SOURCE_CATEGORY_SEGMENT_START_POINT);
+ BOOST_TEST_EQ(1, s.x0());
+ BOOST_TEST_EQ(1, s.x1());
+ BOOST_TEST_EQ(2, s.y0());
+ BOOST_TEST_EQ(2, s.y1());
+ BOOST_TEST(s.is_point());
+ BOOST_TEST(!s.is_segment());
+ BOOST_TEST(!s.is_inverse());
+ BOOST_TEST_EQ(1, s.sorted_index());
+ BOOST_TEST_EQ(2, s.initial_index());
+ BOOST_TEST_EQ(SOURCE_CATEGORY_SEGMENT_START_POINT, s.source_category());
+}
+
+void site_event_test2()
+{
+ site_type s(1, 2, 3, 4);
+ s.sorted_index(1);
+ s.initial_index(2);
+ s.source_category(SOURCE_CATEGORY_INITIAL_SEGMENT);
+ BOOST_TEST_EQ(1, s.x0());
+ BOOST_TEST_EQ(2, s.y0());
+ BOOST_TEST_EQ(3, s.x1());
+ BOOST_TEST_EQ(4, s.y1());
+ BOOST_TEST(!s.is_point());
+ BOOST_TEST(s.is_segment());
+ BOOST_TEST(!s.is_inverse());
+ BOOST_TEST_EQ(SOURCE_CATEGORY_INITIAL_SEGMENT, s.source_category());
+
+ s.inverse();
+ BOOST_TEST_EQ(3, s.x0());
+ BOOST_TEST_EQ(4, s.y0());
+ BOOST_TEST_EQ(1, s.x1());
+ BOOST_TEST_EQ(2, s.y1());
+ BOOST_TEST(s.is_inverse());
+ BOOST_TEST_EQ(SOURCE_CATEGORY_INITIAL_SEGMENT, s.source_category());
+}
+
+void circle_event_test()
+{
+ circle_type c(0, 1, 2);
+ BOOST_TEST_EQ(0, c.x());
+ BOOST_TEST_EQ(1, c.y());
+ BOOST_TEST_EQ(2, c.lower_x());
+ BOOST_TEST_EQ(1, c.lower_y());
+ BOOST_TEST(c.is_active());
+ c.x(3);
+ c.y(4);
+ c.lower_x(5);
+ BOOST_TEST_EQ(3, c.x());
+ BOOST_TEST_EQ(4, c.y());
+ BOOST_TEST_EQ(5, c.lower_x());
+ BOOST_TEST_EQ(4, c.lower_y());
+ c.deactivate();
+ BOOST_TEST(!c.is_active());
+}
+
+void ordered_queue_test()
+{
+ ordered_queue_type q;
+ BOOST_TEST(q.empty());
+ std::vector<int*> vi;
+ for (int i = 0; i < 20; ++i)
+ vi.push_back(&q.push(i));
+ for (int i = 0; i < 20; ++i)
+ *vi[i] <<= 1;
+ BOOST_TEST(!q.empty());
+ for (int i = 0; i < 20; ++i, q.pop())
+ BOOST_TEST_EQ(i << 1, q.top());
+ BOOST_TEST(q.empty());
+}
+
+void beach_line_node_key_test()
+{
+ node_key_type key(1);
+ BOOST_TEST_EQ(1, key.left_site());
+ BOOST_TEST_EQ(1, key.right_site());
+ key.left_site(2);
+ BOOST_TEST_EQ(2, key.left_site());
+ BOOST_TEST_EQ(1, key.right_site());
+ key.right_site(3);
+ BOOST_TEST_EQ(2, key.left_site());
+ BOOST_TEST_EQ(3, key.right_site());
+}
+
+void beach_line_node_data_test()
+{
+ node_data_type node_data(NULL);
+ BOOST_TEST(node_data.edge() == NULL);
+ BOOST_TEST(node_data.circle_event() == NULL);
+ int data = 4;
+ node_data.circle_event(&data);
+ BOOST_TEST(node_data.edge() == NULL);
+ BOOST_TEST(node_data.circle_event() == &data);
+ node_data.edge(&data);
+ BOOST_TEST(node_data.edge() == &data);
+ BOOST_TEST(node_data.circle_event() == &data);
+}
+
+int main()
+{
+ point_2d_test1();
+ site_event_test1();
+ site_event_test2();
+ circle_event_test();
+ ordered_queue_test();
+ beach_line_node_key_test();
+ beach_line_node_data_test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/polygon/test/voronoi_test_helper.hpp b/src/boost/libs/polygon/test/voronoi_test_helper.hpp
new file mode 100644
index 000000000..61c4630a9
--- /dev/null
+++ b/src/boost/libs/polygon/test/voronoi_test_helper.hpp
@@ -0,0 +1,260 @@
+// Boost.Polygon library voronoi_test_helper.hpp file
+
+// Copyright Andrii Sydorchuk 2010-2011.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef VORONOI_TEST_HELPER
+#define VORONOI_TEST_HELPER
+
+#include <boost/polygon/polygon.hpp>
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <fstream>
+#include <map>
+#include <vector>
+#include <utility>
+
+using namespace boost::polygon;
+
+namespace voronoi_test_helper {
+
+enum kOrientation {
+ RIGHT = -1,
+ COLLINEAR = 0,
+ LEFT = 1
+};
+
+template <typename VERTEX>
+kOrientation get_orientation(
+ const VERTEX& v1, const VERTEX& v2, const VERTEX& v3) {
+ typename VERTEX::coordinate_type lhs = (v2.x() - v1.x()) * (v3.y() - v2.y());
+ typename VERTEX::coordinate_type rhs = (v2.y() - v1.y()) * (v3.x() - v2.x());
+ if (lhs == rhs) {
+ return COLLINEAR;
+ }
+ return (lhs < rhs) ? RIGHT : LEFT;
+}
+
+template <typename OUTPUT>
+bool verify_cell_convexity(const OUTPUT& output) {
+ typename OUTPUT::const_cell_iterator cell_it;
+ for (cell_it = output.cells().begin();
+ cell_it != output.cells().end(); cell_it++) {
+ const typename OUTPUT::edge_type* edge = cell_it->incident_edge();
+ if (edge)
+ do {
+ if (edge->next()->prev() != edge) {
+ return false;
+ }
+ if (edge->cell() != &(*cell_it)) {
+ return false;
+ }
+ if (edge->vertex1() != edge->next()->vertex0()) {
+ return false;
+ }
+ if (edge->vertex0() != NULL &&
+ edge->vertex1() != NULL &&
+ edge->next()->vertex1() != NULL) {
+ if (get_orientation(*edge->vertex0(),
+ *edge->vertex1(),
+ *edge->next()->vertex1()) != LEFT) {
+ return false;
+ }
+ }
+ edge = edge->next();
+ } while (edge != cell_it->incident_edge());
+ }
+ return true;
+}
+
+template <typename OUTPUT>
+bool verify_incident_edges_ccw_order(const OUTPUT& output) {
+ typedef typename OUTPUT::edge_type voronoi_edge_type;
+ typename OUTPUT::const_vertex_iterator vertex_it;
+ for (vertex_it = output.vertices().begin();
+ vertex_it != output.vertices().end(); vertex_it++) {
+ if (vertex_it->is_degenerate())
+ continue;
+ const voronoi_edge_type* edge = vertex_it->incident_edge();
+ do {
+ const voronoi_edge_type* next_edge = edge->rot_next();
+ if (edge->vertex0() != next_edge->vertex0()) {
+ return false;
+ }
+ if (edge->vertex1() != NULL && next_edge->vertex1() != NULL &&
+ get_orientation(*edge->vertex1(),
+ *edge->vertex0(),
+ *next_edge->vertex1()) == LEFT) {
+ return false;
+ }
+ edge = edge->rot_next();
+ } while (edge != vertex_it->incident_edge());
+ }
+ return true;
+}
+
+template <typename VERTEX>
+struct cmp {
+ bool operator()(const VERTEX& v1, const VERTEX& v2) const {
+ if (v1.x() != v2.x())
+ return v1.x() < v2.x();
+ return v1.y() < v2.y();
+ }
+};
+
+template <typename Output>
+bool verfiy_no_line_edge_intersections(const Output &output) {
+ // Create map from edges with first point less than the second one.
+ // Key is the first point of the edge, value is a vector of second points
+ // with the same first point.
+ typedef typename Output::vertex_type vertex_type;
+ cmp<vertex_type> comparator;
+ std::map< vertex_type, std::vector<vertex_type>, cmp<vertex_type> > edge_map;
+ typename Output::const_edge_iterator edge_it;
+ for (edge_it = output.edges().begin();
+ edge_it != output.edges().end(); edge_it++) {
+ if (edge_it->is_finite()) {
+ if (comparator(*edge_it->vertex0(), *edge_it->vertex1())) {
+ edge_map[*edge_it->vertex0()].push_back(*edge_it->vertex1());
+ }
+ }
+ }
+ return !intersection_check(edge_map);
+}
+
+template <typename Point2D>
+bool intersection_check(
+ const std::map< Point2D, std::vector<Point2D>, cmp<Point2D> > &edge_map) {
+ // Iterate over map of edges and check if there are any intersections.
+ // All the edges are stored by the low x value. That's why we iterate
+ // left to right checking for intersections between all pairs of edges
+ // that overlap in the x dimension.
+ // Complexity. Approximately N*sqrt(N). Worst case N^2.
+ typedef Point2D point_type;
+ typedef typename point_type::coordinate_type coordinate_type;
+ typedef typename std::map<point_type, std::vector<point_type>, cmp<Point2D> >::const_iterator
+ edge_map_iterator;
+ typedef typename std::vector<point_type>::size_type size_type;
+ edge_map_iterator edge_map_it1, edge_map_it2, edge_map_it_bound;
+ for (edge_map_it1 = edge_map.begin();
+ edge_map_it1 != edge_map.end(); edge_map_it1++) {
+ const point_type &point1 = edge_map_it1->first;
+ for (size_type i = 0; i < edge_map_it1->second.size(); i++) {
+ const point_type &point2 = edge_map_it1->second[i];
+ coordinate_type min_y1 = (std::min)(point1.y(), point2.y());
+ coordinate_type max_y1 = (std::max)(point1.y(), point2.y());
+
+ // Find the first edge with greater or equal first point.
+ edge_map_it_bound = edge_map.lower_bound(point2);
+
+ edge_map_it2 = edge_map_it1;
+ edge_map_it2++;
+ for (; edge_map_it2 != edge_map_it_bound; edge_map_it2++) {
+ const point_type &point3 = edge_map_it2->first;
+ for (size_type j = 0; j < edge_map_it2->second.size(); j++) {
+ const point_type &point4 = edge_map_it2->second[j];
+ coordinate_type min_y2 = (std::min)(point3.y(), point4.y());
+ coordinate_type max_y2 = (std::max)(point3.y(), point4.y());
+
+ // In most cases it is enought to make
+ // simple intersection check in the y dimension.
+ if (!(max_y1 > min_y2 && max_y2 > min_y1))
+ continue;
+
+ // Intersection check.
+ if (get_orientation(point1, point2, point3) *
+ get_orientation(point1, point2, point4) == RIGHT &&
+ get_orientation(point3, point4, point1) *
+ get_orientation(point3, point4, point2) == RIGHT)
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+enum kVerification {
+ CELL_CONVEXITY = 1,
+ INCIDENT_EDGES_CCW_ORDER = 2,
+ NO_HALF_EDGE_INTERSECTIONS = 4,
+ FAST_VERIFICATION = 3,
+ COMPLETE_VERIFICATION = 7
+};
+
+template <typename Output>
+bool verify_output(const Output &output, kVerification mask) {
+ bool result = true;
+ if (mask & CELL_CONVEXITY)
+ result &= verify_cell_convexity(output);
+ if (mask & INCIDENT_EDGES_CCW_ORDER)
+ result &= verify_incident_edges_ccw_order(output);
+ if (mask & NO_HALF_EDGE_INTERSECTIONS)
+ result &= verfiy_no_line_edge_intersections(output);
+ return result;
+}
+
+template <typename PointIterator>
+void save_points(
+ PointIterator first, PointIterator last, const char* file_name) {
+ std::ofstream ofs(file_name);
+ ofs << std::distance(first, last) << std::endl;
+ for (PointIterator it = first; it != last; ++it) {
+ ofs << it->x() << " " << it->y() << std::endl;
+ }
+ ofs.close();
+}
+
+template <typename SegmentIterator>
+void save_segments(
+ SegmentIterator first, SegmentIterator last, const char* file_name) {
+ std::ofstream ofs(file_name);
+ ofs << std::distance(first, last) << std::endl;
+ for (SegmentIterator it = first; it != last; ++it) {
+ ofs << it->low().x() << " " << it->low().y() << " ";
+ ofs << it->high().x() << " " << it->high().y() << std::endl;
+ }
+ ofs.close();
+}
+
+template <typename T>
+void clean_segment_set(std::vector< segment_data<T> >& data) {
+ typedef T Unit;
+ typedef typename scanline_base<Unit>::Point Point;
+ typedef typename scanline_base<Unit>::half_edge half_edge;
+ typedef int segment_id;
+ std::vector<std::pair<half_edge, segment_id> > half_edges;
+ std::vector<std::pair<half_edge, segment_id> > half_edges_out;
+ segment_id id = 0;
+ half_edges.reserve(data.size());
+ for (typename std::vector< segment_data<T> >::iterator it = data.begin();
+ it != data.end(); ++it) {
+ Point l = it->low();
+ Point h = it->high();
+ half_edges.push_back(std::make_pair(half_edge(l, h), id++));
+ }
+ half_edges_out.reserve(half_edges.size());
+ // Apparently no need to pre-sort data when calling validate_scan.
+ line_intersection<Unit>::validate_scan(
+ half_edges_out, half_edges.begin(), half_edges.end());
+ std::vector< segment_data<T> > result;
+ result.reserve(half_edges_out.size());
+ for (std::size_t i = 0; i < half_edges_out.size(); ++i) {
+ id = half_edges_out[i].second;
+ Point l = half_edges_out[i].first.first;
+ Point h = half_edges_out[i].first.second;
+ segment_data<T> orig_seg = data[id];
+ if (orig_seg.high() < orig_seg.low())
+ std::swap(l, h);
+ result.push_back(segment_data<T>(l, h));
+ }
+ std::swap(result, data);
+}
+} // voronoi_test_helper
+
+#endif