diff --git a/GeoLib/AnalyticalGeometry.cpp b/GeoLib/AnalyticalGeometry.cpp index b8fa5b673470556943795b1fb9d4b272e3ad10c1..362b8451d8cd9ea3eee7ea96e578c8ad479c1148 100644 --- a/GeoLib/AnalyticalGeometry.cpp +++ b/GeoLib/AnalyticalGeometry.cpp @@ -103,6 +103,19 @@ bool lineSegmentIntersect( if (!isCoplanar(a, b, c, d)) return false; + // handle special cases here to avoid computing intersection numerical + if (MathLib::sqrDist(a, c) < std::numeric_limits<double>::epsilon() || + MathLib::sqrDist(a, d) < std::numeric_limits<double>::epsilon()) { + s = a; + return true; + } + if (MathLib::sqrDist(b, c) < std::numeric_limits<double>::epsilon() || + MathLib::sqrDist(b, d) < std::numeric_limits<double>::epsilon()) { + s = b; + return true; + } + + // general case MathLib::Vector3 const v(a, b); MathLib::Vector3 const w(c, d); MathLib::Vector3 const qp(a, c); @@ -155,7 +168,7 @@ bool lineSegmentIntersect( return false; } -bool lineSegmentsIntersect(const GeoLib::Polyline* ply, +bool lineSegmentsIntersect(const GeoLib::Polyline* ply, size_t &idx0, size_t &idx1, GeoLib::Point& intersection_pnt) @@ -424,4 +437,26 @@ bool isCoplanar(const GeoLib::Point& a, const GeoLib::Point& b, const GeoLib::Po return (sqr_scalar_triple/normalisation_factor < 1e-11); } +void computeAndInsertAllIntersectionPoints(GeoLib::PointVec &pnt_vec, + std::vector<GeoLib::Polyline*> & plys) +{ + for (auto it0(plys.begin()); it0 != plys.end(); ++it0) { + auto it1(it0); + ++it1; + for (; it1 != plys.end(); ++it1) { + GeoLib::Point s; + for (std::size_t i(0); i<(*it0)->getNumberOfPoints()-1; i++) { + for (std::size_t j(0); j<(*it1)->getNumberOfPoints()-1; j++) { + if (lineSegmentIntersect(*(*it0)->getPoint(i), *(*it0)->getPoint(i+1), + *(*it1)->getPoint(j), *(*it1)->getPoint(j+1), s)) { + std::size_t const id(pnt_vec.push_back(new GeoLib::Point(s))); + (*it0)->insertPoint(i+1, id); + (*it1)->insertPoint(j+1, id); + } + } + } + } + } +} + } // end namespace GeoLib diff --git a/GeoLib/AnalyticalGeometry.h b/GeoLib/AnalyticalGeometry.h index 1a6b1a48d9dd33275de281d3b8fc77d547cf23ae..9a705b5d1e2828dd27a2c94107a0a7b99696bc3a 100644 --- a/GeoLib/AnalyticalGeometry.h +++ b/GeoLib/AnalyticalGeometry.h @@ -17,6 +17,7 @@ // GeoLib #include "Triangle.h" +#include "PointVec.h" // MathLib #include "LinAlg/Dense/DenseMatrix.h" @@ -183,6 +184,16 @@ double scalarTriple(MathLib::Vector3 const& u, MathLib::Vector3 const& v, MathLi const GeoLib::Point& c, const GeoLib::Point& d); +/** + * Method first computes the intersection points of line segements of GeoLib::Polyline objects + * (@see computeIntersectionPoints()) and pushes each intersection point in the GeoLib::PointVec + * pnt_vec. For each intersection an id is returned. This id is used to split the two + * intersecting straight line segments in four straight line segments. + */ +void computeAndInsertAllIntersectionPoints( + GeoLib::PointVec &pnt_vec, + std::vector<GeoLib::Polyline*> & plys); + } // end namespace GeoLib #endif /* ANALYTICAL_GEOMETRY_H_ */ diff --git a/GeoLib/Polygon.cpp b/GeoLib/Polygon.cpp index 93c4c394ea84f9df49d1fe0558c4e69a9bd3c3e5..fc3ebfe3e76581ea46b5738c84cfd0ec6e8eebe6 100644 --- a/GeoLib/Polygon.cpp +++ b/GeoLib/Polygon.cpp @@ -113,18 +113,84 @@ bool Polygon::isPntInPolygon(double x, double y, double z) const return isPntInPolygon (pnt); } -bool Polygon::isPolylineInPolygon(const Polyline& ply) const +std::vector<GeoLib::Point> Polygon::getAllIntersectionPoints( + GeoLib::Point const& a, GeoLib::Point const& b) const { - std::size_t ply_size (ply.getNumberOfPoints()), cnt (0); - for (std::size_t k(0); k < ply_size; k++) { - if (isPntInPolygon (*(ply.getPoint(k)))) { - cnt++; + std::vector<GeoLib::Point> intersections; + const std::size_t n_segments(getNumberOfPoints() - 1); + GeoLib::Point s; + for (std::size_t k(0); k < n_segments; k++) { + if (GeoLib::lineSegmentIntersect(*(getPoint(k)), *(getPoint(k+1)), a, b, s)) { + intersections.push_back(s); } } - if (cnt == ply_size) - return true; - return false; + return intersections; +} + +bool Polygon::containsSegment(GeoLib::Point const& a, GeoLib::Point const& b) const +{ + std::vector<GeoLib::Point> s(getAllIntersectionPoints(a, b)); + + // no intersections -> check if at least one point of segment is in polygon + if (s.empty()) { + return (isPntInPolygon(a)); + } + + const double tol(std::numeric_limits<float>::epsilon()); + + // one intersection, intersection in line segment end point + if (s.size() == 1) { + const double sqr_dist_as(MathLib::sqrDist(a,s[0])); + if (sqr_dist_as < tol) { + return (isPntInPolygon(b)); + } + + const double sqr_dist_bs(MathLib::sqrDist(b,s[0])); + if (sqr_dist_bs < tol) { + return (isPntInPolygon(a)); + } + } + + // Sorting the intersection with respect to the distance to the point a. + // This induces a partition of the line segment into sub segments. + std::sort(s.begin(), s.end(), + [&a] (GeoLib::Point const& p0, GeoLib::Point const& p1) { + return MathLib::sqrDist(a, p0) <= MathLib::sqrDist(a, p1); + } + ); + + // remove sub segments with almost zero length + for (std::size_t k(0); k<s.size()-1; ) { + if (MathLib::sqrDist(s[k], s[k+1]) < tol) { + s.erase(s.begin()+k+1); + } else { + k++; + } + } + + // Check if all sub segments are within the polygon. + if (!isPntInPolygon(GeoLib::Point(0.5*(a[0]+s[0][0]), 0.5*(a[1]+s[0][1]), 0.5*(a[2]+s[0][2])))) + return false; + const std::size_t n_sub_segs(s.size()-1); + for (std::size_t k(0); k<n_sub_segs; k++) { + if (!isPntInPolygon(GeoLib::Point(0.5*(s[k][0]+s[k+1][0]), 0.5*(s[k][1]+s[k+1][1]), 0.5*(s[k][2]+s[k+1][2])))) + return false; + } + if (!isPntInPolygon(GeoLib::Point(0.5*(s[0][0]+b[0]), 0.5*(s[0][1]+b[1]), 0.5*(s[0][2]+b[2])))) + return false; + return true; +} + +bool Polygon::isPolylineInPolygon(const Polyline& ply) const +{ + std::size_t const n_segments(ply.getNumberOfPoints()-1); + for (std::size_t k(0); k < n_segments; k++) { + if (!containsSegment(*ply.getPoint(k), *ply.getPoint(k+1))) { + return false; + } + } + return true; } bool Polygon::isPartOfPolylineInPolygon(const Polyline& ply) const diff --git a/GeoLib/Polygon.h b/GeoLib/Polygon.h index 667d935d8602cc178cd0f126a58da57814e89224..d66dd5998bad4111be2e6fef6bfb8e7016416512 100644 --- a/GeoLib/Polygon.h +++ b/GeoLib/Polygon.h @@ -39,7 +39,7 @@ enum class EdgeType }; /** - * + * A polygon is a (closed) polyline. Thus class Polygon is derived from class Polyline. */ class Polygon : public Polyline { @@ -71,6 +71,16 @@ public: * @return if point is inside the polygon true, else false */ bool isPntInPolygon (double x, double y, double z) const; + + /** + * Checks if the straight line segment given by its end points a and b + * is contained within the polygon. + * @param a the first end point of the straight line segment + * @param b the second end point of the straight line segment + * @return true if the straight line segment is within the polygon, else false + */ + bool containsSegment(GeoLib::Point const& a, GeoLib::Point const& b) const; + /** * Method checks if all points of the polyline ply are inside of the polygon. * @param ply the polyline that should be checked @@ -104,6 +114,16 @@ public: friend bool operator==(Polygon const& lhs, Polygon const& rhs); private: + /** + * computes all intersection points of the straight line segment and the polyline boundary + * @param a end point of line segment + * @param b end point of line segment + * @return a vector of tuples, where a tuple contains the intersection point and + * the intersected segment number + */ + std::vector<GeoLib::Point> getAllIntersectionPoints( + GeoLib::Point const& a, GeoLib::Point const& b) const; + /** * from book: Computational Geometry and Computer Graphics in C++, page 119 * get the type of edge with respect to the given point (2d method!) diff --git a/GeoLib/PolylineWithSegmentMarker.h b/GeoLib/PolylineWithSegmentMarker.h index 0e7cc7a905d800bf5bc9affe882cce5e7eee243d..f904bf032af4b28d19b1f8f7c714427d6131b2d0 100644 --- a/GeoLib/PolylineWithSegmentMarker.h +++ b/GeoLib/PolylineWithSegmentMarker.h @@ -19,6 +19,10 @@ namespace GeoLib { +/** + * This is a polyline with the possibility to mark some segments. Thus class + * PolylineWithSegmentMarker is derived from class Polyline. + */ class PolylineWithSegmentMarker: public GeoLib::Polyline { public: PolylineWithSegmentMarker(GeoLib::Polyline const& polyline); diff --git a/GeoLib/SimplePolygonTree.cpp b/GeoLib/SimplePolygonTree.cpp index 0c6796cdfb051aee649e4118a54fbfcc2e08d4f5..6c09108b1e2aeb47b7461cbddc37e1734554b768 100644 --- a/GeoLib/SimplePolygonTree.cpp +++ b/GeoLib/SimplePolygonTree.cpp @@ -30,20 +30,7 @@ SimplePolygonTree::~SimplePolygonTree() bool SimplePolygonTree::isPolygonInside (const SimplePolygonTree* polygon_hierarchy) const { - const Polygon* polygon (polygon_hierarchy->getPolygon()); - // check *all* points of polygon - size_t n_pnts_polygon (polygon->getNumberOfPoints() - 1), cnt(0); - for (size_t k(0); k < n_pnts_polygon && cnt == k; k++) { - if (_node_polygon->isPntInPolygon (*(polygon->getPoint(k)))) { - cnt++; - } - } - - // all points of the given polygon are contained in the - if (cnt == n_pnts_polygon) - return true; - else - return false; + return _node_polygon->isPolylineInPolygon(*(polygon_hierarchy->getPolygon())); } void SimplePolygonTree::insertSimplePolygonTree (SimplePolygonTree* polygon_hierarchy) diff --git a/Tests/GeoLib/TestComputeAndInsertAllIntersectionPoints.cpp b/Tests/GeoLib/TestComputeAndInsertAllIntersectionPoints.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1495ed8a33c0ed33fc6c3993566ae64df37c962f --- /dev/null +++ b/Tests/GeoLib/TestComputeAndInsertAllIntersectionPoints.cpp @@ -0,0 +1,108 @@ +/** + * @file TestComputeAndInsertAllIntersectionPoints.cpp + * @date 2014-05-09 + * + * @copyright + * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/LICENSE.txt + */ + +#include <ctime> +#include <tuple> + +#include "gtest/gtest.h" + +#include "Point.h" +#include "Polyline.h" +#include "GEOObjects.h" +#include "AnalyticalGeometry.h" + +TEST(GeoLib, TestComputeAndInsertAllIntersectionPoints) +{ + // *** insert points in vector + std::vector<GeoLib::Point*> *pnts(new std::vector<GeoLib::Point*>); + pnts->push_back(new GeoLib::Point(0.0,0.0,0.0)); + pnts->push_back(new GeoLib::Point(11.0,0.0,0.0)); + + pnts->push_back(new GeoLib::Point(0.0,1.0,0.0)); + pnts->push_back(new GeoLib::Point(1.0,-1.0,0.0)); + pnts->push_back(new GeoLib::Point(2.0, 1.0,0.0)); + pnts->push_back(new GeoLib::Point(3.0,-1.0,0.0)); + pnts->push_back(new GeoLib::Point(4.0, 1.0,0.0)); + pnts->push_back(new GeoLib::Point(5.0,-1.0,0.0)); + pnts->push_back(new GeoLib::Point(6.0, 1.0,0.0)); + pnts->push_back(new GeoLib::Point(7.0,-1.0,0.0)); + pnts->push_back(new GeoLib::Point(8.0, 1.0,0.0)); + pnts->push_back(new GeoLib::Point(9.0,-1.0,0.0)); + pnts->push_back(new GeoLib::Point(10.0, 1.0,0.0)); + pnts->push_back(new GeoLib::Point(11.0,-1.0,0.0)); + + GeoLib::GEOObjects geo_objs; + std::string geo_name("TestGeometry"); + geo_objs.addPointVec(pnts, geo_name); + + // *** create polylines + GeoLib::Polyline* ply0(new GeoLib::Polyline(*pnts)); + ply0->addPoint(0); + ply0->addPoint(1); + GeoLib::Polyline* ply1(new GeoLib::Polyline(*pnts)); + for (std::size_t k(2); k<14; k++) + ply1->addPoint(k); + std::vector<GeoLib::Polyline*>* plys(new std::vector<GeoLib::Polyline*>); + plys->push_back(ply0); + plys->push_back(ply1); + + GeoLib::PointVec &pnt_vec(*(const_cast<GeoLib::PointVec*>(geo_objs.getPointVecObj(geo_name)))); + GeoLib::computeAndInsertAllIntersectionPoints(pnt_vec, *plys); + + ASSERT_EQ(25u, pnt_vec.size()); + ASSERT_EQ(13u, ply0->getNumberOfPoints()); + ASSERT_EQ(23u, ply1->getNumberOfPoints()); + + // check correct order of points in ply0 + EXPECT_EQ(0u, ply0->getPointID(0)); + EXPECT_EQ(14u, ply0->getPointID(1)); + EXPECT_EQ(15u, ply0->getPointID(2)); + EXPECT_EQ(16u, ply0->getPointID(3)); + EXPECT_EQ(17u, ply0->getPointID(4)); + EXPECT_EQ(18u, ply0->getPointID(5)); + EXPECT_EQ(19u, ply0->getPointID(6)); + EXPECT_EQ(20u, ply0->getPointID(7)); + EXPECT_EQ(21u, ply0->getPointID(8)); + EXPECT_EQ(22u, ply0->getPointID(9)); + EXPECT_EQ(23u, ply0->getPointID(10)); + EXPECT_EQ(24u, ply0->getPointID(11)); + EXPECT_EQ(1u, ply0->getPointID(12)); + + // check correct order of points in ply1 + EXPECT_EQ(2u, ply1->getPointID(0)); + EXPECT_EQ(14u, ply1->getPointID(1)); + EXPECT_EQ(3u, ply1->getPointID(2)); + EXPECT_EQ(15u, ply1->getPointID(3)); + EXPECT_EQ(4u, ply1->getPointID(4)); + EXPECT_EQ(16u, ply1->getPointID(5)); + EXPECT_EQ(5u, ply1->getPointID(6)); + EXPECT_EQ(17u, ply1->getPointID(7)); + EXPECT_EQ(6u, ply1->getPointID(8)); + EXPECT_EQ(18u, ply1->getPointID(9)); + EXPECT_EQ(7u, ply1->getPointID(10)); + EXPECT_EQ(19u, ply1->getPointID(11)); + EXPECT_EQ(8u, ply1->getPointID(12)); + EXPECT_EQ(20u, ply1->getPointID(13)); + EXPECT_EQ(9u, ply1->getPointID(14)); + EXPECT_EQ(21u, ply1->getPointID(15)); + EXPECT_EQ(10u, ply1->getPointID(16)); + EXPECT_EQ(22u, ply1->getPointID(17)); + EXPECT_EQ(11u, ply1->getPointID(18)); + EXPECT_EQ(23u, ply1->getPointID(19)); + EXPECT_EQ(12u, ply1->getPointID(20)); + EXPECT_EQ(24u, ply1->getPointID(21)); + EXPECT_EQ(13u, ply1->getPointID(22)); + + delete plys; + delete ply1; + delete ply0; +} + diff --git a/Tests/GeoLib/TestPolygon.cpp b/Tests/GeoLib/TestPolygon.cpp index 47444e0ca5fc63445121fe6d00ea8c9227ef04bf..eeaa7b8155c8854a2c57924b481e705f3c870b2f 100644 --- a/Tests/GeoLib/TestPolygon.cpp +++ b/Tests/GeoLib/TestPolygon.cpp @@ -20,32 +20,34 @@ using namespace GeoLib; /** * Polygon: - * 3 - * / \ - * / \ - * 2 4 - * | | - * | | - * 1 5 - * \ / - * \ / - * 0 + * 2 4 6 + * |\ / \ /| + * | \ / \ / | + * 1 3 5 7 + * \ / + * \ / + * \ / + * \ / + * \ / + * 0 */ -class IsPntInPolygonTest : public testing::Test +class PolygonTest : public testing::Test { public: - IsPntInPolygonTest() : + PolygonTest() : _polygon(nullptr) { // create points and construct polygon - _pnts.push_back(new Point(1.0,0.0,0.0)); - _pnts.push_back(new Point(0.0,1.0,0.0)); - _pnts.push_back(new Point(0.0,2.0,0.0)); - _pnts.push_back(new Point(1.0,3.0,0.0)); - _pnts.push_back(new Point(2.0,2.0,0.0)); - _pnts.push_back(new Point(2.0,1.0,0.0)); + _pnts.push_back(new Point( 0.0, 0.0,0.0)); // 0 + _pnts.push_back(new Point(-2.0, 2.0,0.0)); // 1 + _pnts.push_back(new Point(-2.0, 4.0,0.0)); // 2 + _pnts.push_back(new Point(-1.0, 2.0,0.0)); // 3 + _pnts.push_back(new Point( 0.0, 4.0,0.0)); // 4 + _pnts.push_back(new Point( 1.0, 2.0,0.0)); // 5 + _pnts.push_back(new Point( 2.0, 4.0,0.0)); // 6 + _pnts.push_back(new Point( 2.0, 2.0,0.0)); // 7 // create closed polyline Polyline ply(_pnts); @@ -55,13 +57,15 @@ public: ply.addPoint(3); ply.addPoint(4); ply.addPoint(5); + ply.addPoint(6); + ply.addPoint(7); ply.addPoint(0); // create polygon _polygon = new Polygon(ply); } - ~IsPntInPolygonTest() + ~PolygonTest() { delete _polygon; for (std::size_t k(0); k<_pnts.size(); k++) @@ -73,13 +77,13 @@ protected: Polygon *_polygon; }; -TEST_F(IsPntInPolygonTest, CheckCorners) +TEST_F(PolygonTest, isPntInPolygonCheckCorners) { for (std::size_t k(0); k<_pnts.size(); k++) EXPECT_TRUE(_polygon->isPntInPolygon(*_pnts[k])); } -TEST_F(IsPntInPolygonTest, CheckPointsRestOnPolygonEdges) +TEST_F(PolygonTest, isPntInPolygonCheckPointsRestOnPolygonEdges) { for (std::size_t k(0); k<_pnts.size()-1; k++) { for (double t(0.0); t<1.0; t+=0.001) { @@ -94,20 +98,128 @@ TEST_F(IsPntInPolygonTest, CheckPointsRestOnPolygonEdges) } } -TEST_F(IsPntInPolygonTest, CheckInnerPoints) +TEST_F(PolygonTest, isPntInPolygonCheckInnerPoints) { ASSERT_TRUE(_polygon->isPntInPolygon(Point(1.0,1.0,0.0))); ASSERT_TRUE(_polygon->isPntInPolygon(Point(0.5,1.0,0.0))); } -TEST_F(IsPntInPolygonTest, CheckOuterPoints) +TEST_F(PolygonTest, isPntInPolygonCheckOuterPoints) { - ASSERT_FALSE(_polygon->isPntInPolygon(Point(1.0-std::numeric_limits<float>::epsilon(),0.0,0.0))); - ASSERT_FALSE(_polygon->isPntInPolygon(Point(1.0+std::numeric_limits<float>::epsilon(),0.0,0.0))); - ASSERT_FALSE(_polygon->isPntInPolygon(Point(0.0-std::numeric_limits<float>::epsilon(),1.0,0.0))); - ASSERT_FALSE(_polygon->isPntInPolygon(Point(0.0-std::numeric_limits<float>::epsilon(),2.0,0.0))); - ASSERT_FALSE(_polygon->isPntInPolygon(Point(1.0-std::numeric_limits<float>::epsilon(),3.0,0.0))); - ASSERT_FALSE(_polygon->isPntInPolygon(Point(1.0+std::numeric_limits<float>::epsilon(),3.0,0.0))); + ASSERT_FALSE(_polygon->isPntInPolygon(Point(0.0-std::numeric_limits<float>::epsilon(),0.0,0.0))); + ASSERT_FALSE(_polygon->isPntInPolygon(Point(-2.0-std::numeric_limits<float>::epsilon(),2.0,0.0))); + ASSERT_FALSE(_polygon->isPntInPolygon(Point(-2.0-std::numeric_limits<float>::epsilon(),4.0,0.0))); + ASSERT_FALSE(_polygon->isPntInPolygon(Point(-1.0, 2.0+std::numeric_limits<float>::epsilon(),0.0))); + ASSERT_FALSE(_polygon->isPntInPolygon(Point(0.0-std::numeric_limits<float>::epsilon(),4.0,0.0))); + ASSERT_FALSE(_polygon->isPntInPolygon(Point(1.0,2.0+std::numeric_limits<float>::epsilon(),0.0))); + ASSERT_FALSE(_polygon->isPntInPolygon(Point(2.0-std::numeric_limits<float>::epsilon(),4.0,0.0))); ASSERT_FALSE(_polygon->isPntInPolygon(Point(2.0+std::numeric_limits<float>::epsilon(),2.0,0.0))); - ASSERT_FALSE(_polygon->isPntInPolygon(Point(2.0+std::numeric_limits<float>::epsilon(),1.0,0.0))); +} + +/** + * 2 4 6 + * |\ / \ /| + * | \ / \ / | + * 1 3 5 7 + * \ / + * \ / + * \ / + * \ / + * \ / + * 0 + * 0 = (0,0), 1=(-2,2), 2=(-2,4), 3=(-1,2), 4=(0,4), 5=(1,2), 6=(2,4), 7=(2,2) + */ +TEST_F(PolygonTest, containsSegment) +{ + // test segment (2,6) + GeoLib::Point &a(*(const_cast<GeoLib::Point*>(_polygon->getPoint(2)))); + GeoLib::Point &b(*(const_cast<GeoLib::Point*>(_polygon->getPoint(6)))); + ASSERT_FALSE(_polygon->containsSegment(a, b)); + + // test segments of polygon + for (std::size_t k(0); k<_polygon->getNumberOfPoints()-1;k++) { + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(k))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(k+1))); + EXPECT_TRUE(_polygon->containsSegment(a, b)); + } + + // 01 + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(0))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(1))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // 12 + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(1))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(2))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // 23 + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(2))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(3))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // 34 + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(3))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(4))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // 45 + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(4))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(5))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // 56 + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(5))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(6))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // 67 + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(6))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(7))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // 70 + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(7))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(0))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // test segment (3,5) + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(3))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(5))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // test segment (1,7) + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(1))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(7))); + ASSERT_TRUE(_polygon->containsSegment(a, b)); + + // test segment (1,4) + a = *(const_cast<GeoLib::Point*>(_polygon->getPoint(1))); + b = *(const_cast<GeoLib::Point*>(_polygon->getPoint(4))); + ASSERT_FALSE(_polygon->containsSegment(a, b)); + +} + +TEST_F(PolygonTest, isPolylineInPolygon) +{ + // create a test polyline + std::vector<GeoLib::Point*> pnts; + pnts.push_back(new GeoLib::Point(-2.0,4.0,0.0)); // 2 + pnts.push_back(new GeoLib::Point( 2.0,4.0,0.0)); // 6 + GeoLib::Polyline outer_ply(pnts); + outer_ply.addPoint(0); + outer_ply.addPoint(1); + ASSERT_FALSE(_polygon->isPolylineInPolygon(outer_ply)); + for (std::size_t k(0); k<pnts.size(); k++) + delete pnts[k]; + pnts.clear(); + + pnts.push_back(new GeoLib::Point(-1.0,2.0,0.0)); // 3 + pnts.push_back(new GeoLib::Point( 1.0,2.0,0.0)); // 5 + GeoLib::Polyline inner_ply(pnts); + inner_ply.addPoint(0); + inner_ply.addPoint(1); + ASSERT_TRUE(_polygon->isPolylineInPolygon(inner_ply)); + for (std::size_t k(0); k<pnts.size(); k++) + delete pnts[k]; }