diff options
-rw-r--r-- | game/geoData.cpp | 15 | ||||
-rw-r--r-- | test/test-geoData.cpp | 2 |
2 files changed, 12 insertions, 5 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp index 70133a9..d092d00 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -155,6 +155,16 @@ namespace { static_assert(linesCrossLtR({1, 1}, {2, 2}, {1, 2}, {2, 1})); static_assert(!linesCrossLtR({2, 2}, {1, 1}, {1, 2}, {2, 1})); + + constexpr GlobalPosition3D + positionOnTriangle(const GlobalPosition2D point, const GeoData::Triangle<3> & t) + { + const glm::vec<3, int64_t> a = t[1] - t[0], b = t[2] - t[0]; + const auto n = crossInt(a, b); + return {point, ((n.x * t[0].x) + (n.y * t[0].y) + (n.z * t[0].z) - (n.x * point.x) - (n.y * point.y)) / n.z}; + } + + static_assert(positionOnTriangle({7, -2}, {{1, 2, 3}, {1, 0, 1}, {-2, 1, 0}}) == GlobalPosition3D {7, -2, 3}); } OpenMesh::FaceHandle @@ -179,10 +189,7 @@ GeoData::findPoint(GlobalPosition2D p, OpenMesh::FaceHandle f) const GlobalPosition3D GeoData::positionAt(const PointFace & p) const { - RelativePosition3D out {}; - const auto t = triangle<3>(p.face(this)); - glm::intersectLineTriangle<RelativePosition3D>({p.point, 0}, up, t[0], t[1], t[2], out); - return {p.point, out[0]}; + return positionOnTriangle(p.point, triangle<3>(p.face(this))); } [[nodiscard]] std::optional<GlobalPosition3D> diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp index cb0466e..164a6a5 100644 --- a/test/test-geoData.cpp +++ b/test/test-geoData.cpp @@ -92,7 +92,7 @@ BOOST_DATA_TEST_CASE(findPositionAt, {{310050000, 490050000}, 33000}, {{310000000, 490050000}, 32700}, {{310050000, 490000000}, 33200}, - {{310750000, 490150000}, 58399}, + {{310750000, 490150000}, 58400}, // midpoints {{310025000, 490025000}, 32900}, {{310025000, 490050000}, 32850}, |