Sign in

    #@totto2727/geo/geo/2d/type

    totto2727/geo/geo/2d/type owns the concrete two-dimensional geometry values consumed by totto2727/geo/geo/2d, including points, lines, polygons, collections, rectangles, triangles, and the Geometry sum type.

    #Usage

    Normalize clockwise survey vertices before handing a closed boundary to a polygon consumer:

    ///|
    test "normalize a triangle boundary" {
    let triangle = Triangle::ccw(
    Coord(0.0, 0.0),
    Coord(0.0, 6.0),
    Coord(4.0, 0.0),
    )
    let boundary = triangle.to_polygon().exterior().coords()
    @test.assert_eq(boundary, [
    Coord(0.0, 0.0),
    Coord(4.0, 0.0),
    Coord(0.0, 6.0),
    Coord(0.0, 0.0),
    ])
    }

    #API

    This README was generated from the share-artifact skill and README template.

    HasLength

    pub(open) trait HasLength {
    fn length(Self) -> Int
    }

    Collection-style cardinality (number of components or coords). Mirrors Vec::len() / Array::length(). Distinct from HasEuclideanLength (the physical length of a curve, defined in geo/2d/traits.mbt).

    IsClosed

    pub(open) trait IsClosed {
    fn is_closed(Self) -> Bool
    }

    Anything that can be a closed ring (first and last coord equal).

    IsEmpty

    pub(open) trait IsEmpty {
    fn is_empty(Self) -> Bool
    }

    Anything that can be empty (zero coords / zero components). Mirrors the is_empty() inherent method present on every collection-shaped type.

    MismatchedGeometry

    pub suberror MismatchedGeometry {
    MismatchedGeometry(expected~ : String, found~ : String)
    } derive(Eq,
    Debug
    )

    Raised by Geometry::try_into_* when the variant does not match the expected one. Carries both the expected variant name and the actual variant name observed, matching the upstream Rust MismatchedGeometry error.

    Coord

    pub struct Coord {
    x : Double
    y : Double
    } derive(Default, Eq, Hash,
    Debug
    )

    A lightweight struct used to store coordinates on the 2-dimensional Cartesian plane.

    Unlike Point (which in the future may contain additional information such as an envelope, a precision model, and spatial reference system information), a Coord only contains ordinate values and accessor methods.

    This type implements the vector-space operations: add, sub, neg, zero, mul, div (the last two by scalar), and dot.

    Semantics

    This type does not represent any geospatial primitive, but is used in their definitions. The only requirement is that the coordinates it contains are valid numbers (e.g. not NaN).
    impl Add for Coord
    impl Neg for Coord
    impl Sub for Coord

    Coord::Coord

    fn Coord::Coord(x : Double, y : Double) -> Coord

    Creates a new Coord from the given x and y ordinate values.

    Coord::cross

    fn Coord::cross(self : Coord, other : Coord) -> Double

    Returns the 2D cross / wedge product (signed area of the parallelogram).

    Coord::div

    fn Coord::div(self : Coord, scalar : Double) -> Coord

    Divides this coordinate component-wise by a scalar.

    MoonBit's trait system cannot express the Rust Div<T> overload across different types, so we expose this as a regular method instead.

    Coord::dot

    fn Coord::dot(self : Coord, other : Coord) -> Double

    Returns the dot product of this coordinate with another.

    Coord::from_array

    fn Coord::from_array(a : Array[Double]) -> Coord

    Builds a Coord from a 2-element array [x, y]. Aborts when the input length is not 2.

    Coord::from_tuple

    fn Coord::from_tuple(t : (Double, Double)) -> Coord

    Builds a Coord from a (x, y) tuple.

    Coord::is_zero

    fn Coord::is_zero(self : Coord) -> Bool

    Returns whether this Coord is at the origin.

    Coord::mul

    fn Coord::mul(self : Coord, scalar : Double) -> Coord

    Multiplies this coordinate component-wise by a scalar.

    MoonBit's trait system cannot express the Rust Mul<T> overload across different types, so we expose this as a regular method instead.

    Coord::to_array

    fn Coord::to_array(self : Coord) -> Array[Double]

    Builds a 2-element array [x, y].

    Coord::x

    fn Coord::x(self : Coord) -> Double

    Returns the x component of this coordinate.

    Coord::x_y

    fn Coord::x_y(self : Coord) -> (Double, Double)

    Returns a tuple (x, y) of this coordinate's components.

    Coord::y

    fn Coord::y(self : Coord) -> Double

    Returns the y component of this coordinate.

    Coord::zero

    fn Coord::zero() -> Coord

    Creates a Coord at the origin (0.0, 0.0).

    Geometry

    pub(all) enum Geometry {
    Point(Point)
    Line(Line)
    LineString(LineString)
    Polygon(Polygon)
    MultiPoint(MultiPoint)
    MultiLineString(MultiLineString)
    MultiPolygon(MultiPolygon)
    GeometryCollection(GeometryCollection)
    Rect(Rect)
    Triangle(Triangle)
    } derive(Eq,
    Debug
    )

    An enumeration of all geometry types except Coord (which is not itself a "geometry" in the OGC sense).
    impl IsEmpty for Geometry

    Geometry::is_empty

    fn Geometry::is_empty(self : Geometry) -> Bool

    Geometry::try_into_geometry_collection

    fn Geometry::try_into_geometry_collection(self : Geometry) -> GeometryCollection raise MismatchedGeometry

    Unlike the Rust upstream — which excludes GeometryCollection from its try_from_geometry_impl! macro to avoid clashing with a deprecated From<single_geom> for GeometryCollection impl — the port has no such deprecated conversion, so the symmetry is preserved here.

    Geometry::try_into_line

    fn Geometry::try_into_line(self : Geometry) -> Line raise MismatchedGeometry

    Geometry::try_into_line_string

    fn Geometry::try_into_line_string(self : Geometry) -> LineString raise MismatchedGeometry

    Geometry::try_into_multi_line_string

    fn Geometry::try_into_multi_line_string(self : Geometry) -> MultiLineString raise MismatchedGeometry

    Geometry::try_into_multi_point

    fn Geometry::try_into_multi_point(self : Geometry) -> MultiPoint raise MismatchedGeometry

    Geometry::try_into_multi_polygon

    fn Geometry::try_into_multi_polygon(self : Geometry) -> MultiPolygon raise MismatchedGeometry

    Geometry::try_into_point

    fn Geometry::try_into_point(self : Geometry) -> Point raise MismatchedGeometry

    If self is the Point variant, returns the inner Point. Otherwise raises MismatchedGeometry with the expected / actual variant names. Mirrors Rust upstream TryFrom<Geometry> for Point (g.try_into()).

    Geometry::try_into_polygon

    fn Geometry::try_into_polygon(self : Geometry) -> Polygon raise MismatchedGeometry

    Geometry::try_into_rect

    fn Geometry::try_into_rect(self : Geometry) -> Rect raise MismatchedGeometry

    Geometry::try_into_triangle

    fn Geometry::try_into_triangle(self : Geometry) -> Triangle raise MismatchedGeometry

    GeometryCollection

    pub struct GeometryCollection {
    geometries : Array[Geometry]
    } derive(Default, Eq,
    Debug
    )

    A collection of Geometry values. Useful for representing heterogeneous collections (the GeoJSON GeometryCollection).

    GeometryCollection::GeometryCollection

    fn GeometryCollection::GeometryCollection(geometries : Array[Geometry]) -> GeometryCollection

    GeometryCollection::empty

    Creates an empty GeometryCollection. Mirrors Rust geo_types::GeometryCollection::empty.

    GeometryCollection::geometries

    GeometryCollection::is_empty

    fn GeometryCollection::is_empty(self : GeometryCollection) -> Bool

    GeometryCollection::length

    fn GeometryCollection::length(self : GeometryCollection) -> Int

    Line

    pub struct Line {
    start : Coord
    end : Coord
    } derive(Eq, Hash,
    Debug
    )

    A line segment made up of exactly two Coords.

    Semantics

    The interior and boundary are defined as with a LineString containing only the two end points.

    Line::Line

    fn Line::Line(start : Coord, end : Coord) -> Line

    Creates a new line segment from two coordinates.

    Line::delta

    fn Line::delta(self : Line) -> Coord

    Calculates the difference in coordinates (Δx, Δy).

    Line::determinant

    fn Line::determinant(self : Line) -> Double

    Calculates the determinant start.x * end.y - start.y * end.x.

    Line::dx

    fn Line::dx(self : Line) -> Double

    Calculates the difference in x components (Δx).

    Line::dy

    fn Line::dy(self : Line) -> Double

    Calculates the difference in y components (Δy).

    Line::end

    fn Line::end(self : Line) -> Coord

    Returns the end coordinate.

    Line::end_point

    fn Line::end_point(self : Line) -> Point

    Returns the end point.

    Line::from_tuples

    fn Line::from_tuples(start : (Double, Double), end : (Double, Double)) -> Line

    Creates a new line segment from (x, y) tuples.

    Line::points

    fn Line::points(self : Line) -> (Point, Point)

    Returns (start_point, end_point).

    Line::reverse

    fn Line::reverse(self : Line) -> Line

    Returns a new Line with start and end swapped — the same segment traversed in the opposite direction.

    Independent from Rust upstream (geo_types::Line does not expose a dedicated reverse method); added here as a focused helper.

    Note for LineString::rev_lines: that method intentionally does NOT build forward lines first and then reverse them — it constructs each segment with swapped endpoints directly inside its loop. This avoids an avoidable round trip through Line::reverse.

    Line::slope

    fn Line::slope(self : Line) -> Double

    Calculates the slope Δy / Δx.

    Line::start

    fn Line::start(self : Line) -> Coord

    Returns the start coordinate.

    Line::start_point

    fn Line::start_point(self : Line) -> Point

    Returns the start point.

    LineString

    pub struct LineString {
    coords : Array[Coord]
    } derive(Default, Eq,
    Debug
    )

    An ordered collection of two or more Coords, representing a path between locations.

    Semantics

    • 0 or 1 points: empty interior and boundary, treated as invalid in many APIs.
    • 2 or more points: interior is the union of the line segments; boundary is the start and end coordinate (open) or empty (closed, i.e. start == end).

    LineString::LineString

    fn LineString::LineString(coords : Array[Coord]) -> LineString

    Creates a new LineString from an array of Coords.

    LineString::closed

    fn LineString::closed(self : LineString) -> LineString

    Returns a closed copy of this line string. If self is already closed (or empty — there is no start coord to repeat), self is returned directly without allocating a new value. Otherwise a new LineString is built via the array-spread literal [..self.coords, self.coords[0]], pre-sized to its final length in a single allocation.

    The original self is never mutated. This is the immutable counterpart of Rust upstream LineString::close(&mut self).

    LineString::coords

    fn LineString::coords(self : LineString) -> Array[Coord]

    Returns the underlying coordinate array.

    LineString::empty

    fn LineString::empty() -> LineString

    Creates an empty LineString (no coordinates). Equivalent to LineString::LineString([]) and mirrors Rust geo_types::LineString::empty.

    LineString::from_tuples

    fn LineString::from_tuples(tuples : Array[(Double, Double)]) -> LineString

    Creates a new LineString from (x, y) tuples.

    LineString::is_closed

    fn LineString::is_closed(self : LineString) -> Bool

    LineString::is_empty

    fn LineString::is_empty(self : LineString) -> Bool

    LineString::length

    fn LineString::length(self : LineString) -> Int

    LineString::lines

    fn LineString::lines(self : LineString) -> Array[Line]

    Returns the line segments composing this line string, eagerly. Each segment connects two consecutive coords with the same orientation as upstream Rust geo_types::LineString::lines. For a pipeline that already consumes results as an iterator, prefer lines_iter to skip the intermediate Array allocation.

    An empty line string and a single-coordinate line string yield an empty segment array.

    LineString::lines_iter

    fn LineString::lines_iter(self : LineString) -> Iter[Line]

    Returns a lazy iterator yielding the line segments composing this line string. Independent of lines() — does not allocate an intermediate Array; each Line is constructed on demand. Use this when chaining iterator combinators (take, filter, …) so allocation is paid only for what is consumed.

    An empty line string and a single-coordinate line string yield an iterator with no elements.

    LineString::points

    fn LineString::points(self : LineString) -> Array[Point]

    Returns each coordinate wrapped as a Point, eagerly. Equivalent to coords().map(Point::from_coord) but more readable at call sites and matches the Rust geo_types::LineString::points API. For pipelines that already process the result as an iterator, prefer points_iter to skip the intermediate array allocation.

    LineString::points_iter

    fn LineString::points_iter(self : LineString) -> Iter[Point]

    Returns a lazy iterator yielding each coordinate wrapped as a Point. Mirrors Rust geo_types::LineString::points_iter. Prefer this over points when the consumer is itself iterator-based; the conversion happens on demand without allocating a new array.

    LineString::rev_lines

    fn LineString::rev_lines(self : LineString) -> Array[Line]

    Returns the line segments in reverse order, with each segment's start / end swapped, eagerly. Mirrors Rust geo_types::LineString::rev_lines.

    For a line string [a, b, c, d], lines() yields [a→b, b→c, c→d] while rev_lines() yields [d→c, c→b, b→a].

    An empty line string and a single-coordinate line string yield an empty segment array.

    LineString::rev_lines_iter

    fn LineString::rev_lines_iter(self : LineString) -> Iter[Line]

    Lazy iterator version of rev_lines(). Independent implementation; does not allocate an intermediate Array. Yields segments in reverse order with each Line's start / end swapped, just like the eager variant.

    An empty line string and a single-coordinate line string yield an iterator with no elements.

    MultiLineString

    pub struct MultiLineString {
    line_strings : Array[LineString]
    } derive(Default, Eq,
    Debug
    )

    A collection of LineStrings.

    MultiLineString::MultiLineString

    fn MultiLineString::MultiLineString(line_strings : Array[LineString]) -> MultiLineString

    MultiLineString::empty

    Creates an empty MultiLineString. Mirrors Rust geo_types::MultiLineString::empty.

    MultiLineString::is_closed

    fn MultiLineString::is_closed(self : MultiLineString) -> Bool

    MultiLineString::is_empty

    fn MultiLineString::is_empty(self : MultiLineString) -> Bool

    MultiLineString::length

    fn MultiLineString::length(self : MultiLineString) -> Int

    MultiLineString::line_strings

    fn MultiLineString::line_strings(self : MultiLineString) -> Array[LineString]

    MultiPoint

    pub struct MultiPoint {
    points : Array[Point]
    } derive(Default, Eq,
    Debug
    )

    A collection of Points. Can be created from a list of points, or from tuples / coords via the helper constructors.

    MultiPoint::MultiPoint

    fn MultiPoint::MultiPoint(points : Array[Point]) -> MultiPoint

    MultiPoint::empty

    fn MultiPoint::empty() -> MultiPoint

    Creates an empty MultiPoint. Mirrors Rust geo_types::MultiPoint::empty.

    MultiPoint::from_coord

    fn MultiPoint::from_coord(c : Coord) -> MultiPoint

    Creates a MultiPoint containing a single Coord.

    MultiPoint::from_coords

    fn MultiPoint::from_coords(coords : Array[Coord]) -> MultiPoint

    Creates a MultiPoint from an Array[Coord].

    MultiPoint::from_point

    fn MultiPoint::from_point(p : Point) -> MultiPoint

    Creates a MultiPoint containing a single Point.

    MultiPoint::from_tuples

    fn MultiPoint::from_tuples(tuples : Array[(Double, Double)]) -> MultiPoint

    MultiPoint::is_empty

    fn MultiPoint::is_empty(self : MultiPoint) -> Bool

    MultiPoint::length

    fn MultiPoint::length(self : MultiPoint) -> Int

    MultiPoint::points

    fn MultiPoint::points(self : MultiPoint) -> Array[Point]

    MultiPolygon

    pub struct MultiPolygon {
    polygons : Array[Polygon]
    } derive(Default, Eq,
    Debug
    )

    A collection of Polygons.

    MultiPolygon::MultiPolygon

    fn MultiPolygon::MultiPolygon(polygons : Array[Polygon]) -> MultiPolygon

    MultiPolygon::empty

    fn MultiPolygon::empty() -> MultiPolygon

    Creates an empty MultiPolygon. Mirrors Rust geo_types::MultiPolygon::empty.

    MultiPolygon::is_empty

    fn MultiPolygon::is_empty(self : MultiPolygon) -> Bool

    MultiPolygon::length

    fn MultiPolygon::length(self : MultiPolygon) -> Int

    MultiPolygon::polygons

    fn MultiPolygon::polygons(self : MultiPolygon) -> Array[Polygon]

    Point

    pub struct Point {
    coord : Coord
    } derive(Default, Eq, Hash,
    Debug
    )

    A single point in 2D space.

    Semantics

    The interior of the point is itself (a singleton set), and its boundary is empty. A point is valid if and only if its Coord is valid.
    impl Add for Point
    impl Neg for Point
    impl Sub for Point

    Point::Point

    fn Point::Point(x : Double, y : Double) -> Point

    Canonical constructor: creates a new point from x and y.

    Point::coord

    fn Point::coord(self : Point) -> Coord

    Returns the underlying Coord.

    Point::cross_prod

    fn Point::cross_prod(self : Point, b : Point, c : Point) -> Double

    Returns the cross product of three points.

    A positive value implies self → b → c is counter-clockwise; a negative value implies clockwise; zero implies collinear. This function is not robust against floating-point error — see src/robust/orient2d.mbt.

    Point::div

    fn Point::div(self : Point, scalar : Double) -> Point

    Divides the point's coordinates by a scalar.

    Point::dot

    fn Point::dot(self : Point, other : Point) -> Double

    Returns the dot product of the two points: x1 * x2 + y1 * y2.

    Point::from_coord

    fn Point::from_coord(c : Coord) -> Point

    Creates a point from a Coord. Goes through the canonical constructor.

    Point::from_tuple

    fn Point::from_tuple(t : (Double, Double)) -> Point

    Creates a point from a (x, y) tuple. Goes through the canonical constructor.

    Point::mul

    fn Point::mul(self : Point, scalar : Double) -> Point

    Multiplies the point's coordinates by a scalar.

    Point::with_x

    fn Point::with_x(self : Point, x : Double) -> Point

    Returns a new point with x set, the original y preserved.

    Point::with_y

    fn Point::with_y(self : Point, y : Double) -> Point

    Returns a new point with y set, the original x preserved.

    Point::x

    fn Point::x(self : Point) -> Double

    Returns the x/horizontal component.

    Point::x_y

    fn Point::x_y(self : Point) -> (Double, Double)

    Returns a (x, y) tuple.

    Point::y

    fn Point::y(self : Point) -> Double

    Returns the y/vertical component.

    Polygon

    pub struct Polygon {
    exterior : LineString
    interiors : Array[LineString]
    } derive(Eq,
    Debug
    )

    A bounded two-dimensional area.

    A Polygon's outer boundary (exterior) is represented by a LineString that is automatically closed. It may contain zero or more interiors representing holes (rings within the polygon).

    Validity

    Per the OGC SFA, a valid Polygon requires:
    1. Each ring is closed (first coord == last coord).
    2. Rings have at least 4 coords (3 unique).
    3. Rings do not self-cross.
    4. The exterior contains all interior rings, and interiors do not overlap.

    This module does not enforce validity; use the validation algorithm (planned for ms-15) for explicit checks.
    impl IsEmpty for Polygon

    Polygon::Polygon

    fn Polygon::Polygon(exterior : LineString, interiors : Array[LineString]) -> Polygon

    Creates a new Polygon.

    The exterior and each interior ring are closed (auto-closure matches the Rust geo-types semantics). The closure is immutable: each input LineString is replaced via LineString::closed, which returns either self (if already closed) or a fresh closed copy. The caller's references are never mutated as a side effect of constructing a Polygon.

    Polygon::empty

    fn Polygon::empty() -> Polygon

    Creates an empty Polygon (exterior ring has no coordinates, no holes). Mirrors Rust geo_types::Polygon::empty.

    Polygon::exterior

    fn Polygon::exterior(self : Polygon) -> LineString

    Returns the exterior ring.

    Polygon::interiors

    fn Polygon::interiors(self : Polygon) -> Array[LineString]

    Returns the array of interior rings (holes).

    Polygon::is_empty

    fn Polygon::is_empty(self : Polygon) -> Bool

    Polygon::num_interiors

    fn Polygon::num_interiors(self : Polygon) -> Int

    Returns the number of interior rings (holes).

    Polygon::num_rings

    fn Polygon::num_rings(self : Polygon) -> Int

    Returns the total number of rings: exterior (1) plus interiors. Mirrors Rust upstream Polygon::num_rings.

    Polygon::pushed_interior

    fn Polygon::pushed_interior(self : Polygon, new_interior : LineString) -> Polygon

    Returns a new Polygon whose interiors are the original interiors plus new_interior appended at the end. The original Polygon is not modified (immutable counterpart of Rust upstream Polygon::interiors_push, which mutates &mut self).

    new_interior itself is left untouched: LineString::closed returns self when already closed (no allocation), or a freshly closed copy otherwise — never mutating the caller's value.

    The destination interiors array is built with the array-spread literal [..self.interiors, new_interior.closed()], which pre-sizes to the final length in a single allocation.

    Rect

    pub struct Rect {
    min : Coord
    max : Coord
    } derive(Eq, Hash,
    Debug
    )

    An axis-aligned bounded 2D rectangle whose area is defined by minimum and maximum Coords.

    The constructor normalises the input so that min.x <= max.x and min.y <= max.y.

    Rect::Rect

    fn Rect::Rect(c1 : Coord, c2 : Coord) -> Rect

    Creates a new Rect from two coordinates. Order is not significant — the resulting rectangle's min/max are the component-wise min/max of the inputs.

    Rect::area

    fn Rect::area(self : Rect) -> Double

    Returns the rectangle's signed area: width * height.

    Rect::center

    fn Rect::center(self : Rect) -> Coord

    Returns the centroid of the rectangle.

    Rect::height

    fn Rect::height(self : Rect) -> Double

    Rect::max

    fn Rect::max(self : Rect) -> Coord

    Rect::min

    fn Rect::min(self : Rect) -> Coord

    Rect::split_x

    fn Rect::split_x(self : Rect) -> (Rect, Rect)

    Splits the rectangle into two equal-width halves along the X-axis at the midpoint. Returns (left, right) where left.max.x == right.min.x is the shared mid-X. The shared mid coordinate is computed once and reused in both halves so floating-point round-off is bit-identical on the seam.

    Mirrors Rust upstream geo_types::Rect::split_x (which returns a [Rect<T>; 2] fixed-length array; a tuple is the closest MoonBit equivalent that preserves the "exactly two" type-level guarantee).

    Rect::split_y

    fn Rect::split_y(self : Rect) -> (Rect, Rect)

    Splits the rectangle into two equal-height halves along the Y-axis at the midpoint. Returns (bottom, top) where bottom.max.y == top.min.y is the shared mid-Y. The shared mid coordinate is computed once and reused in both halves so floating-point round-off is bit-identical on the seam.

    Mirrors Rust upstream geo_types::Rect::split_y.

    Rect::to_lines

    fn Rect::to_lines(self : Rect) -> Array[Line]

    Returns the four edges of the rectangle as Line segments, walked CCW starting from the min corner: bl→br, br→tr, tr→tl, tl→bl.

    Mirrors Triangle::to_lines for symmetry and matches the upstream geo_types API surface (the algorithm-layer helper lines_of_rect is now a thin wrapper around this method).

    Rect::to_polygon

    fn Rect::to_polygon(self : Rect) -> Polygon

    Converts the rectangle into a Polygon with the four corners (CCW from min).

    Rect::width

    fn Rect::width(self : Rect) -> Double

    Triangle

    pub struct Triangle {
    v0 : Coord
    v1 : Coord
    v2 : Coord
    } derive(Eq, Hash,
    Debug
    )

    A bounded 2D area whose three vertices are defined by Coords.

    Triangle::Triangle

    fn Triangle::Triangle(v0 : Coord, v1 : Coord, v2 : Coord) -> Triangle

    Stores vertices as-given (no winding normalisation). Semantically equivalent to upstream Triangle::unchecked_winding.

    Triangle::ccw

    fn Triangle::ccw(v0 : Coord, v1 : Coord, v2 : Coord) -> Triangle

    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.

    Triangle::to_lines

    fn Triangle::to_lines(self : Triangle) -> Array[Line]

    Returns the three line segments that make up this triangle in (v0->v1,v1->v2, v2->v0) order.

    Triangle::to_polygon

    fn Triangle::to_polygon(self : Triangle) -> Polygon

    Converts to a closed Polygon representation.

    Triangle::v0

    fn Triangle::v0(self : Triangle) -> Coord

    Triangle::v1

    fn Triangle::v1(self : Triangle) -> Coord

    Triangle::v2

    fn Triangle::v2(self : Triangle) -> Coord