20 #pragma warning(disable : 4512) // boost code: no assignment operator
21 #include <boost/geometry.hpp>
22 #include <boost/geometry/geometries/linestring.hpp>
23 #include <boost/geometry/geometries/point_xy.hpp>
24 #include <boost/geometry/geometries/polygon.hpp>
25 #include <boost/geometry/index/rtree.hpp>
44 namespace bg = boost::geometry;
45 namespace bgi = boost::geometry::index;
55 typedef std::pair<GmBstBox3d, int> ValueBox;
56 typedef bgi::rtree<ValueBox, bgi::quadratic<8>> RtreeBox;
64 BSHP<GmMultiPolyIntersectionSorter> a_sorter,
65 int a_startingId = 1);
68 virtual void SetQuery(GmMultiPolyIntersectorQueryEnum a_query)
override;
74 double a_y2,
VecInt &a_polyids,
75 std::vector<Pt3d> &a_pts)
override;
82 void BuildBoostPoly(
int a_polyIdx, GmBstPoly3d &a_boostPoly)
const;
91 void PointsOnSegment(
const GmBstPoly3d &a_poly,
const GmBstLine3d &a_line,
92 std::deque<Pt3d> &a_output);
96 std::vector<Pt3d> &a_pts);
106 BSHP<GmMultiPolyIntersectionSorter>
108 GmMultiPolyIntersectorQueryEnum
121 GmMultiPolyIntersector::GmMultiPolyIntersector() {
126 GmMultiPolyIntersector::~GmMultiPolyIntersector() {
139 BSHP<GmMultiPolyIntersector>
141 BSHP<GmMultiPolyIntersectionSorter> a_sorter,
143 return BDPC<GmMultiPolyIntersector>(
145 a_points, a_polys, a_sorter, a_startingId)));
166 BSHP<GmMultiPolyIntersectionSorter> a_sorter,
int a_startingId )
167 : m_d(), m_pt1(), m_pt2(), m_rtree(nullptr), m_line(), m_buffer(0.0),
168 m_startingId(a_startingId), m_boostPolys(), m_sorter(a_sorter),
169 m_query(GMMPIQ_COVEREDBY) {
183 GmMultiPolyIntersectorImpl::~GmMultiPolyIntersectorImpl() {
209 for (
size_t i = 0; i <
m_d.
m_polys.size(); ++i) {
210 for (
size_t j = 0; j <
m_d.
m_polys[i].size(); ++j) {
216 const double kFraction = 1e-5;
217 m_buffer = gmXyDistance(mn, mx) * kFraction;
251 int a_polyIdx, GmBstPoly3d &a_boostPoly)
const {
253 for (
int j = 0; j < (int)poly.size(); ++j) {
255 bg::exterior_ring(a_boostPoly).push_back(
m_d.
m_points[poly[j]]);
257 bg::exterior_ring(a_boostPoly).push_back(
m_d.
m_points[poly[0]]);
273 std::vector<ValueBox> boxen;
275 for (
int i = 0; i < (int)
m_d.
m_polys.size(); ++i) {
277 for (
int j = 0; j < (int)
m_d.
m_polys[i].size(); ++j) {
280 GmBstBox3d box(mn, mx);
283 boxen.push_back(std::make_pair(box, i));
287 m_rtree =
new RtreeBox(boxen.begin(), boxen.end());
302 GmMultiPolyIntersectorQueryEnum a_query) {
311 std::vector<ValueBox> result;
312 m_rtree->query(bgi::intersects(pt), std::back_inserter(result));
315 for (
size_t i = 0; i < result.size(); ++i) {
320 case GMMPIQ_COVEREDBY:
321 rv = bg::covered_by(pt, poly);
323 case GMMPIQ_INTERSECTS:
324 rv = bg::intersects(pt, poly);
331 a_poly.insert(result[i].second + 1);
341 std::vector<ValueBox> result;
342 m_rtree->query(bgi::intersects(
m_line), std::back_inserter(result));
350 for (
size_t i = 0; i < result.size(); ++i) {
352 std::deque<Pt3d> output;
353 bg::intersection(poly,
m_line, output);
354 if (2 > output.size())
356 for (
size_t j = 0; j < output.size(); ++j) {
357 ix ixn(output[j], result[i].second + 1,
XM_NODATA);
370 const GmBstLine3d &a_line,
371 std::deque<Pt3d> &a_output) {
373 for (
size_t i = 0; i < a_poly.outer().size(); ++i) {
374 const Pt3d &p = a_poly.outer()[i];
375 if (gmOnLineAndBetweenEndpointsWithTol(
376 a_line[0], a_line[1], p.
x, p.
y,
379 for (
size_t j = 0; j < a_output.size(); ++j) {
380 if (gmEqualPointsXY(a_output[j], p, tol))
384 a_output.push_back(p);
395 double totalLength = gmXyDistance(
m_pt1,
m_pt2);
396 for (
size_t i = 0; i <
m_d.
m_ixs.size(); ++i) {
410 [](
const ix &a,
const ix &b) ->
bool {
return a.
m_t < b.m_t; });
436 i-- > 0 && !found &&
m_d.
m_ixs[i].m_t == 1.0;) {
452 for (
int i = 0; i < (int)polyIds.size() - 1; ++i) {
454 polyIds[i] += offset;
476 double x2,
double y2,
491 double x2,
double y2,
508 double a_x2,
double a_y2,
510 std::vector<Pt3d> &a_pts) {
523 if (!polys.empty()) {
524 rval = (int)*polys.begin();
547 double a_x1,
double a_y1,
double a_x2,
double a_y2,
VecInt &a_polyids,
548 VecDbl &a_tvalues, std::vector<Pt3d> &a_pts) {
562 m_sorter->Sort(
m_d, a_polyids, a_tvalues, a_pts, kTol);
594 void iRunTest(
double x1,
double y1,
double x2,
double y2,
const VecPt3d &pts,
596 const VecDbl &a_expectedtValues,
597 const VecPt3d &a_expectedPoints) {
598 BSHP<GmMultiPolyIntersectionSorter> sorter =
599 BSHP<GmMultiPolyIntersectionSorter>(
601 BSHP<GmMultiPolyIntersector> mpi =
603 VecInt polyIds1, polyIds2, polyIds3;
606 mpi->TraverseLineSegment(x1, y1, x2, y2, polyIds1, tValues);
607 mpi->TraverseLineSegment(x1, y1, x2, y2, polyIds2);
608 mpi->TraverseLineSegment(x1, y1, x2, y2, polyIds3, points);
612 TS_ASSERT_EQUALS(polyIds1.size(), tValues.size());
613 TS_ASSERT_EQUALS(polyIds1.size(), points.size());
614 const double kDelta = 1e-5;
640 VecPt3d pts = {{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
642 VecInt expectedIds = {1, -1};
643 VecDbl expectedTvals = {0.0833333, 0.916667};
644 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
645 iRunTest(-1, 5, 11, 5, pts, polys, expectedIds, expectedTvals,
664 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
666 VecInt expectedIds{1, -1};
667 VecDbl expectedTvals{0.111111, 1.0};
668 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {8.0, 5.0, 0.0}};
669 iRunTest(-1, 5, 8, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
687 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
689 VecInt expectedIds{1, -1};
690 VecDbl expectedTvals{0.0, 0.833333};
691 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
692 iRunTest(5, 5, 11, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
710 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
712 VecInt expectedIds{1, -1};
713 VecDbl expectedTvals{0.0, 1.0};
714 VecPt3d expectedPoints = {{2.0, 5.0, 0.0}, {8.0, 5.0, 0.0}};
715 iRunTest(2, 5, 8, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
733 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
735 VecInt expectedIds{1, -1};
736 VecDbl expectedTvals{0.0, 1.0};
737 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
738 iRunTest(0, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
756 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
758 VecInt expectedIds{1, -1};
759 VecDbl expectedTvals{0.0, 1.0};
760 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {5.0, 5.0, 0.0}};
761 iRunTest(0, 5, 5, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
779 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
781 VecInt expectedIds{1, -1};
782 VecDbl expectedTvals{0.0, 1.0};
783 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
784 iRunTest(5, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
802 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
804 VecInt expectedIds{1, -1};
805 VecDbl expectedTvals{1.0, 1.0};
806 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {0.0, 5.0, 0.0}};
807 iRunTest(-1, 5, 0, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
825 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
827 VecInt expectedIds{1, -1};
828 VecDbl expectedTvals{0.0, 0.0};
829 VecPt3d expectedPoints = {{10.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
830 iRunTest(10, 5, 11, 5, pts, polys, expectedIds, expectedTvals,
849 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
851 VecInt expectedIds{1, -1};
852 VecDbl expectedTvals{0.0, 1.0};
853 VecPt3d expectedPoints = {{3.0, 10.0, 0.0}, {7.0, 10.0, 0.0}};
854 iRunTest(3, 10, 7, 10, pts, polys, expectedIds, expectedTvals,
873 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
875 VecInt expectedIds{1, -1};
876 VecDbl expectedTvals{0.0, 1.0};
877 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {10.0, 10.0, 0.0}};
878 iRunTest(0, 10, 10, 10, pts, polys, expectedIds, expectedTvals,
897 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
899 VecInt expectedIds{1, -1};
900 VecDbl expectedTvals{0.0833333, 0.9166667};
901 VecPt3d expectedPoints = {{10.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
904 iRunTest(11, 10, -1, 10, pts, polys, expectedIds, expectedTvals,
923 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
925 VecInt expectedIds{1, -1};
926 VecDbl expectedTvals{0.166667, 1.0};
927 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {5.0, 10.0, 0.0}};
928 iRunTest(-1, 10, 5, 10, pts, polys, expectedIds, expectedTvals,
930 expectedTvals = {0.0, 5 / 6.0};
931 expectedPoints = {{5.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
932 iRunTest(5, 10, -1, 10, pts, polys, expectedIds, expectedTvals,
937 expectedTvals = {1.0 / 3.0, 1.0};
938 expectedPoints = {{10.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
939 iRunTest(15, 10, 0, 10, pts, polys, expectedIds, expectedTvals,
957 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
959 VecInt expectedIds{1, -1};
960 VecDbl expectedTvals{0.0, 0.833333};
961 VecPt3d expectedPoints = {{5.0, 10.0, 0.0}, {10.0, 10.0, 0.0}};
962 iRunTest(5, 10, 11, 10, pts, polys, expectedIds, expectedTvals,
983 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
985 VecInt expectedIds{1, -1};
986 VecDbl expectedTvals{1.0, 1.0};
987 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
988 iRunTest(-1, 10, 0, 10, pts, polys, expectedIds, expectedTvals,
1008 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1010 VecInt expectedIds{1, -1};
1011 VecDbl expectedTvals{0.5, 0.5};
1012 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
1013 iRunTest(-1, 9, 1, 11, pts, polys, expectedIds, expectedTvals,
1033 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1038 iRunTest(-1, 10, 0, 11, pts, polys, expectedIds, expectedTvals,
1057 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1059 VecInt expectedIds{1, -1};
1060 VecDbl expectedTvals{0.0, 1.0};
1061 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {5.0, 10.0, 0.0}};
1062 iRunTest(0, 10, 5, 10, pts, polys, expectedIds, expectedTvals,
1081 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1083 VecInt expectedIds{1, -1};
1084 VecDbl expectedTvals{0.0, 1.0};
1085 VecPt3d expectedPoints = {{5.0, 10.0, 0.0}, {10.0, 10.0, 0.0}};
1086 iRunTest(5, 10, 10, 10, pts, polys, expectedIds, expectedTvals,
1105 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1106 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1108 VecInt expectedIds{1, -1};
1109 VecDbl expectedTvals{0.0, 1.0};
1110 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
1111 iRunTest(0, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1129 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1130 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1132 VecInt expectedIds{1, -1};
1133 VecDbl expectedTvals{0.0, 1.0};
1134 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
1135 iRunTest(5, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1153 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1154 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1155 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1156 VecInt expectedIds{1, -1};
1157 VecDbl expectedTvals{0.0, 1.0};
1158 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
1159 iRunTest(5, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1177 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1178 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1179 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1180 VecInt expectedIds{1, 2, -1};
1181 VecDbl expectedTvals{0.0454545, 0.5, 0.954545};
1183 {0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}, {20.0, 5.0, 0.0}};
1184 iRunTest(-1, 5, 21, 5, pts, polys, expectedIds, expectedTvals,
1203 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1204 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1205 VecInt2d polys = {{{0, 1, 4, 3}}, {1, 2, 5, 4}};
1206 VecInt expectedIds{1, 2, -1};
1207 VecDbl expectedTvals{0.0625, 0.6875, 1.0};
1209 {0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}, {15.0, 5.0, 0.0}};
1210 iRunTest(-1, 5, 15, 5, pts, polys, expectedIds, expectedTvals,
1229 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1230 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1231 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1232 VecInt expectedIds{1, 2, -1};
1233 VecDbl expectedTvals{0.0, 0.3125, 0.9375};
1235 {5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}, {20.0, 5.0, 0.0}};
1236 iRunTest(5, 5, 21, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1254 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1255 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1256 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1257 VecInt expectedIds{1, 2, -1};
1258 VecDbl expectedTvals{0.0, 0.5, 1.0};
1260 {5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}, {15.0, 5.0, 0.0}};
1261 iRunTest(5, 5, 15, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1278 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1279 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1280 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1281 VecInt expectedIds{1, -1};
1282 VecDbl expectedTvals{0.0, 1.0};
1283 VecPt3d expectedPoints = {{5.0, 10.0, 0.0}, {10.0, 10.0, 0.0}};
1284 iRunTest(5, 10, 10, 10, pts, polys, expectedIds, expectedTvals,
1302 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0},
1303 {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1304 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1305 VecInt expectedIds{2, -1};
1306 VecDbl expectedTvals{0.0, 1.0};
1307 VecPt3d expectedPoints = {{10.0, 10.0, 0.0}, {15.0, 10.0, 0.0}};
1308 iRunTest(10, 10, 15, 10, pts, polys, expectedIds, expectedTvals,
1332 VecPt3d pts{{0, 0, 100}, {10, 0, 110}, {20, 0, 105},
1333 {0, 10, 104}, {10, 10, 103}, {20, 10, 106}};
1334 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1335 VecInt expectedIds{1, 2, -1};
1336 VecDbl expectedTvals = {0.0, 1 / 3.0, 1};
1338 {5.0, 10.0, 0.0}, {10.0, 10.0, 0.0}, {20.0, 10.0, 0.0}};
1339 iRunTest(5, 10, 20, 10, pts, polys, expectedIds, expectedTvals,
1341 expectedIds = {2, 1, -1};
1342 expectedPoints = {{15.0, 10.0, 0.0}, {10.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
1343 iRunTest(15, 10, 0, 10, pts, polys, expectedIds, expectedTvals,
1367 VecPt3d pts{{0, 10, 0}, {10, 10, 0}, {10, 20, 0}, {0, 20, 0},
1368 {10, 0, 0}, {20, 0, 0}, {20, 10, 0}};
1369 VecInt2d polys = {{0, 1, 2, 3}, {4, 5, 6, 1}};
1370 VecInt expectedIds = {1, -1, 2, -1};
1371 VecDbl expectedTvals = {0.0, 0.2, 0.8, 1.0};
1373 {8.0, 18.0, 0.0}, {10.0, 16.0, 0.0}, {16.0, 10.0, 0.0}, {18.0, 8.0, 0.0}};
1374 iRunTest(8, 18, 18, 8, pts, polys, expectedIds, expectedTvals,
1398 trBuildGridTrianglePolys(1, 2, pts, polys);
1400 VecInt expectedIds{4, 3, 5, 6, -1};
1401 VecDbl expectedTvals{0.0, 0.166666, 0.5, 0.833333, 1.0};
1402 VecPt3d expectedPoints = {{5.0, -2.5, 0.0},
1403 {6.6666666666667, -3.333333333333, 0.0},
1405 {13.333333333333, -6.666666666667, 0.0},
1407 iRunTest(5, -2.5, 15, -7.5, pts, polys, expectedIds, expectedTvals,
1431 trBuildGridTrianglePolys(1, 2, pts, polys);
1433 VecInt expectedIds{1, 4, 3, 5, 6, 7, -1};
1434 VecDbl expectedTvals{0.0454545, 0.0833333, 0.34375, 0.5,
1435 0.65625, 0.916667, 0.954545};
1437 {0.0, -0.454545454545, 0.0}, {0.8333333333333, -0.833333333333, 0.0},
1438 {6.5625, -3.4375, 0.0}, {10.0, -5.0, 0.0},
1439 {13.4375, -6.5625, 0.0}, {19.166666666667, -9.166666666667, 0.0},
1440 {20.0, -9.545454545455, 0.0}};
1441 iRunTest(-1, 0, 21, -10, pts, polys, expectedIds, expectedTvals,
1466 trBuildGridTrianglePolys(1, 2, pts, polys);
1471 iRunTest(1, 1, -1, -1, pts, polys, expectedIds, expectedTvals,
1494 TS_SKIP(
"GREENBUILD: This test does not pass on Linux builds.");
1498 trBuildGridTrianglePolys(1, 2, pts, polys);
1499 VecInt expectedIds{1, -1};
1500 VecDbl expectedTvals{1.0, 1.0};
1501 VecPt3d expectedPoints = {{0.0, -2.0, 0.0}, {0.0, -2.0, 0.0}};
1502 iRunTest(-1, -1, 0, -2, pts, polys, expectedIds, expectedTvals,
1544 trBuildGridTrianglePolys(3, 3, pts, polys);
1549 VecInt expectedIds{2, 17, 18, 33, -1};
1550 VecDbl expectedTvals{0.0, 0.22222, 0.5, 0.777778, 1.0};
1551 VecPt3d expectedPoints = {{6.0, -6.0, 0.0},
1555 {24.0, -24.0, 0.0}};
1556 iRunTest(6, -6, 24, -24, pts, polys, expectedIds, expectedTvals,
1589 trBuildGridTrianglePolys(2, 3, pts, polys);
1593 VecInt expectedIds{16, 20, 24, -1};
1594 VecDbl expectedTvals{0.016129032258064516, 0.33870967741935482,
1595 0.66129032258064513, 0.98387096774193550};
1596 VecPt3d expectedPoints = {{0.0, -10.0, 0.0},
1599 {30.0, -10.0, 0.0}};
1600 iRunTest(-0.5, -10, 30.5, -10, pts, polys, expectedIds, expectedTvals,
1626 trBuildGridTrianglePolys(1, 2, pts, polys);
1631 VecInt expectedIds{3, 5, 7, -1};
1632 VecDbl expectedTvals{0.0, 0.14285714285714288, 0.5, 0.85714285714285721};
1633 VecPt3d expectedPoints = {{8.0, -2.5, 0.0},
1634 {10.0, -3.214285714286, 0.0},
1636 {20.0, -6.785714285714, 0.0}};
1637 iRunTest(8, -2.5, 22, -7.5, pts, polys, expectedIds, expectedTvals,
1664 trBuildGridTrianglePolys(1, 2, pts, polys);
1669 VecInt expectedIds{5, 8, -1};
1670 VecDbl expectedTvals{0.0, 0.4, 0.8};
1672 {10.0, -8.0, 0.0}, {14.0, -4.0, 0.0}, {18.0, 0.0, 0.0}};
1673 iRunTest(10, -8, 20, 2, pts, polys, expectedIds, expectedTvals,
1699 TS_SKIP(
"GREENBUILD: This test does not pass on Linux builds.");
1703 trBuildGridTrianglePolys(1, 2, pts, polys);
1708 VecInt expectedIds{3, -1};
1709 VecDbl expectedTvals{0.0, 1.0};
1710 VecPt3d expectedPoints = {{9.0, -5.0, 0.0}, {10.0, -8.0, 0.0}};
1711 iRunTest(9, -5, 10, -8, pts, polys, expectedIds, expectedTvals,
1720 VecPt3d pts{{1937.0003414079, 11829.937474193, 0.0},
1721 {1947.0331979019, 11744.658193995, 0.0},
1722 {1806.3085553039, 11640.957366058, 0.0},
1723 {1827.8055464927, 11817.091027732, 0.0},
1724 {2046.1951363232, 11842.783920654, 0.0},
1725 {2155.4908205085, 11854.643944679, 0.0},
1726 {2160.8354359402, 11805.390806652, 0.0},
1727 {2070.1604445251, 11710.224742147, 0.0}};
1729 polys[0] = {0, 3, 2, 1};
1730 polys[1] = {0, 1, 7, 6, 5, 4};
1732 const double t = 0.41350462827872492;
1733 VecInt expectedIds{2, -1, 2, 1, -1};
1734 VecDbl expectedTvals{0.0, 0.0, t, .5, 1.0};
1736 {2046.1951363232131, 11842.783920653745, 0.00000000000000000},
1737 {2046.1951363231999, 11842.783920653999, 0.00000000000000000},
1738 {1955.8900301603892, 11832.159790516887, 0.00000000000000000},
1739 {1937.0003414078999, 11829.937474193001, 0.00000000000000000},
1740 {1827.8055464926999, 11817.091027732000, 0.00000000000000000}};
1741 iRunTest(2046.1951363232131, 11842.783920653745, 1827.8055464926651,
1742 11817.091027732373, pts, polys, expectedIds, expectedTvals,
1744 expectedIds = {1, 2, -1, 2, -1};
1745 expectedTvals = {0.0, .5, 1 - t, 1, 1};
1746 expectedPoints = {{1827.8055464927, 11817.091027732, 0.0},
1747 {1937.0003414079, 11829.937474193, 0.0},
1748 {1955.8909579942, 11832.159899674, 0.0},
1749 {2046.1951363232, 11842.783920654, 0.0},
1750 {2046.1951363232, 11842.783920654, 0.0}};
1751 iRunTest(1827.8055464926651, 11817.091027732373, 2046.1951363232131,
1752 11842.783920653745, pts, polys, expectedIds, expectedTvals,
1778 trBuildGridTrianglePolys(1, 2, pts, polys);
1783 VecInt expectedIds{8, 5, -1};
1784 VecDbl expectedTvals{0.2, 0.6, 1.0};
1785 VecPt3d expectedPoints = {{18.0, 0.0}, {14.0, -4.0, 0.0}, {10.0, -8.0, 0.0}};
1786 iRunTest(20, 2, 10, -8, pts, polys, expectedIds, expectedTvals,
1793 VecPt3d pts{{-39.719999999999999, 90.079999999999998, 0.0},
1794 {-21.129999999999999, 90.469999999999999, 1.0},
1795 {-38.930000000000000, 75.840000000000003, 2.0},
1796 {-20.539999999999999, 76.629999999999995, 3.0},
1797 {-39.719999999999999, 62.000000000000000, 4.0},
1798 {-20.539999999999999, 61.609999999999999, 5.0},
1799 {-40.509999999999998, 47.770000000000003, 6.0},
1800 {-20.150000000000002, 46.579999999999998, 7.0},
1801 {-41.100000000000001, 30.370000000000001, 8.0},
1802 {-19.550000000000001, 29.379999999999999, 9.0}};
1804 polys[0] = {7, 5, 6};
1805 polys[1] = {3, 2, 5};
1806 polys[2] = {2, 3, 1};
1807 polys[3] = {9, 7, 8};
1808 polys[4] = {7, 6, 8};
1809 polys[5] = {0, 2, 1};
1810 polys[6] = {5, 2, 4};
1811 polys[7] = {4, 6, 5};
1813 VecInt expectedIds{6, 3, 2, 7, 8, 1, 5, 4, -1};
1815 0.065777232109665892, 0.18968813237387866, 0.26837085508795250,
1816 0.35199491192297022, 0.47395399691316503, 0.58799734941084614,
1817 0.68358069055240822, 0.81969307266961533, 0.93250275302111885};
1818 VecPt3d expectedPoints = {{-31.97119143306, 90.242562417488, 0.0},
1819 {-31.8980840019, 81.619602868102, 0.0},
1820 {-31.8516611955, 76.144072194429, 0.0},
1821 {-31.80232300197, 70.32467407928, 0.0},
1822 {-31.73036714182, 61.837541354813, 0.0},
1823 {-31.66308156385, 53.901264454499, 0.0},
1824 {-31.60668739257, 47.249619744458, 0.0},
1825 {-31.52638108712, 37.777559072921, 0.0},
1826 {-31.45982337572, 29.92713341726, 0.0}};
1827 iRunTest(-32.009999999999998, 94.819999999999993, -31.420000000000002,
1828 25.230000000000000, pts, polys, expectedIds, expectedTvals,
1842 return *CxxTest::TestGroup::GetGroup(CxxTest::TG_INTERMEDIATE);
1855 trBuildGridTrianglePolys(1000, 3, pts, polys);
1861 VecInt expectedIds{2, 17, 18, 33, -1};
1862 VecDbl expectedTvals{0.0, 0.22222, 0.5, 0.777778, 1.0};
1863 VecPt3d expectedPoints = {{6.0, -6.0, 0.0},
1867 {24.0, -24.0, 0.0}};
1868 iRunTest(6, -6, 24, -24, pts, polys, expectedIds, expectedTvals,
1882 trBuildGridTrianglePolys(1000, 3, pts, polys);
1885 VecInt expectedIds = {2, 17, 18, 33, -1};
1886 VecDbl expectedTvals = {0.0, 0.22222, 0.5, 0.777778, 1.0};
1887 BSHP<GmMultiPolyIntersectionSorter> sorter =
1888 BSHP<GmMultiPolyIntersectionSorter>(
1890 BSHP<GmMultiPolyIntersector> mpi =
1894 const int nIntersectingLines =
1896 for (
size_t i = 0; i < nIntersectingLines; ++i) {
1898 mpi->TraverseLineSegment(6, -6, 24, -24, polyIds, tValues);
1899 mpi->TraverseLineSegment(7, -6, 25, -24, polyIds, tValues);
1900 mpi->TraverseLineSegment(25, -6, 6, -24, polyIds, tValues);
GmBstPoly3d & GetBoostPoly(int a_polyIdx)
Create and return a boost polygon given a polygon index.
std::vector< std::vector< int > > m_polys
0-based? indices into m_points to form polygons
GmMultiPolyIntersectorQueryEnum m_query
Type of query (intersect, covered by...)
void GetPolysForPoint(Pt3d pt, SetInt &poly)
Find the set of polygons intersected (in or on) by the point.
See GmMultiPolyIntersectorImpl comments.
void testSmsCase1()
This case revealed the need for a tolerance when comparing t values.
static const double XM_DBL_LOWEST
void testMap2MfBug()
We only do the first part: inside to edge.
Functions dealing with triangles.
void ComputeTValues()
Compute t values (0.0 - 1.0) from the intersection.
RtreeBox * m_rtree
Rtree used to find polygons.
GmBstLine3d m_line
Current line segment.
Used to intersect a line segment with any number of polygons in 2D. Returns the intersected polygons ...
void CalculateBuffer()
Calculate a small buffer distance by which we expand all polygon bounding boxes.
virtual void SetQuery(GmMultiPolyIntersectorQueryEnum a_query) override
Set the query to use (covered by, intersects...).
static boost::shared_ptr< GmMultiPolyIntersector > New(const std::vector< Pt3d > &a_points, const std::vector< std::vector< int > > &a_polys, boost::shared_ptr< GmMultiPolyIntersectionSorter > a_sorter, int a_startingId=1)
Creates a new GmMultiPolyIntersectorImpl object.
void IntersectEachPolyWithLine()
Go through results (potential polygons) and intersect each one.
GmMultiPolyIntersectorData m_d
Point and poly data.
void testInsideToInside()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
void testOutsideToOutside()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
An intersection point of a line with a polygon.
std::set< int > m_polys2
polygon IDs (1-based) that 2nd point is inside on on
void testAlongEdgesInsideToInside()
Given 3 x 3 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
void testEndAtEdgeFromAdjacent()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
void SortIntersections()
Does a preliminary sort of the intersections by t value.
void CreateLine()
Creates a boost geom line of the current line segment.
std::vector< int > VecInt
std::vector< GmBstPoly3d > m_boostPolys
Polygons as boost geom polygons.
Pt3d m_pt2
2nd line segment point
void BuildRTree()
Create a boost rtree of polygon extents.
Pt3d m_pt1
1st line segment point
Functions dealing with geometry.
int m_startingId
Offset if polys start at something other than one.
double m_buffer
Small buffer around each bounding box.
std::vector< double > VecDbl
std::set< int > m_polys1
polygon IDs (1-based) that 1st point is inside or on
void testTouchesVertex()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
GmMultiPolyIntersectorImpl(const VecPt3d &a_points, const VecInt2d &a_polys, BSHP< GmMultiPolyIntersectionSorter > a_sorter, int a_startingId=1)
constructor
virtual int PolygonFromPoint(const Pt3d &a_pt) override
Finds the polygon containing the point.
BSHP< GmMultiPolyIntersectionSorter > m_sorter
Sorter used to process results.
#define XM_ENSURE_TRUE_VOID_NO_ASSERT(...)
void TraverseLineSegmentAll(double a_x1, double a_y1, double a_x2, double a_y2, VecInt &a_polyids, VecDbl &a_tvalues, std::vector< Pt3d > &a_pts)
Intersect segment with polys and save intersected polys, t-values, and intersection points...
std::vector< Pt3d > VecPt3d
void PointsOnSegment(const GmBstPoly3d &a_poly, const GmBstLine3d &a_line, std::deque< Pt3d > &a_output)
Check if the points on the outside of the polygon lie on the line segment.
std::vector< ix > m_ixs
Intersections.
void Set(T a_x, T a_y, T a_z)
Struct used by GmMultiPolyIntersector.
void OffsetPolyIds(VecInt &polyIds) const
If polygon IDs should start at something other than 1, we handle that here.
void EnsureEndPointsRepresented()
Because unfortunately intersecting the line with the poly doesn't always create an intersection if a ...
std::vector< VecInt > VecInt2d
void testStartAtEdgeThroughAdjacent()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
Class for sorting intersections from GmMultiPolyIntersector in a terse way (with no duplicate info)...
virtual void TraverseLineSegment(double x1, double y1, double x2, double y2, VecInt &polyids, VecDbl &tvalues) override
Intersect segment with polys and save intersected polys and t-values.
void testInsideToEdgeThenThroughAdjacent()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
void BufferTheBox(GmBstBox3d &box) const
Because the rtree intersection fails in some cases where the line is on an edge, we slightly expand t...
void testTouchesEdge()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
void testAlongEdgesOutsideToOutside()
Given 3 x 3 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
void testEdgeThroughOppositeVertexAtAngle()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
std::vector< Pt3d > m_points
All points used by all polygons.
static const double XM_DBL_HIGHEST
void BuildBoostPoly(int a_polyIdx, GmBstPoly3d &a_boostPoly) const
Build a boost polygon given a polygon index.