i_overlay 6.0.0

Boolean Operations for 2D Polygons: Supports intersection, union, difference, xor, and self-intersections for all polygon varieties.
Documentation
use i_float::adapter::FloatPointAdapter;
use i_float::float::compatible::FloatPointCompatible;
use i_float::float::number::FloatNumber;
use i_float::int::point::IntPoint;

pub(super) struct Miter;

pub(super) enum SharpMiter {
    Degenerate,
    AB(IntPoint, IntPoint),
    AcB(IntPoint, IntPoint, IntPoint),
}

impl Miter {
    #[inline]
    pub(super) fn sharp<P: FloatPointCompatible>(
        pa: P,
        pb: P,
        va: P,
        vb: P,
        adapter: &FloatPointAdapter<P>,
    ) -> SharpMiter {
        let ia = adapter.float_to_int(&pa);
        let ib = adapter.float_to_int(&pb);

        if ia == ib {
            return SharpMiter::Degenerate;
        }

        let c = Self::peak(pa, pb, va, vb);

        let ic = adapter.float_to_int(&c);

        if ia == ic || ib == ic {
            SharpMiter::AB(ia, ib)
        } else {
            SharpMiter::AcB(ia, ic, ib)
        }
    }

    #[inline]
    pub(super) fn peak<P: FloatPointCompatible>(pa: P, pb: P, va: P, vb: P) -> P {
        let pax = pa.x();
        let pay = pa.y();
        let pbx = pb.x();
        let pby = pb.y();
        let vax = va.x();
        let vay = va.y();
        let vbx = vb.x();
        let vby = vb.y();

        let xx = vax + vbx;
        let yy = vay + vby;

        let k = if xx.abs() > yy.abs() {
            (pbx - pax) / xx
        } else {
            (pby - pay) / yy
        };

        let x = pax + k * vax;
        let y = pay + k * vay;

        P::from_xy(x, y)
    }
}