// Ported from georust/geo-types
// https://github.com/georust/geo/blob/main/geo-types/src/geometry/triangle.rs
///|
/// A bounded 2D area whose three vertices are defined by `Coord`s.
pub struct Triangle {
v0 : Coord
v1 : Coord
v2 : Coord
} derive(Eq, Debug, Hash)
///|
/// Stores vertices as-given (no winding normalisation). Semantically equivalent
/// to upstream `Triangle::unchecked_winding`.
pub fn Triangle::Triangle(v0 : Coord, v1 : Coord, v2 : Coord) -> Triangle {
Triangle::{ v0, v1, v2 }
}
///|
/// Creates a `Triangle` with counter-clockwise (CCW) winding.
///
/// Winding is determined by the signed double-area cross product
/// `(v1 − v0) × (v2 − v0)` (non-robust, matching geo-types
/// `Triangle::new`). If the input vertices are clockwise, `v1` and `v2`
/// are swapped to produce CCW winding. Collinear input is stored as-is.
pub fn Triangle::ccw(v0 : Coord, v1 : Coord, v2 : Coord) -> Triangle {
let cross = (v1.x() - v0.x()) * (v2.y() - v0.y()) -
(v1.y() - v0.y()) * (v2.x() - v0.x())
if cross >= 0.0 {
Triangle::Triangle(v0, v1, v2)
} else {
Triangle::Triangle(v0, v2, v1)
}
}
///|
pub fn Triangle::v0(self : Triangle) -> Coord {
self.v0
}
///|
pub fn Triangle::v1(self : Triangle) -> Coord {
self.v1
}
///|
pub fn Triangle::v2(self : Triangle) -> Coord {
self.v2
}
///|
/// Returns the three line segments that make up this triangle in `(v0->v1,
/// v1->v2, v2->v0)` order.
pub fn Triangle::to_lines(self : Triangle) -> Array[Line] {
[
Line::Line(self.v0, self.v1),
Line::Line(self.v1, self.v2),
Line::Line(self.v2, self.v0),
]
}
///|
/// Converts to a closed `Polygon` representation.
pub fn Triangle::to_polygon(self : Triangle) -> Polygon {
let exterior = LineString::LineString([self.v0, self.v1, self.v2, self.v0])
Polygon::Polygon(exterior, [])
}