18 #pragma warning(disable : 4512) // boost code: no assignment operator 19 #pragma warning(disable : 4244) // boost code: possible loss of data 20 #pragma warning(disable : 4127) // boost code: conditional expression is constant 21 #include <boost/geometry/geometry.hpp> 54 virtual bool Within(
Pt3d a_point)
const override;
57 std::vector<BSHP<GmPolygon>>& a_out)
const override;
58 virtual void Union(
const GmPolygon& a_, std::vector<BSHP<GmPolygon>>& a_out)
const override;
79 for (
size_t i = 0; i < a_ring.size(); ++i)
81 line.push_back(a_ring[i]);
83 double d = boost::geometry::distance(line, a_pt);
118 namespace bg = boost::geometry;
124 for (
size_t i = 0; i < a_outPoly.size(); ++i)
126 bg::exterior_ring(
m_poly).push_back(a_outPoly[i]);
130 for (
size_t i = 0; i < a_inPolys.size(); ++i)
133 for (
size_t j = 0; j < a_inPolys[i].size(); ++j)
135 inner.push_back(a_inPolys[i][j]);
137 bg::interior_rings(
m_poly).push_back(inner);
153 a_outPoly =
m_poly.outer();
154 for (
auto& p :
m_poly.inners())
156 a_inPolys.push_back(p);
170 namespace bg = boost::geometry;
172 if (bg::covered_by(a_point,
m_poly))
189 namespace bg = boost::geometry;
191 if (bg::within(a_point,
m_poly))
204 namespace bg = boost::geometry;
206 for (
size_t i = 0; i <
m_poly.inners().size(); ++i)
222 namespace bg = boost::geometry;
225 std::vector<GmBstPoly3d> output;
228 for (
auto& o : output)
232 for (
auto& i : o.inners())
237 gp->Setup(outPoly, inPoly);
249 namespace bg = boost::geometry;
252 std::vector<GmBstPoly3d> output;
255 for (
auto& o : output)
259 for (
auto& i : o.inners())
264 gp->Setup(outPoly, inPoly);
304 #include <boost/assign.hpp> 305 #include <boost/timer/timer.hpp> 340 xms::VecPt3d2d inPolys(1,
m_inPoly);
402 xms::VecPt3d poly{{0, 0, 0}, {5, 0, 0}, {10, 0, 0}, {10, 5, 0}, {10, 10, 0}, {0, 10, 0}};
404 m->Setup(poly, xms::VecPt3d2d());
405 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, 15, 0)),
false);
406 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, 15, 0)),
false);
407 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, 15, 0)),
false);
408 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, 15, 0)),
false);
409 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, 15, 0)),
false);
410 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, 10, 0)),
false);
411 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, 10, 0)),
true);
412 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, 10, 0)),
true);
413 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, 10, 0)),
true);
414 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, 10, 0)),
false);
415 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, 5, 0)),
false);
416 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, 5, 0)),
true);
417 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, 5, 0)),
true);
418 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, 5, 0)),
true);
419 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, 5, 0)),
false);
420 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, 0, 0)),
false);
421 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, 0, 0)),
true);
422 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, 0, 0)),
true);
423 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, 0, 0)),
true);
424 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, 0, 0)),
false);
425 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(-5, -5, 0)),
false);
426 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(0, -5, 0)),
false);
427 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(5, -5, 0)),
false);
428 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(10, -5, 0)),
false);
429 TS_ASSERT_EQUALS(m->CoveredBy(
Pt3d(15, -5, 0)),
false);
431 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, 15, 0)),
false);
432 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, 15, 0)),
false);
433 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, 15, 0)),
false);
434 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, 15, 0)),
false);
435 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, 15, 0)),
false);
436 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, 10, 0)),
false);
437 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, 10, 0)),
false);
438 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, 10, 0)),
false);
439 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, 10, 0)),
false);
440 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, 10, 0)),
false);
441 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, 5, 0)),
false);
442 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, 5, 0)),
false);
443 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, 5, 0)),
true);
444 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, 5, 0)),
false);
445 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, 5, 0)),
false);
446 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, 0, 0)),
false);
447 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, 0, 0)),
false);
448 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, 0, 0)),
false);
449 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, 0, 0)),
false);
450 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, 0, 0)),
false);
451 TS_ASSERT_EQUALS(m->Within(
Pt3d(-5, -5, 0)),
false);
452 TS_ASSERT_EQUALS(m->Within(
Pt3d(0, -5, 0)),
false);
453 TS_ASSERT_EQUALS(m->Within(
Pt3d(5, -5, 0)),
false);
454 TS_ASSERT_EQUALS(m->Within(
Pt3d(10, -5, 0)),
false);
455 TS_ASSERT_EQUALS(m->Within(
Pt3d(15, -5, 0)),
false);
488 xms::VecPt3d outPoly;
489 xms::VecPt3d2d inPolys;
494 inPolys[1].erase(inPolys[1].begin() + inPolys[1].size() - 1);
496 std::reverse(inPolys[1].begin(), inPolys[1].end());
500 m->Setup(outPoly, inPolys);
504 std::vector<int> actual(pts.size(), 0);
505 for (
size_t i = 0; i < pts.size(); ++i)
507 actual[i] = (m->CoveredBy(pts[i]) != 0);
510 std::vector<int> expected{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
511 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 1, 1, 1, 0, 1, 1, 1, 0,
515 0, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
524 std::vector<int> actual(pts.size(), 0);
525 for (
size_t i = 0; i < pts.size(); ++i)
527 actual[i] = (m->Within(pts[i]) != 0);
530 std::vector<int> expected{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
531 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
532 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
533 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
537 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
538 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
569 xms::VecPt3d2d& a_inPolys,
570 xms::VecPt3d& a_ptsToTest)
579 a_outPoly = {{0, 0, 0}, {0, 30, 0}, {50, 30, 0}, {50, 15, 0}, {50, 0, 0}, {25, 0, 0}, {0, 0, 0}};
582 xms::VecPt3d inPoly1{{10, 10, 0}, {15, 10, 0}, {20, 10, 0}, {20, 15, 0},
583 {20, 20, 0}, {10, 20, 0}, {10, 10, 0}};
584 xms::VecPt3d inPoly2{{30, 10, 0}, {35, 10, 0}, {40, 10, 0}, {40, 15, 0},
585 {40, 20, 0}, {30, 20, 0}, {30, 10, 0}};
586 a_inPolys.push_back(inPoly1);
587 a_inPolys.push_back(inPoly2);
591 for (
int y = 35; y >= -5; y -= 5)
593 for (
int x = -5; x <= 55; x += 5)
595 a_ptsToTest.push_back(
Pt3d(x, y, 0));
634 0, 0, 0, 5, 0, 10, 0, 15, 5, 15, 5, 20, 0, 20, 0, 25, 0, 30, 5, 30,
635 5, 25, 10, 25, 10, 30, 15, 30, 15, 25, 20, 25, 20, 30, 25, 30, 25, 25, 30, 25,
636 30, 30, 35, 30, 35, 25, 40, 25, 40, 30, 50, 30, 50, 25, 45, 25, 45, 20, 50, 20,
637 50, 15, 45, 15, 45, 10, 50, 10, 50, 5, 45, 5, 45, 0, 40, 0, 40, 5, 35, 5,
638 35, 0, 30, 0, 30, 5, 25, 5, 25, 0, 20, 0, 20, 5, 15, 5, 15, 0, 10, 0,
639 10, 5, 5, 5, 5, 0, 0, 0};
655 10, 10, 15, 10, 15, 15, 20, 15, 20, 10, 25, 10, 25, 15, 30, 15, 30, 10, 35, 10,
656 35, 15, 40, 15, 40, 20, 35, 20, 30, 20, 25, 20, 20, 20, 15, 20, 10, 20, 10, 15,
674 std::vector<Pt3d> pts{{0, 0, 0}, {0, 10, 0}, {10, 10, 0}, {10, 0, 0}};
675 std::vector<std::vector<Pt3d>> v2d;
690 std::vector<Pt3d> in{{1, 1, 0}, {2, 1, 0}, {2, 2, 0}, {1, 2, 0}};
692 in = {{8, 8, 0}, {9, 8, 0}, {9, 9, 0}, {8, 9, 0}};
710 xms::VecPt3d out1 = {{0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}};
713 xms::VecPt3d out2 = {{-1.0, -1.0}, {-1.0, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {-1.0, -1.0}};
715 std::vector<BSHP<xms::GmPolygon>> output;
716 p1->Intersection(*p2, output);
717 TS_ASSERT(output.size() == 1);
718 if (output.size() != 1)
720 xms::VecPt3d base = out1;
721 xms::VecPt3d outputPts;
722 xms::VecPt3d2d outputPtsInPoly;
723 output[0]->GetPoints(outputPts, outputPtsInPoly);
727 out2 = {{0.5, -1.0}, {0.5, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {0.5, -1.0}};
729 p1->Intersection(*p2, output);
730 TS_ASSERT(output.size() == 1);
731 if (output.size() != 1)
733 base = {{0.5, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.5, 0.0}, {0.5, 1.0}};
734 output[0]->GetPoints(outputPts, outputPtsInPoly);
747 xms::VecPt3d out1 = {{0.0, 0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}};
750 xms::VecPt3d out2 = {{-1.0, -1.0}, {-1.0, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {-1.0, -1.0}};
752 std::vector<BSHP<xms::GmPolygon>> output;
753 p1->Union(*p2, output);
754 TS_ASSERT(output.size() == 1);
755 if (output.size() != 1)
757 xms::VecPt3d base = out2;
758 xms::VecPt3d outputPts;
759 xms::VecPt3d2d outputPtsInPoly;
760 output[0]->GetPoints(outputPts, outputPtsInPoly);
764 out2 = {{0.5, -1.0}, {0.5, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {0.5, -1.0}};
766 p1->Union(*p2, output);
767 TS_ASSERT(output.size() == 1);
768 if (output.size() != 1)
770 base = {{0.5, 1.0}, {0.5, 2.0}, {2.0, 2.0}, {2.0, -1.0}, {0.5, -1.0},
771 {0.5, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.5, 1.0}};
772 output[0]->GetPoints(outputPts, outputPtsInPoly);
776 out2 = {{2.0, 0.0}, {2.0, 1.0}, {3.0, 1.0}, {3.0, 0.0}, {2.0, 0.0}};
778 p1->Union(*p2, output);
779 TS_ASSERT(output.size() == 2);
780 output[0]->GetPoints(outputPts, outputPtsInPoly);
784 output[1]->GetPoints(outputPts, outputPtsInPoly);
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.
boost::geometry::model::linestring< Pt3d > GmBstLine3d
Boost line 3d.
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.
VecPt3d gmArrayToVecPt3d(double *a_array, int a_size)
Useful in testing to create a VecPt3d from a C array of xy pairs.
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
boost::geometry::ring_type< GmBstPoly3d >::type GmBstRing3d
Boost ring 3d.
#define XM_ENSURE_TRUE(...)
BSHP< xms::GmPolygon > m_poly
Polygon to test.
boost::geometry::model::polygon< Pt3d > GmBstPoly3d
Boost polygon 3d.
std::vector< VecPt3d > VecPt3d2d
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.
static double iDistanceToRing(const GmBstRing3d &a_ring, const Pt3d &a_pt)
Return the minimum distance from the point to a line on the ring.
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.
std::vector< Pt3d > VecPt3d
virtual void Union(const GmPolygon &a_, std::vector< BSHP< GmPolygon >> &a_out) const override
Performs a polygon union.