tilezz 0.2.0

Utilities to work with perfect-precision polygonal tiles built on top of cyclotomic integer rings.
Documentation
//! Float geometry over ring vectors: norms, cross products, and shoelace area
//! evaluated in `f64`.
//!
//! PROPOSAL-SIDE ONLY (the "float proposes, exact check disposes" rule): these
//! rank candidates, size blocks, and read off near-integer coordinates, but
//! every acceptance-relevant decision reduces to an exact ring comparison. The
//! exact counterparts live in the parent [`geometry`](super) module
//! (`cross_2i`, `signed_area_4i`, `covol_eq_m_areas`, `area_eq_k_area`); this
//! file is deliberately separate so the `f64` contamination is quarantined from
//! the exact API.

use crate::cyclotomic::IsRing;

/// Squared Euclidean norm of a ring vector (float).
pub(crate) fn norm2_f<T: IsRing>(v: &T) -> f64 {
    let (x, y) = v.xy();
    x * x + y * y
}

/// Euclidean norm of a ring vector (float).
pub(crate) fn norm_f<T: IsRing>(v: &T) -> f64 {
    norm2_f(v).sqrt()
}

/// Shoelace area of a polygon (float, always positive).
pub(crate) fn area_f<T: IsRing>(poly: &[T]) -> f64 {
    let mut a = 0.0;
    let n = poly.len();
    for i in 0..n {
        let (x1, y1) = poly[i].xy();
        let (x2, y2) = poly[(i + 1) % n].xy();
        a += x1 * y2 - x2 * y1;
    }
    a.abs() / 2.0
}

/// 2D cross product of two ring vectors (float).
pub(crate) fn cross_f<T: IsRing>(a: &T, b: &T) -> f64 {
    let (ax, ay) = a.xy();
    let (bx, by) = b.xy();
    ax * by - ay * bx
}