similari 0.19.0

Machine learning framework for building object trackers and similarity search engines
Documentation
use geo::{Coordinate, CoordsIter, LineString, Polygon};

fn is_inside(q: &Coordinate<f64>, p1: &Coordinate<f64>, p2: &Coordinate<f64>) -> bool {
    let r = (p2.x - p1.x) * (q.y - p1.y) - (p2.y - p1.y) * (q.x - p1.x);
    let i1 = p2.x - p1.x;
    let i2 = q.y - p1.y;
    let i3 = p2.y - p1.y;
    let i4 = q.x - p1.x;
    dbg!(i1, i2, i3, i4);

    eprintln!("p1={:?}, p2={:?}, q={:?}, r={:?}", p1, p2, q, r);
    r <= 0.0
}

fn compute_intersection(
    cp1: &Coordinate<f64>,
    cp2: &Coordinate<f64>,
    s: &Coordinate<f64>,
    e: &Coordinate<f64>,
) -> Coordinate<f64> {
    let dc = Coordinate {
        x: cp1.x - cp2.x,
        y: cp1.y - cp2.y,
    };
    let dp = Coordinate {
        x: s.x - e.x,
        y: s.y - e.y,
    };
    let n1 = cp1.x * cp2.y - cp1.y * cp2.x;
    let n2 = s.x * e.y - s.y * e.x;
    let n3 = 1.0 / (dc.x * dp.y - dc.y * dp.x);
    Coordinate {
        x: (n1 * dp.x - n2 * dc.x) * n3,
        y: (n1 * dp.y - n2 * dc.y) * n3,
    }
}

pub fn sutherland_hodgman_clip(
    subject_polygon: &Polygon<f64>,
    clipping_polygon: &Polygon<f64>,
) -> Polygon<f64> {
    let mut final_polygon = subject_polygon.coords_iter().collect::<Vec<_>>();
    final_polygon.pop();

    let mut clipping_polygon = clipping_polygon.coords_iter().collect::<Vec<_>>();
    clipping_polygon.pop();

    for i in 0..clipping_polygon.len() {
        let next_polygon = final_polygon;
        dbg!(&next_polygon);
        final_polygon = Vec::default();

        let i_i = if i == 0 {
            clipping_polygon.len() - 1
        } else {
            i - 1
        };

        let c_edge_start = clipping_polygon[i_i];

        let c_edge_end = clipping_polygon[i];
        for j in 0..next_polygon.len() {
            let j_i = if j == 0 {
                next_polygon.len() - 1
            } else {
                j - 1
            };

            let s_edge_start = next_polygon[j_i];
            let s_edge_end = next_polygon[j];

            eprintln!(
                "c_edge_start={:?}, c_edge_end={:?}, s_edge_start={:?}, s_edge_end={:?}",
                c_edge_start, c_edge_end, s_edge_start, s_edge_end
            );

            if is_inside(&s_edge_end, &c_edge_start, &c_edge_end) {
                eprintln!("inside s_edge_end");
                if !is_inside(&s_edge_start, &c_edge_start, &c_edge_end) {
                    eprintln!("!inside s_edge_start");
                    let int = compute_intersection(
                        &s_edge_start,
                        &s_edge_end,
                        &c_edge_start,
                        &c_edge_end,
                    );
                    final_polygon.push(int);
                }
                final_polygon.push(s_edge_end);
            } else if is_inside(&s_edge_start, &c_edge_start, &c_edge_end) {
                eprintln!("inside s_edge_start");
                let int =
                    compute_intersection(&s_edge_start, &s_edge_end, &c_edge_start, &c_edge_end);
                final_polygon.push(int);
            }
        }
    }
    Polygon::new(LineString::new(final_polygon), vec![])
}

#[cfg(test)]
mod tests {
    use crate::utils::clipping::sutherland_hodgman_clip;
    use geo::{polygon, Area, BooleanOps, Polygon};

    #[test]
    fn clip() {
        let subject_polygon: Polygon<f64> = polygon![
            (x: 8055.658, y: 7977.5537),
            (x: 8010.734, y: 7999.9697),
            (x: 8032.9717, y: 8044.537),
            (x: 8077.896, y: 8022.121),
        ];

        let clip_polygon: Polygon<f64> = polygon![
            (x: 8055.805, y: 7977.847),
            (x: 8010.871, y: 8000.2676),
            (x: 8033.105, y: 8044.8286),
            (x: 8078.039, y: 8022.408),
        ];

        let result = sutherland_hodgman_clip(&subject_polygon, &clip_polygon);
        dbg!(&result);
        println!("Alg: {:?}", result.unsigned_area());
        println!(
            "Lib: {:?}",
            subject_polygon.intersection(&clip_polygon).unsigned_area()
        );
    }

    #[test]
    fn mul() {
        dbg!(-22.23399999999947 * -44.85429999999997 - -44.561000000000604 * -22.380999999999403);
    }
}