From ecbb621171af0f20751bbc590453d00a7bd38320 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 9 Feb 2025 15:18:35 +0000 Subject: Move lots of geoData helpers into lib --- lib/maths.h | 46 +++++++++++++++++++++++++++++++++++++++++++--- lib/triangle.h | 27 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/maths.h b/lib/maths.h index 3d4f440..2049c78 100644 --- a/lib/maths.h +++ b/lib/maths.h @@ -14,6 +14,9 @@ template concept Arithmetic = std::is_arithmetic_v; +template using CalcType = std::conditional_t, T, int64_t>; +template using DifferenceType = std::conditional_t, T, float>; + struct Arc : public std::pair { template requires(Lc >= 2, Le >= 2) @@ -102,7 +105,7 @@ operator-(const GlobalPosition & global, const CalcPosition & relative) } template -using DifferenceVector = glm::vec, T, float>, Q>; +using DifferenceVector = glm::vec, Q>; template constexpr DifferenceVector @@ -111,6 +114,16 @@ difference(const glm::vec & globalA, const glm::vec & globalB) return globalA - globalB; } +template +using CalcVector = glm::vec, Q>; + +template +constexpr CalcVector +calcDifference(const glm::vec & globalA, const glm::vec & globalB) +{ + return globalA - globalB; +} + template constexpr auto distance(const glm::vec & pointA, const glm::vec & pointB) @@ -364,8 +377,6 @@ normalize(T ang) return ang; } -template using CalcType = std::conditional_t, T, int64_t>; - template [[nodiscard]] constexpr std::optional> linesIntersectAt(const glm::vec<2, T, Q> Aabs, const glm::vec<2, T, Q> Babs, const glm::vec<2, T, Q> Cabs, @@ -547,3 +558,32 @@ ArcSegment::crossesLineAt(const glm::vec<2, T, Q> & lineStart, const glm:: }); return std::make_pair(centre + first.first, first.second); } + +namespace { + template typename Op> + [[nodiscard]] constexpr auto + pointLineOp(const GlobalPosition2D point, const GlobalPosition2D end1, const GlobalPosition2D end2) + { + return Op {}(CalcDistance(end2.x - end1.x) * CalcDistance(point.y - end1.y), + CalcDistance(end2.y - end1.y) * CalcDistance(point.x - end1.x)); + } +} + +constexpr auto pointLeftOfLine = pointLineOp; +constexpr auto pointLeftOfOrOnLine = pointLineOp; + +[[nodiscard]] constexpr bool +linesCross(const GlobalPosition2D lineAend1, const GlobalPosition2D lineAend2, const GlobalPosition2D lineBend1, + const GlobalPosition2D lineBend2) +{ + return (pointLeftOfLine(lineAend2, lineBend1, lineBend2) == pointLeftOfLine(lineAend1, lineBend2, lineBend1)) + && (pointLeftOfLine(lineBend1, lineAend1, lineAend2) == pointLeftOfLine(lineBend2, lineAend2, lineAend1)); +} + +[[nodiscard]] constexpr bool +linesCrossLtR(const GlobalPosition2D lineAend1, const GlobalPosition2D lineAend2, const GlobalPosition2D lineBend1, + const GlobalPosition2D lineBend2) +{ + return pointLeftOfLine(lineAend2, lineBend1, lineBend2) && pointLeftOfLine(lineAend1, lineBend2, lineBend1) + && pointLeftOfLine(lineBend1, lineAend1, lineAend2) && pointLeftOfLine(lineBend2, lineAend2, lineAend1); +} diff --git a/lib/triangle.h b/lib/triangle.h index e430653..abd697c 100644 --- a/lib/triangle.h +++ b/lib/triangle.h @@ -64,6 +64,12 @@ struct Triangle : public glm::vec<3, glm::vec> { return difference(p(side), p(0)); } + [[nodiscard]] constexpr auto + calcSideDifference(glm::length_t side) const + { + return calcDifference(p(side), p(0)); + } + [[nodiscard]] constexpr auto angle(glm::length_t corner) const { @@ -126,4 +132,25 @@ struct Triangle : public glm::vec<3, glm::vec> { { return begin() + 3; } + + [[nodiscard]] + constexpr auto + positionOnPlane(const glm::vec<2, T, Q> coord2d) const + requires(Dim == 3) + { + const auto edgeCrossProduct = crossProduct(calcSideDifference(1), calcSideDifference(2)); + return coord2d + || static_cast( + ((edgeCrossProduct.x * p(0).x) + (edgeCrossProduct.y * p(0).y) + (edgeCrossProduct.z * p(0).z) + - (edgeCrossProduct.x * coord2d.x) - (edgeCrossProduct.y * coord2d.y)) + / edgeCrossProduct.z); + } + + [[nodiscard]] + constexpr bool + containsPoint(const GlobalPosition2D coord) const + { + return pointLeftOfOrOnLine(coord, p(0), p(1)) && pointLeftOfOrOnLine(coord, p(1), p(2)) + && pointLeftOfOrOnLine(coord, p(2), p(0)); + } }; -- cgit v1.2.3