use crate::tree::{Edge, Node};
use float_cmp::approx_eq;
pub fn num_intersections(node: &Node, n: i32, p: (f64, f64)) -> i32 {
if skip_box_intersection(p, node) {
return n;
}
let mut n_ = n;
if !node.children_nodes.is_empty() {
for child_node in &node.children_nodes {
n_ = num_intersections(child_node, n_, p);
}
return n_;
}
if !node.edges.is_empty() {
for edge in &node.edges {
if crosses(p, edge) {
if (approx_eq!(f64, p.1, edge.p1.y, ulps = 2) && edge.p1.in_between)
|| (approx_eq!(f64, p.1, edge.p2.y, ulps = 2) && edge.p2.in_between)
{
n_ += 1;
} else {
n_ += 2;
}
}
}
return n_;
}
n
}
fn skip_box_intersection(p: (f64, f64), node: &Node) -> bool {
if p.0 < node.xmin {
return true;
}
if p.1 > node.ymax {
return true;
}
if p.1 < node.ymin {
return true;
}
false
}
fn a_z(r: (f64, f64), e: &Edge) -> f64 {
let b_x = e.p2.x - e.p1.x;
let b_y = e.p2.y - e.p1.y;
let c_x = r.0 - e.p1.x;
let c_y = r.1 - e.p1.y;
b_x * c_y - b_y * c_x
}
fn crosses(r: (f64, f64), e: &Edge) -> bool {
if r.1 > e.p1.y.max(e.p2.y) {
return false;
}
if r.1 < e.p1.y.min(e.p2.y) {
return false;
}
if e.p1.y < e.p2.y {
a_z(r, e) < 0.0
} else {
a_z(r, e) > 0.0
}
}