19 #pragma warning(disable : 4512) // boost code: no assignment operator 20 #include <boost/geometry.hpp> 21 #include <boost/geometry/geometries/linestring.hpp> 22 #include <boost/geometry/geometries/point_xy.hpp> 23 #include <boost/geometry/geometries/polygon.hpp> 24 #include <boost/geometry/index/rtree.hpp> 44 namespace bg = boost::geometry;
45 namespace bgi = boost::geometry::index;
57 typedef bgi::rtree<ValueBox, bgi::quadratic<8>>
RtreeBox;
67 BSHP<GmMultiPolyIntersectionSorter> a_sorter,
68 int a_startingId = 1);
77 VecDbl& a_tValues)
override;
82 VecInt& a_polyIds)
override;
114 std::deque<Pt3d>& a_output);
139 GmMultiPolyIntersector::GmMultiPolyIntersector()
145 GmMultiPolyIntersector::~GmMultiPolyIntersector()
162 BSHP<GmMultiPolyIntersectionSorter> a_sorter,
165 return BDPC<GmMultiPolyIntersector>(BSHP<GmMultiPolyIntersectorImpl>(
187 BSHP<GmMultiPolyIntersectionSorter> a_sorter,
195 , m_startingId(a_startingId)
198 , m_query(GMMPIQ_COVEREDBY)
213 GmMultiPolyIntersectorImpl::~GmMultiPolyIntersectorImpl()
240 Pt3d mn(XM_DBL_HIGHEST), mx(XM_DBL_LOWEST);
241 for (
size_t i = 0; i <
m_d.
m_polys.size(); ++i)
243 for (
size_t j = 0; j <
m_d.
m_polys[i].size(); ++j)
250 const double kFraction = 1e-5;
291 for (
int j = 0; j < (int)poly.size(); ++j)
294 bg::exterior_ring(a_boostPoly).push_back(
m_d.
m_points[poly[j]]);
296 bg::exterior_ring(a_boostPoly).push_back(
m_d.
m_points[poly[0]]);
313 std::vector<ValueBox> boxen;
315 for (
int i = 0; i < (int)
m_d.
m_polys.size(); ++i)
317 Pt3d mn(XM_DBL_HIGHEST), mx(XM_DBL_LOWEST);
318 for (
int j = 0; j < (int)
m_d.
m_polys[i].size(); ++j)
325 boxen.push_back(std::make_pair(
box, i));
355 std::vector<ValueBox> result;
356 m_rtree->query(bgi::intersects(pt), std::back_inserter(result));
359 for (
size_t i = 0; i < result.size(); ++i)
366 case GMMPIQ_COVEREDBY:
367 rv = bg::covered_by(pt, poly);
369 case GMMPIQ_INTERSECTS:
370 rv = bg::intersects(pt, poly);
378 a_poly.insert(result[i].second + 1);
389 std::vector<ValueBox> result;
390 m_rtree->query(bgi::intersects(
m_line), std::back_inserter(result));
398 for (
size_t i = 0; i < result.size(); ++i)
401 std::deque<Pt3d> output;
402 bg::intersection(poly,
m_line, output);
403 if (2 > output.size())
405 for (
size_t j = 0; j < output.size(); ++j)
407 ix ixn(output[j], result[i].second + 1,
XM_NODATA);
421 std::deque<Pt3d>& a_output)
424 for (
size_t i = 0; i < a_poly.outer().size(); ++i)
426 const Pt3d& p = a_poly.outer()[i];
430 for (
size_t j = 0; j < a_output.size(); ++j)
436 a_output.push_back(p);
448 for (
size_t i = 0; i <
m_d.
m_ixs.size(); ++i)
474 [](
const ix& a,
const ix& b) ->
bool {
return a.
m_t < b.m_t; });
487 for (
size_t i = 0; i <
m_d.
m_ixs.size() && !found &&
m_d.
m_ixs[i].m_t == 0.0; ++i)
500 for (
size_t i =
m_d.
m_ixs.size(); i-- > 0 && !found &&
m_d.
m_ixs[i].m_t == 1.0;)
519 for (
int i = 0; i < (int)polyIds.size() - 1; ++i)
523 polyIds[i] += offset;
622 double oldTolerance =
gmXyTol();
640 m_sorter->Sort(
m_d, a_polyIds, a_tValues, a_pts, kTol);
670 int size((
int)a_tValues.size());
671 for (
int i = size - 1; i > 0; --i)
676 for (
int j = i - 1; j > 0; --j)
681 a_polyIds[i] == a_polyIds[j])
682 indexesToRemove.push_back(j);
685 else if (a_polyIds[i] == -1 && a_polyIds[i - 1] == -1)
688 for (
int j = i - 1; j > 0; --j)
695 indexesToRemove.push_back(j);
701 if (!indexesToRemove.empty())
703 auto it = std::unique(indexesToRemove.begin(), indexesToRemove.end());
704 indexesToRemove.resize(std::distance(indexesToRemove.begin(), it));
705 for (
auto&& i : indexesToRemove)
707 a_polyIds.erase(a_polyIds.begin() + i);
708 a_tValues.erase(a_tValues.begin() + i);
709 a_pts.erase(a_pts.begin() + i);
725 rval = (int)*polys.begin();
744 #include <xmsgrid/ugrid/XmEdge.h> 758 void iRunTest(
double x1,
764 const VecInt& a_expectedPolyIDs,
765 const VecDbl& a_expectedtValues,
766 const VecPt3d& a_expectedPoints)
768 BSHP<GmMultiPolyIntersectionSorter> sorter =
771 VecInt polyIds1, polyIds2, polyIds3, polyIds4;
772 VecDbl tValues1, tValues2;
774 mpi->TraverseLineSegment(x1, y1, x2, y2, polyIds1, tValues1);
775 mpi->TraverseLineSegment(x1, y1, x2, y2, polyIds2);
776 mpi->TraverseLineSegment(x1, y1, x2, y2, polyIds3, points1);
777 mpi->TraverseLineSegment(x1, y1, x2, y2, polyIds4, tValues2, points2);
782 TS_ASSERT_EQUALS(polyIds1.size(), tValues1.size());
783 TS_ASSERT_EQUALS(polyIds1.size(), points1.size());
784 TS_ASSERT_EQUALS(polyIds1.size(), polyIds2.size());
785 TS_ASSERT_EQUALS(polyIds1.size(), polyIds3.size());
786 TS_ASSERT_EQUALS(polyIds1.size(), polyIds4.size());
787 TS_ASSERT_EQUALS(tValues1.size(), tValues2.size());
788 TS_ASSERT_EQUALS(points1.size(), points2.size());
789 const double kDelta = 1e-5;
818 VecPt3d pts = {{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
820 VecInt expectedIds = {1, -1};
821 VecDbl expectedTvals = {0.0833333, 0.916667};
822 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
823 iRunTest(-1, 5, 11, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
842 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
844 VecInt expectedIds{1, -1};
845 VecDbl expectedTvals{0.111111, 1.0};
846 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {8.0, 5.0, 0.0}};
847 iRunTest(-1, 5, 8, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
866 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
868 VecInt expectedIds{1, -1};
869 VecDbl expectedTvals{0.0, 0.833333};
870 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
871 iRunTest(5, 5, 11, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
890 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
892 VecInt expectedIds{1, -1};
893 VecDbl expectedTvals{0.0, 1.0};
894 VecPt3d expectedPoints = {{2.0, 5.0, 0.0}, {8.0, 5.0, 0.0}};
895 iRunTest(2, 5, 8, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
914 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
916 VecInt expectedIds{1, -1};
917 VecDbl expectedTvals{0.0, 1.0};
918 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
919 iRunTest(0, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
938 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
940 VecInt expectedIds{1, -1};
941 VecDbl expectedTvals{0.0, 1.0};
942 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {5.0, 5.0, 0.0}};
943 iRunTest(0, 5, 5, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
962 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
964 VecInt expectedIds{1, -1};
965 VecDbl expectedTvals{0.0, 1.0};
966 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
967 iRunTest(5, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
986 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
988 VecInt expectedIds{1, -1};
989 VecDbl expectedTvals{1.0, 1.0};
990 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {0.0, 5.0, 0.0}};
991 iRunTest(-1, 5, 0, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1010 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1012 VecInt expectedIds{1, -1};
1013 VecDbl expectedTvals{0.0, 0.0};
1014 VecPt3d expectedPoints = {{10.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
1015 iRunTest(10, 5, 11, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1034 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1036 VecInt expectedIds{1, -1};
1037 VecDbl expectedTvals{0.0, 1.0};
1038 VecPt3d expectedPoints = {{3.0, 10.0, 0.0}, {7.0, 10.0, 0.0}};
1039 iRunTest(3, 10, 7, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1058 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1060 VecInt expectedIds{1, -1};
1061 VecDbl expectedTvals{0.0, 1.0};
1062 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {10.0, 10.0, 0.0}};
1063 iRunTest(0, 10, 10, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1082 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1084 VecInt expectedIds{1, -1};
1085 VecDbl expectedTvals{0.0833333, 0.9166667};
1086 VecPt3d expectedPoints = {{10.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
1089 iRunTest(11, 10, -1, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1108 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1110 VecInt expectedIds{1, -1};
1111 VecDbl expectedTvals{0.166667, 1.0};
1112 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {5.0, 10.0, 0.0}};
1113 iRunTest(-1, 10, 5, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1114 expectedTvals = {0.0, 5 / 6.0};
1115 expectedPoints = {{5.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
1116 iRunTest(5, 10, -1, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1120 expectedTvals = {1.0 / 3.0, 1.0};
1121 expectedPoints = {{10.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
1122 iRunTest(15, 10, 0, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1140 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1142 VecInt expectedIds{1, -1};
1143 VecDbl expectedTvals{0.0, 0.833333};
1144 VecPt3d expectedPoints = {{5.0, 10.0, 0.0}, {10.0, 10.0, 0.0}};
1145 iRunTest(5, 10, 11, 10, pts, polys, expectedIds, expectedTvals,
1167 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1169 VecInt expectedIds{1, -1};
1170 VecDbl expectedTvals{1.0, 1.0};
1171 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
1172 iRunTest(-1, 10, 0, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1192 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1194 VecInt expectedIds{1, -1};
1195 VecDbl expectedTvals{0.5, 0.5};
1196 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
1197 iRunTest(-1, 9, 1, 11, pts, polys, expectedIds, expectedTvals, expectedPoints);
1217 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1222 iRunTest(-1, 10, 0, 11, pts, polys, expectedIds, expectedTvals, expectedPoints);
1241 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1243 VecInt expectedIds{1, -1};
1244 VecDbl expectedTvals{0.0, 1.0};
1245 VecPt3d expectedPoints = {{0.0, 10.0, 0.0}, {5.0, 10.0, 0.0}};
1246 iRunTest(0, 10, 5, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1265 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {10, 10, 0}, {0, 10, 0}};
1267 VecInt expectedIds{1, -1};
1268 VecDbl expectedTvals{0.0, 1.0};
1269 VecPt3d expectedPoints = {{5.0, 10.0, 0.0}, {10.0, 10.0, 0.0}};
1270 iRunTest(5, 10, 10, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1289 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1291 VecInt expectedIds{1, -1};
1292 VecDbl expectedTvals{0.0, 1.0};
1293 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
1294 iRunTest(0, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1313 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1315 VecInt expectedIds{1, -1};
1316 VecDbl expectedTvals{0.0, 1.0};
1317 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
1318 iRunTest(5, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1337 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1338 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1339 VecInt expectedIds{1, -1};
1340 VecDbl expectedTvals{0.0, 1.0};
1341 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}};
1342 iRunTest(5, 5, 10, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1361 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1362 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1363 VecInt expectedIds{1, 2, -1};
1364 VecDbl expectedTvals{0.0454545, 0.5, 0.954545};
1365 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}, {20.0, 5.0, 0.0}};
1366 iRunTest(-1, 5, 21, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1385 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1386 VecInt2d polys = {{{0, 1, 4, 3}}, {1, 2, 5, 4}};
1387 VecInt expectedIds{1, 2, -1};
1388 VecDbl expectedTvals{0.0625, 0.6875, 1.0};
1389 VecPt3d expectedPoints = {{0.0, 5.0, 0.0}, {10.0, 5.0, 0.0}, {15.0, 5.0, 0.0}};
1390 iRunTest(-1, 5, 15, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1409 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1410 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1411 VecInt expectedIds{1, 2, -1};
1412 VecDbl expectedTvals{0.0, 0.3125, 0.9375};
1413 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}, {20.0, 5.0, 0.0}};
1414 iRunTest(5, 5, 21, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1433 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1434 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1435 VecInt expectedIds{1, 2, -1};
1436 VecDbl expectedTvals{0.0, 0.5, 1.0};
1437 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 5.0, 0.0}, {15.0, 5.0, 0.0}};
1438 iRunTest(5, 5, 15, 5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1456 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1457 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1458 VecInt expectedIds{1, -1};
1459 VecDbl expectedTvals{0.0, 1.0};
1460 VecPt3d expectedPoints = {{5.0, 10.0, 0.0}, {10.0, 10.0, 0.0}};
1461 iRunTest(5, 10, 10, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1479 VecPt3d pts{{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {0, 10, 0}, {10, 10, 0}, {20, 10, 0}};
1480 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1481 VecInt expectedIds{2, -1};
1482 VecDbl expectedTvals{0.0, 1.0};
1483 VecPt3d expectedPoints = {{10.0, 10.0, 0.0}, {15.0, 10.0, 0.0}};
1484 iRunTest(10, 10, 15, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1508 VecPt3d pts{{0, 0, 100}, {10, 0, 110}, {20, 0, 105}, {0, 10, 104}, {10, 10, 103}, {20, 10, 106}};
1509 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1510 VecInt expectedIds{1, 2, -1};
1511 VecDbl expectedTvals = {0.0, 1 / 3.0, 1};
1512 VecPt3d expectedPoints = {{5.0, 10.0, 0.0}, {10.0, 10.0, 0.0}, {20.0, 10.0, 0.0}};
1513 iRunTest(5, 10, 20, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1514 expectedIds = {2, 1, -1};
1515 expectedPoints = {{15.0, 10.0, 0.0}, {10.0, 10.0, 0.0}, {0.0, 10.0, 0.0}};
1516 iRunTest(15, 10, 0, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1534 VecPt3d pts{{0, 0, 100}, {10, 0, 110}, {20, 0, 105}, {0, 10, 104}, {10, 10, 103}, {20, 10, 106}};
1535 VecInt2d polys = {{0, 1, 4, 3}, {1, 2, 5, 4}};
1536 VecInt expectedIds{1, -1};
1537 VecDbl expectedTvals = {0.0, 1};
1538 VecPt3d expectedPoints = {{5.0, 5.0, 0.0}, {10.0, 0.0, 0.0}};
1539 iRunTest(5, 5, 10, 0, pts, polys, expectedIds, expectedTvals, expectedPoints);
1540 expectedIds = {2, -1};
1541 expectedPoints = {{15.0, 5.0, 0.0}, {10.0, 10.0, 0.0}};
1542 iRunTest(15, 5, 10, 10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1573 VecPt3d pts{{104.346, -300.604, 48.558}, {105.148, -298.88, 48.225}, {105.994, -297.142, 47.225},
1574 {110.439, -299.669, 48.533}, {109.543, -301.391, 47.2}, {108.738, -303.082, 47.867},
1575 {113.06, -305.811, 47.175}, {113.886, -304.089, 48.175}};
1576 VecInt2d polys = {{0, 5, 4, 1}, {1, 4, 3, 2}, {4, 7, 3}, {5, 6, 7, 4}};
1577 VecInt expectedIds{2, -1};
1578 VecDbl expectedTvals = {0.0, 1};
1579 VecPt3d expectedPoints = {{107.769, -299.267, 0.0}, {109.543, -301.391, 0.0}};
1580 iRunTest(107.769, -299.267, 109.543, -301.391, pts, polys, expectedIds, expectedTvals,
1582 expectedIds = {4, -1};
1583 expectedPoints = {{109.543, -301.391, 0.0}, {111.302, -303.601, 0.0}};
1584 iRunTest(109.543, -301.391, 111.302, -303.601, pts, polys, expectedIds, expectedTvals,
1617 {263.313, -361.915, 47.375}, {263.914, -360.497, 46.375}, {264.582, -358.729, 48.375},
1618 {269.892, -359.609, 48.35}, {269.228, -361.033, 46.35}, {268.569, -362.502, 47.35},
1619 {273.694, -363.319, 47.325}, {274.372, -361.835, 46.325}, {275.054, -360.401, 48.325}};
1620 VecInt2d polys = {{0, 5, 4, 1}, {1, 4, 3, 2}, {4, 7, 8, 3}, {5, 6, 7, 4}};
1621 VecInt expectedIds{2, -1};
1622 VecDbl expectedTvals = {0.0, 1};
1623 VecPt3d expectedPoints = {{266.571, -360.765, 0.0}, {269.228, -361.033, 46.35}};
1624 iRunTest(266.57100000000003, -360.76499999999999, 269.22800000000001, -361.03300000000002, pts,
1625 polys, expectedIds, expectedTvals, expectedPoints);
1649 VecPt3d pts{{0, 10, 0}, {10, 10, 0}, {10, 20, 0}, {0, 20, 0},
1650 {10, 0, 0}, {20, 0, 0}, {20, 10, 0}};
1651 VecInt2d polys = {{0, 1, 2, 3}, {4, 5, 6, 1}};
1652 VecInt expectedIds = {1, -1, 2, -1};
1653 VecDbl expectedTvals = {0.0, 0.2, 0.8, 1.0};
1655 {8.0, 18.0, 0.0}, {10.0, 16.0, 0.0}, {16.0, 10.0, 0.0}, {18.0, 8.0, 0.0}};
1656 iRunTest(8, 18, 18, 8, pts, polys, expectedIds, expectedTvals, expectedPoints);
1682 VecInt expectedIds{4, 3, 5, 6, -1};
1683 VecDbl expectedTvals{0.0, 0.166666, 0.5, 0.833333, 1.0};
1684 VecPt3d expectedPoints = {{5.0, -2.5, 0.0},
1685 {6.6666666666667, -3.333333333333, 0.0},
1687 {13.333333333333, -6.666666666667, 0.0},
1689 iRunTest(5, -2.5, 15, -7.5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1715 VecInt expectedIds{1, 4, 3, 5, 6, 7, -1};
1716 VecDbl expectedTvals{0.0454545, 0.0833333, 0.34375, 0.5, 0.65625, 0.916667, 0.954545};
1717 VecPt3d expectedPoints = {{0.0, -0.454545454545, 0.0}, {0.8333333333333, -0.833333333333, 0.0},
1718 {6.5625, -3.4375, 0.0}, {10.0, -5.0, 0.0},
1719 {13.4375, -6.5625, 0.0}, {19.166666666667, -9.166666666667, 0.0},
1720 {20.0, -9.545454545455, 0.0}};
1721 iRunTest(-1, 0, 21, -10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1751 iRunTest(1, 1, -1, -1, pts, polys, expectedIds, expectedTvals, expectedPoints);
1774 TS_SKIP(
"GREENBUILD: This test does not pass on Linux builds.");
1779 VecInt expectedIds{1, -1};
1780 VecDbl expectedTvals{1.0, 1.0};
1781 VecPt3d expectedPoints = {{0.0, -2.0, 0.0}, {0.0, -2.0, 0.0}};
1782 iRunTest(-1, -1, 0, -2, pts, polys, expectedIds, expectedTvals, expectedPoints);
1829 VecInt expectedIds{2, 17, 18, 33, -1};
1830 VecDbl expectedTvals{0.0, 0.22222, 0.5, 0.777778, 1.0};
1831 VecPt3d expectedPoints = {{6.0, -6.0, 0.0},
1835 {24.0, -24.0, 0.0}};
1836 iRunTest(6, -6, 24, -24, pts, polys, expectedIds, expectedTvals, expectedPoints);
1873 VecInt expectedIds{16, 20, 24, -1};
1874 VecDbl expectedTvals{0.016129032258064516, 0.33870967741935482, 0.66129032258064513,
1875 0.98387096774193550};
1877 {0.0, -10.0, 0.0}, {10.0, -10.0, 0.0}, {20.0, -10.0, 0.0}, {30.0, -10.0, 0.0}};
1878 iRunTest(-0.5, -10, 30.5, -10, pts, polys, expectedIds, expectedTvals, expectedPoints);
1909 VecInt expectedIds{3, 5, 7, -1};
1910 VecDbl expectedTvals{0.0, 0.14285714285714288, 0.5, 0.85714285714285721};
1911 VecPt3d expectedPoints = {{8.0, -2.5, 0.0},
1912 {10.0, -3.214285714286, 0.0},
1914 {20.0, -6.785714285714, 0.0}};
1915 iRunTest(8, -2.5, 22, -7.5, pts, polys, expectedIds, expectedTvals, expectedPoints);
1947 VecInt expectedIds{5, 8, -1};
1948 VecDbl expectedTvals{0.0, 0.4, 0.8};
1949 VecPt3d expectedPoints = {{10.0, -8.0, 0.0}, {14.0, -4.0, 0.0}, {18.0, 0.0, 0.0}};
1950 iRunTest(10, -8, 20, 2, pts, polys, expectedIds, expectedTvals, expectedPoints);
1976 TS_SKIP(
"GREENBUILD: This test does not pass on Linux builds.");
1985 VecInt expectedIds{3, -1};
1986 VecDbl expectedTvals{0.0, 1.0};
1987 VecPt3d expectedPoints = {{9.0, -5.0, 0.0}, {10.0, -8.0, 0.0}};
1988 iRunTest(9, -5, 10, -8, pts, polys, expectedIds, expectedTvals, expectedPoints);
1997 VecPt3d pts{{1937.0003414079, 11829.937474193, 0.0}, {1947.0331979019, 11744.658193995, 0.0},
1998 {1806.3085553039, 11640.957366058, 0.0}, {1827.8055464927, 11817.091027732, 0.0},
1999 {2046.1951363232, 11842.783920654, 0.0}, {2155.4908205085, 11854.643944679, 0.0},
2000 {2160.8354359402, 11805.390806652, 0.0}, {2070.1604445251, 11710.224742147, 0.0}};
2002 polys[0] = {0, 3, 2, 1};
2003 polys[1] = {0, 1, 7, 6, 5, 4};
2005 const double t = 0.41350462827872492;
2006 VecInt expectedIds{2, 1, -1};
2007 VecDbl expectedTvals{0.0, .5, 1.0};
2008 VecPt3d expectedPoints = {{2046.1951363232, 11842.783920654, 0.00000000000000000},
2009 {1937.0003414079, 11829.937474193, 0.00000000000000000},
2010 {1827.8055464927, 11817.091027732, 0.00000000000000000}};
2011 iRunTest(2046.1951363232, 11842.783920654, 1827.8055464927, 11817.091027732, pts, polys,
2012 expectedIds, expectedTvals, expectedPoints);
2013 expectedIds = {1, 2, -1};
2014 expectedTvals = {0.0, .5, 1};
2015 expectedPoints = {{1827.8055464927, 11817.091027732, 0.0},
2016 {1937.0003414079, 11829.937474193, 0.0},
2017 {2046.1951363232, 11842.783920654, 0.0}};
2018 iRunTest(1827.8055464927, 11817.091027732, 2046.1951363232, 11842.783920654, pts, polys,
2019 expectedIds, expectedTvals, expectedPoints);
2050 VecInt expectedIds{8, 5, -1};
2051 VecDbl expectedTvals{0.2, 0.6, 1.0};
2052 VecPt3d expectedPoints = {{18.0, 0.0}, {14.0, -4.0, 0.0}, {10.0, -8.0, 0.0}};
2053 iRunTest(20, 2, 10, -8, pts, polys, expectedIds, expectedTvals, expectedPoints);
2061 {-39.719999999999999, 90.079999999999998, 0.0}, {-21.129999999999999, 90.469999999999999, 1.0},
2062 {-38.930000000000000, 75.840000000000003, 2.0}, {-20.539999999999999, 76.629999999999995, 3.0},
2063 {-39.719999999999999, 62.000000000000000, 4.0}, {-20.539999999999999, 61.609999999999999, 5.0},
2064 {-40.509999999999998, 47.770000000000003, 6.0}, {-20.150000000000002, 46.579999999999998, 7.0},
2065 {-41.100000000000001, 30.370000000000001, 8.0}, {-19.550000000000001, 29.379999999999999, 9.0}};
2067 polys[0] = {7, 5, 6};
2068 polys[1] = {3, 2, 5};
2069 polys[2] = {2, 3, 1};
2070 polys[3] = {9, 7, 8};
2071 polys[4] = {7, 6, 8};
2072 polys[5] = {0, 2, 1};
2073 polys[6] = {5, 2, 4};
2074 polys[7] = {4, 6, 5};
2076 VecInt expectedIds{6, 3, 2, 7, 8, 1, 5, 4, -1};
2077 VecDbl expectedTvals{0.065777232109665892, 0.18968813237387866, 0.26837085508795250,
2078 0.35199491192297022, 0.47395399691316503, 0.58799734941084614,
2079 0.68358069055240822, 0.81969307266961533, 0.93250275302111885};
2081 {-31.97119143306, 90.242562417488, 0.0}, {-31.8980840019, 81.619602868102, 0.0},
2082 {-31.8516611955, 76.144072194429, 0.0}, {-31.80232300197, 70.32467407928, 0.0},
2083 {-31.73036714182, 61.837541354813, 0.0}, {-31.66308156385, 53.901264454499, 0.0},
2084 {-31.60668739257, 47.249619744458, 0.0}, {-31.52638108712, 37.777559072921, 0.0},
2085 {-31.45982337572, 29.92713341726, 0.0}};
2086 iRunTest(-32.009999999999998, 94.819999999999993, -31.420000000000002, 25.230000000000000, pts,
2087 polys, expectedIds, expectedTvals, expectedPoints);
2112 VecInt expectedIds{2, 17, 18, 33, -1};
2113 VecDbl expectedTvals{0.0, 0.22222, 0.5, 0.777778, 1.0};
2114 VecPt3d expectedPoints = {{6.0, -6.0, 0.0},
2118 {24.0, -24.0, 0.0}};
2119 iRunTest(6, -6, 24, -24, pts, polys, expectedIds, expectedTvals, expectedPoints);
2137 VecInt expectedIds = {2, 17, 18, 33, -1};
2138 VecDbl expectedTvals = {0.0, 0.22222, 0.5, 0.777778, 1.0};
2139 BSHP<GmMultiPolyIntersectionSorter> sorter =
2144 const int nIntersectingLines =
2146 for (
size_t i = 0; i < nIntersectingLines; ++i)
2149 mpi->TraverseLineSegment(6, -6, 24, -24, polyIds, tValues);
2150 mpi->TraverseLineSegment(7, -6, 25, -24, polyIds, tValues);
2151 mpi->TraverseLineSegment(25, -6, 6, -24, polyIds, tValues);
2163 std::string testFilesPath(XMS_TEST_PATH);
2164 std::ifstream input(testFilesPath +
"bug12586.xmc", std::ios_base::binary);
2166 std::string header = binary ?
"Binary " :
"ASCII ";
2167 header +=
"UGrid2d Version 1";
2173 xms::VecInt2d cellPolys;
2174 cellPolys.assign(xmGrid->GetCellCount(), xms::VecInt());
2175 for (
int cellIdx = 0; cellIdx < xmGrid->GetCellCount(); ++cellIdx)
2177 xms::VecInt& polygon = cellPolys[cellIdx];
2178 polygon.reserve(xmGrid->GetCellEdgeCount(cellIdx));
2179 for (
int edgeIdx = 0; edgeIdx < xmGrid->GetCellEdgeCount(cellIdx); ++edgeIdx)
2182 xms::XmEdge pairIdx = xmGrid->GetCellEdge(cellIdx, edgeIdx);
2183 polygon.push_back(pairIdx.
GetFirst());
2188 std::vector<int> expectedIds = {15802, 7949, 15802, 15955, 7949, 7948, 15955, 16108, 7948,
2189 7947, 16108, 16261, 7946, 7947, 7946, -1};
2191 std::vector<int> expectedIds = {15802, 7949, 15802, 15955, 7949, 7948, 15955, 16108, 7947,
2192 7948, 16108, 16261, 7946, 7947, 7946, -1};
2194 std::vector<int> expectedIds = {15802, 7949, 15802, 15955, 7948, 7949, 15955, 16108, 7947,
2195 7948, 16261, 16108, 7946, 7947, 7946, -1};
2197 std::vector<xms::Pt3d> expectedPoints =
2198 {{1538860.1699999999, 7379636.5400000000, 0.00000000000000000},
2199 {1538860.1700000018, 7379636.5399999982, 4549.3574218750000},
2200 {1538860.6799999995, 7379637.6599999992, 0.00000000000000000},
2201 {1538860.6799999995, 7379637.6599999992, 0.00000000000000000},
2202 {1538860.6800000020, 7379637.6599999983, 4548.8906250000000},
2203 {1538860.6800000020, 7379637.6599999983, 4548.8906250000000},
2204 {1538861.1899999988, 7379638.7799999975, 0.00000000000000000},
2205 {1538861.1899999988, 7379638.7799999975, 0.00000000000000000},
2206 {1538861.1900000013, 7379638.7799999965, 4548.8012695312500},
2207 {1538861.1900000013, 7379638.7799999965, 4548.8012695312500},
2208 {1538861.6999999990, 7379639.8999999976, 0.00000000000000000},
2209 {1538861.6999999990, 7379639.8999999976, 0.00000000000000000},
2210 {1538861.7000000027, 7379639.8999999966, 4548.7114257812500},
2211 {1538861.7000000027, 7379639.8999999966, 4548.7114257812500},
2212 {1538862.2100000030, 7379641.0199999977, 4548.6220703125000},
2213 {1538862.2099999995, 7379641.0199999986, 0.00000000000000000}};
2214 std::vector<double> expectedTvals = {0.00000000000000000, -1.8755588329223459e-010,
2215 0.24999999983166091, 0.24999999983166091, 0.24999999987509086, 0.24999999987509086,
2216 0.49999999947153817, 0.49999999947153817, 0.49999999951496815, 0.49999999951496815,
2217 0.74999999953418495, 0.74999999953418495, 0.74999999967562048, 0.74999999967562048,
2218 0.99999999991044985, 0.99999999978861531};
2219 iRunTest(1538860.17, 7379636.54, 1538862.21, 7379641.02,
2220 xmGrid->GetLocations(), cellPolys, expectedIds, expectedTvals, expectedPoints);
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.
Contains the XmUGrid Class and supporting data types.
std::vector< int > VecInt
bg::model::box< bPt > box
box
void testSmsCase1()
This case revealed the need for a tolerance when comparing t values.
void testMap2MfBug()
We only do the first part: inside to edge.
double gmXyDistance(double x1, double y1, double x2, double y2)
Compute the 2d distance between 2 points.
bool gmOnLineAndBetweenEndpointsWithTol(const Pt3d &a_pt1, const Pt3d &a_pt2, const double a_x, const double a_y, double a_tol)
determines if (x,y) is on the line passing through p1 & p2 and between p1 & p2.
void BufferTheBox(GmBstBox3d &box) const
Because the rtree intersection fails in some cases where the line is on an edge, we slightly expand t...
GmMultiPolyIntersectorQueryEnum
Type of query.
std::shared_ptr< XmUGrid > XmReadUGridFromStream(std::istream &a_inStream)
Read an XmUGrid from ASCII text from an input stream.
Functions dealing with triangles.
std::vector< double > VecDbl
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 ...
Contains IO functions as well as several utility functions for XmUGrid.
void CalculateBuffer()
Calculate a small buffer distance by which we expand all polygon bounding boxes.
bool gmEqualPointsXY(double x1, double y1, double x2, double y2, double tolerance)
Returns true if the points are equal to within gmXyTol().
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.
bool daReadNamedLine(std::istream &a_inStream, const char *a_name)
virtual void TraverseLineSegment(double a_x1, double a_y1, double a_x2, double a_y2, VecInt &a_polyIds, VecDbl &a_tValues) override
Intersect segment with polys and save intersected polys and t-values.
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.
boost::geometry::model::linestring< Pt3d > GmBstLine3d
Boost line 3d.
double m_xyTol
XY tolerance for computing t-values.
double gmPtDistanceAlongSegment(const Pt3d &a_pt1, const Pt3d &a_pt2, const Pt3d &a_pt, const double a_tol)
Finds the distance along a segment for the location closest to a_pt.
std::vector< GmBstPoly3d > m_boostPolys
Polygons as boost geom polygons.
Pt3d m_pt2
2nd line segment point
std::vector< VecInt > VecInt2d
void testQuadCornersBug12396()
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.
bool GTEQ_TOL(_T A, _U B, _V tol)
double m_buffer
Small buffer around each bounding box.
std::set< int > m_polys1
polygon IDs (1-based) that 1st point is inside or on
bool daLineBeginsWith(std::istream &a_inStream, const std::string &a_text)
void trBuildGridTrianglePolys(int rows, int cols, VecPt3d &a_points, VecInt2d &a_polys)
Create something like this:
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.
double gmComputeXyTol(const Pt3d &a_mn, const Pt3d &a_mx)
Given extents (min, max), compute a tolerance for the xy plane to be used with geometric functions...
#define XM_ENSURE_TRUE_VOID_NO_ASSERT(...)
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.
Two integer values representing an edge of an XmUGrid. By default has a direction. Can be sorted to have minimum index first.
double gmXyTol(bool a_set, double a_value)
Get or set (set first time) global xy tolerance for float operations.
std::vector< ix > m_ixs
Intersections.
void Set(T a_x, T a_y, T a_z)
boost::geometry::model::polygon< Pt3d > GmBstPoly3d
Boost polygon 3d.
boost::geometry::model::box< Pt3d > GmBstBox3d
Boost box 3d.
Struct used by GmMultiPolyIntersector.
void RemoveDuplicateTValues(VecInt &a_polyIds, VecDbl &a_tValues, VecPt3d &a_pts)
Removes duplicate T Values and updates the polygon ID and point vectors.
void BuildBoostPoly(int a_polyIdx, GmBstPoly3d &a_boostPoly) const
Build a boost polygon given a polygon index.
void OffsetPolyIds(VecInt &polyIds) const
If polygon IDs should start at something other than 1, we handle that here.
void gmAddToExtents(const Pt3d &a_pt, Pt3d &a_min, Pt3d &a_max)
Compares a_pt to a_min and a_max. If a_pt is less than a_min or greater than a_max, a_min and a_max are updated.
std::pair< GmBstBox3d, int > ValueBox
Pair used in rtree.
void EnsureEndPointsRepresented()
Because unfortunately intersecting the line with the poly doesn't always create an intersection if a ...
void testStartAtEdgeThroughAdjacent()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
bgi::rtree< ValueBox, bgi::quadratic< 8 > > RtreeBox
Rtree typedef.
Class for sorting intersections from GmMultiPolyIntersector in a terse way (with no duplicate info)...
void testInsideToEdgeThenThroughAdjacent()
Given 1 x 2 2D grid turned into triangles with point at poly center triangles numbered as follows: ...
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: ...
int GetFirst() const
Get the first index.
std::vector< Pt3d > VecPt3d
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.