19 #pragma warning(disable : 4512) // boost code: no assignment operator
20 #pragma warning(disable : 4244) // boost code: possible loss of data
21 #pragma warning(disable : 4127) // boost code: conditional expression is constant
22 #include <boost/geometry/geometry.hpp>
55 virtual bool Within(
Pt3d a_point)
const override;
58 std::vector<BSHP<GmPolygon>>& a_out)
const override;
59 virtual void Union(
const GmPolygon& a_, std::vector<BSHP<GmPolygon>>& a_out)
const override;
67 static double iDistanceToRing(
const GmBstRing3d& a_ring,
const Pt3d& a_pt);
76 static double iDistanceToRing(
const GmBstRing3d& a_ring,
const Pt3d& a_pt)
80 for (
size_t i = 0; i < a_ring.size(); ++i)
82 line.push_back(a_ring[i]);
84 double d = boost::geometry::distance(line, a_pt);
119 namespace bg = boost::geometry;
125 for (
size_t i = 0; i < a_outPoly.size(); ++i)
127 bg::exterior_ring(
m_poly).push_back(a_outPoly[i]);
131 for (
size_t i = 0; i < a_inPolys.size(); ++i)
134 for (
size_t j = 0; j < a_inPolys[i].size(); ++j)
136 inner.push_back(a_inPolys[i][j]);
138 bg::interior_rings(
m_poly).push_back(inner);
154 a_outPoly =
m_poly.outer();
155 for (
auto& p :
m_poly.inners())
157 a_inPolys.push_back(p);
171 namespace bg = boost::geometry;
173 if (bg::covered_by(a_point,
m_poly))
190 namespace bg = boost::geometry;
192 if (bg::within(a_point,
m_poly))
205 namespace bg = boost::geometry;
206 double d = iDistanceToRing(
m_poly.outer(), a_pt);
207 for (
size_t i = 0; i <
m_poly.inners().size(); ++i)
209 double d1 = iDistanceToRing(
m_poly.inners()[i], a_pt);
223 namespace bg = boost::geometry;
226 std::vector<GmBstPoly3d> output;
229 for (
auto& o : output)
233 for (
auto& i : o.inners())
238 gp->Setup(outPoly, inPoly);
250 namespace bg = boost::geometry;
253 std::vector<GmBstPoly3d> output;
256 for (
auto& o : output)
260 for (
auto& i : o.inners())
265 gp->Setup(outPoly, inPoly);
305 #include <boost/assign.hpp>
306 #include <boost/timer/timer.hpp>
403 xms::VecPt3d poly{{0, 0, 0}, {5, 0, 0}, {10, 0, 0}, {10, 5, 0}, {10, 10, 0}, {0, 10, 0}};
406 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, 15, 0)),
false);
407 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, 15, 0)),
false);
408 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, 15, 0)),
false);
409 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, 15, 0)),
false);
410 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, 15, 0)),
false);
411 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, 10, 0)),
false);
412 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, 10, 0)),
true);
413 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, 10, 0)),
true);
414 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, 10, 0)),
true);
415 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, 10, 0)),
false);
416 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, 5, 0)),
false);
417 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, 5, 0)),
true);
418 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, 5, 0)),
true);
419 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, 5, 0)),
true);
420 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, 5, 0)),
false);
421 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, 0, 0)),
false);
422 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, 0, 0)),
true);
423 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, 0, 0)),
true);
424 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, 0, 0)),
true);
425 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, 0, 0)),
false);
426 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, -5, 0)),
false);
427 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, -5, 0)),
false);
428 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, -5, 0)),
false);
429 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, -5, 0)),
false);
430 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, -5, 0)),
false);
432 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, 15, 0)),
false);
433 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, 15, 0)),
false);
434 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, 15, 0)),
false);
435 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, 15, 0)),
false);
436 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, 15, 0)),
false);
437 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, 10, 0)),
false);
438 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, 10, 0)),
false);
439 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, 10, 0)),
false);
440 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, 10, 0)),
false);
441 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, 10, 0)),
false);
442 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, 5, 0)),
false);
443 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, 5, 0)),
false);
444 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, 5, 0)),
true);
445 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, 5, 0)),
false);
446 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, 5, 0)),
false);
447 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, 0, 0)),
false);
448 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, 0, 0)),
false);
449 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, 0, 0)),
false);
450 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, 0, 0)),
false);
451 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, 0, 0)),
false);
452 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, -5, 0)),
false);
453 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, -5, 0)),
false);
454 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, -5, 0)),
false);
455 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, -5, 0)),
false);
456 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, -5, 0)),
false);
495 inPolys[1].erase(inPolys[1].begin() + inPolys[1].size() - 1);
497 std::reverse(inPolys[1].begin(), inPolys[1].end());
501 m->Setup(outPoly, inPolys);
505 std::vector<int> actual(pts.size(), 0);
506 for (
size_t i = 0; i < pts.size(); ++i)
508 actual[i] = (m->CoveredBy(pts[i]) != 0);
511 std::vector<int> expected{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
512 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
513 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
514 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
515 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0,
516 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
517 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
518 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
519 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
525 std::vector<int> actual(pts.size(), 0);
526 for (
size_t i = 0; i < pts.size(); ++i)
528 actual[i] = (m->Within(pts[i]) != 0);
531 std::vector<int> expected{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
532 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
533 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
534 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
535 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
536 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
537 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
538 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
539 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
580 a_outPoly = {{0, 0, 0}, {0, 30, 0}, {50, 30, 0}, {50, 15, 0}, {50, 0, 0}, {25, 0, 0}, {0, 0, 0}};
583 xms::VecPt3d inPoly1{{10, 10, 0}, {15, 10, 0}, {20, 10, 0}, {20, 15, 0},
584 {20, 20, 0}, {10, 20, 0}, {10, 10, 0}};
585 xms::VecPt3d inPoly2{{30, 10, 0}, {35, 10, 0}, {40, 10, 0}, {40, 15, 0},
586 {40, 20, 0}, {30, 20, 0}, {30, 10, 0}};
587 a_inPolys.push_back(inPoly1);
588 a_inPolys.push_back(inPoly2);
592 for (
int y = 35; y >= -5; y -= 5)
594 for (
int x = -5; x <= 55; x += 5)
596 a_ptsToTest.push_back(
Pt3d(x, y, 0));
635 0, 0, 0, 5, 0, 10, 0, 15, 5, 15, 5, 20, 0, 20, 0, 25, 0, 30, 5, 30,
636 5, 25, 10, 25, 10, 30, 15, 30, 15, 25, 20, 25, 20, 30, 25, 30, 25, 25, 30, 25,
637 30, 30, 35, 30, 35, 25, 40, 25, 40, 30, 50, 30, 50, 25, 45, 25, 45, 20, 50, 20,
638 50, 15, 45, 15, 45, 10, 50, 10, 50, 5, 45, 5, 45, 0, 40, 0, 40, 5, 35, 5,
639 35, 0, 30, 0, 30, 5, 25, 5, 25, 0, 20, 0, 20, 5, 15, 5, 15, 0, 10, 0,
640 10, 5, 5, 5, 5, 0, 0, 0};
641 a_outPoly = xms::gmArrayToVecPt3d(outPoly,
XM_COUNTOF(outPoly));
656 10, 10, 15, 10, 15, 15, 20, 15, 20, 10, 25, 10, 25, 15, 30, 15, 30, 10, 35, 10,
657 35, 15, 40, 15, 40, 20, 35, 20, 30, 20, 25, 20, 20, 20, 15, 20, 10, 20, 10, 15,
659 a_inPoly = xms::gmArrayToVecPt3d(inPoly1,
XM_COUNTOF(inPoly1));
675 std::vector<Pt3d> pts{{0, 0, 0}, {0, 10, 0}, {10, 10, 0}, {10, 0, 0}};
676 std::vector<std::vector<Pt3d>> v2d;
680 TS_ASSERT_EQUALS(10, i.MinDistanceToBoundary(pt));
683 TS_ASSERT_EQUALS(10, i.MinDistanceToBoundary(pt));
687 TS_ASSERT_EQUALS(d, i.MinDistanceToBoundary(pt));
690 TS_ASSERT_EQUALS(1, i.MinDistanceToBoundary(pt));
691 std::vector<Pt3d> in{{1, 1, 0}, {2, 1, 0}, {2, 2, 0}, {1, 2, 0}};
693 in = {{8, 8, 0}, {9, 8, 0}, {9, 9, 0}, {8, 9, 0}};
698 TS_ASSERT_EQUALS(1, i.MinDistanceToBoundary(pt));
701 TS_ASSERT_EQUALS(1, i.MinDistanceToBoundary(pt));
711 xms::VecPt3d out1 = {{0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}};
714 xms::VecPt3d out2 = {{-1.0, -1.0}, {-1.0, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {-1.0, -1.0}};
716 std::vector<BSHP<xms::GmPolygon>> output;
717 p1->Intersection(*p2, output);
718 TS_ASSERT(output.size() == 1);
719 if (output.size() != 1)
724 output[0]->GetPoints(outputPts, outputPtsInPoly);
728 out2 = {{0.5, -1.0}, {0.5, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {0.5, -1.0}};
730 p1->Intersection(*p2, output);
731 TS_ASSERT(output.size() == 1);
732 if (output.size() != 1)
734 base = {{0.5, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}};
735 output[0]->GetPoints(outputPts, outputPtsInPoly);
748 xms::VecPt3d out1 = {{0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}};
751 xms::VecPt3d out2 = {{-1.0, -1.0}, {-1.0, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {-1.0, -1.0}};
753 std::vector<BSHP<xms::GmPolygon>> output;
754 p1->Union(*p2, output);
755 TS_ASSERT(output.size() == 1);
756 if (output.size() != 1)
761 output[0]->GetPoints(outputPts, outputPtsInPoly);
765 out2 = {{0.5, -1.0}, {0.5, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {0.5, -1.0}};
767 p1->Union(*p2, output);
768 TS_ASSERT(output.size() == 1);
769 if (output.size() != 1)
771 base = {{0.5, 1.0}, {0.5, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {0.5, -1.0},
772 {0.5, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 1.0}};
773 output[0]->GetPoints(outputPts, outputPtsInPoly);
777 out2 = {{2.0, 0.0}, {2.0, 1.0}, {3.0, 1.0}, {3.0, 0.0}, {2.0, 0.0}};
779 p1->Union(*p2, output);
780 TS_ASSERT(output.size() == 2);
781 output[0]->GetPoints(outputPts, outputPtsInPoly);
785 output[1]->GetPoints(outputPts, outputPtsInPoly);
800 return *CxxTest::TestGroup::GetGroup(CxxTest::TG_INTERMEDIATE);
virtual void Setup()
Setup the polygons.
virtual void Setup(const VecPt3d &a_poly, const VecPt3d2d &a_inPolys) override
Create a boost geometry polygon to use in point in polygon.
GmBstPoly3d m_poly
The boost geom polygon.
void testNoHoles()
Test a simple polygon with some points outside, some inside, some on, and some coincident with polygo...
virtual void GetPoints(VecPt3d &a_poly, VecPt3d2d &a_inPolys) const override
Get the points from a boost polygon as vectors of Pt3d.
Wraps a boost polygon for point in poly, min distance from point to poly etc.
virtual void Setup() override
Sets things up.
virtual bool Within(Pt3d a_point) const override
Tests if a_point is inside the polygon and not in a hole.
Interface to a boost::geometry::polygon class.
static BSHP< GmPolygon > New()
Creates a class.
static void SetUpPolyWithHole(xms::VecPt3d &a_outPoly, xms::VecPt3d &a_inPolys)
Used in tests to create a polygon with lots of segments and 2 holes.
virtual void CheckPoint(const xms::Pt3d &a_pt) override
Checks if point is covered by the poly and updates status.
virtual double MaxTime() override
Return the max time this test should ever take.
void testIntersection()
tests intersection of polygons
virtual bool CoveredBy(Pt3d a_point) const override
Tests if a_point is inside or on the polygon and not in a hole.
std::vector< VecPt3d > VecPt3d2d
int m_status
Status (in, out, on) of at least one pt.
XM_DISALLOW_COPY_AND_ASSIGN(GmPointInPolyTester_GmPolygon)
Hide compiler generated copy and assign.
static void SetUpPolyWithHoles1(xms::VecPt3d &a_outPoly, xms::VecPt3d2d &a_inPolys, xms::VecPt3d &a_ptsToTest)
Used in tests to create a polygon with two holes.
void DoTest()
Run the test. This is the main function to call.
virtual ~GmPolygon()
Destructor.
GmPointInPolyTester_GmPolygon()
Constructor.
Functions dealing with geometry.
void testUnion()
tests union of polygons
#define XM_ENSURE_TRUE(...)
std::vector< Pt3d > VecPt3d
BSHP< xms::GmPolygon > m_poly
Polygon to test.
std::vector< xms::Pt3d > m_inPoly
Input polygon.
Used for speed tests of various point in poly functions / classes.
#define XM_COUNTOF(array)
GmPolygonImpl()
Constructor.
virtual void Intersection(const GmPolygon &a_, std::vector< BSHP< GmPolygon >> &a_out) const override
Performs a polygon intersection.
void testWithHoles()
Test a polygon with holes.
std::vector< xms::Pt3d > m_outPoly
Output polygon.
void testMinDistanceToBoundary()
tests calculating the minimum distance to the boundary of a polygon.
virtual double MinDistanceToBoundary(Pt3d a_pt) const override
Computes the min distance from a point to a polygon.
Helper class for testing GmPolygon.
virtual void Union(const GmPolygon &a_, std::vector< BSHP< GmPolygon >> &a_out) const override
Performs a polygon union.