use i_float::adapter::FloatPointAdapter;
use i_float::float::compatible::FloatPointCompatible;
pub trait IntArea<P: FloatPointCompatible> {
fn unsafe_int_area(&self, adapter: &FloatPointAdapter<P>) -> i64;
}
impl<P: FloatPointCompatible> IntArea<P> for [P] {
fn unsafe_int_area(&self, adapter: &FloatPointAdapter<P>) -> i64 {
let n = self.len();
let mut p0 = adapter.float_to_int(&self[n - 1]);
let mut area: i64 = 0;
for pi in self.iter() {
let p1 = adapter.float_to_int(pi);
let a = (p1.x as i64).wrapping_mul(p0.y as i64);
let b = (p1.y as i64).wrapping_mul(p0.x as i64);
area = area.wrapping_add(a).wrapping_sub(b);
p0 = p1;
}
area
}
}
#[cfg(test)]
mod tests {
use crate::float::int_area::IntArea;
use crate::path;
use i_float::adapter::FloatPointAdapter;
#[test]
fn test_0() {
let square = path![[-1f32, -1f32], [1f32, -1f32], [1f32, 1f32], [-1f32, 1f32],];
let adapter = FloatPointAdapter::with_iter(square.iter());
let area = square.unsafe_int_area(&adapter);
assert!(area < 0);
}
}