summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/maths.h46
-rw-r--r--lib/triangle.h27
2 files changed, 70 insertions, 3 deletions
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<typename T>
concept Arithmetic = std::is_arithmetic_v<T>;
+template<Arithmetic T> using CalcType = std::conditional_t<std::is_floating_point_v<T>, T, int64_t>;
+template<Arithmetic T> using DifferenceType = std::conditional_t<std::is_floating_point_v<T>, T, float>;
+
struct Arc : public std::pair<Angle, Angle> {
template<glm::length_t Lc, glm::length_t Le, Arithmetic T, glm::qualifier Q = glm::defaultp>
requires(Lc >= 2, Le >= 2)
@@ -102,7 +105,7 @@ operator-(const GlobalPosition<D> & global, const CalcPosition<D> & relative)
}
template<glm::length_t D, Arithmetic T, glm::qualifier Q = glm::defaultp>
-using DifferenceVector = glm::vec<D, std::conditional_t<std::is_floating_point_v<T>, T, float>, Q>;
+using DifferenceVector = glm::vec<D, DifferenceType<T>, Q>;
template<glm::length_t D, Arithmetic T, glm::qualifier Q = glm::defaultp>
constexpr DifferenceVector<D, T, Q>
@@ -112,6 +115,16 @@ difference(const glm::vec<D, T, Q> & globalA, const glm::vec<D, T, Q> & globalB)
}
template<glm::length_t D, Arithmetic T, glm::qualifier Q = glm::defaultp>
+using CalcVector = glm::vec<D, CalcType<T>, Q>;
+
+template<glm::length_t D, Arithmetic T, glm::qualifier Q = glm::defaultp>
+constexpr CalcVector<D, T, Q>
+calcDifference(const glm::vec<D, T, Q> & globalA, const glm::vec<D, T, Q> & globalB)
+{
+ return globalA - globalB;
+}
+
+template<glm::length_t D, Arithmetic T, glm::qualifier Q = glm::defaultp>
constexpr auto
distance(const glm::vec<D, T, Q> & pointA, const glm::vec<D, T, Q> & pointB)
{
@@ -364,8 +377,6 @@ normalize(T ang)
return ang;
}
-template<Arithmetic T> using CalcType = std::conditional_t<std::is_floating_point_v<T>, T, int64_t>;
-
template<Arithmetic T, glm::qualifier Q = glm::defaultp>
[[nodiscard]] constexpr std::optional<glm::vec<2, T, Q>>
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<T, Q>::crossesLineAt(const glm::vec<2, T, Q> & lineStart, const glm::
});
return std::make_pair(centre + first.first, first.second);
}
+
+namespace {
+ template<template<typename> 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<std::greater>;
+constexpr auto pointLeftOfOrOnLine = pointLineOp<std::greater_equal>;
+
+[[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
@@ -65,6 +65,12 @@ struct Triangle : public glm::vec<3, glm::vec<Dim, T, Q>> {
}
[[nodiscard]] constexpr auto
+ calcSideDifference(glm::length_t side) const
+ {
+ return calcDifference(p(side), p(0));
+ }
+
+ [[nodiscard]] constexpr auto
angle(glm::length_t corner) const
{
return Arc {P(corner), P(corner + 2), P(corner + 1)}.length();
@@ -126,4 +132,25 @@ struct Triangle : public glm::vec<3, glm::vec<Dim, T, Q>> {
{
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<T>(
+ ((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));
+ }
};