Start correct implementation of line-rect intersection test

This commit is contained in:
Francesco Magliocca 2020-11-09 23:33:30 +01:00
parent 2aaf3f7cc9
commit db8a0462a2
1 changed files with 39 additions and 7 deletions

View File

@ -1,17 +1,49 @@
use druid::kurbo::BezPath;
struct Interval {
start_pos: f64,
end_pos: f64,
}
impl Interval {
fn new(x1: f64, x2: f64) -> Interval {
Interval {
start_pos: x1.min(x2),
end_pos: x1.max(x2),
}
}
fn new_ordered(start: f64, end: f64) -> Interval {
Interval {
start_pos: start,
end_pos: end,
}
}
fn overlaps(&self, other: &Self) -> bool {
self.start_pos < other.end_pos && other.start_pos < self.end_pos
}
}
// O(1) complexity
// TODO: This is only a toy implementation, this is not at all correct!
// TODO: Implement this in a way that is not so flamboyant
// TODO: Implement intersection test for bezier curves
fn segment_intersects_rect(segment: &druid::kurbo::PathSeg, rect: druid::Rect) -> bool {
match segment {
druid::kurbo::PathSeg::Line(line) => rect.contains(line.p0) || rect.contains(line.p1),
druid::kurbo::PathSeg::Line(line) => {
// A Segment intersects the rect
// if their projections on the x and y line both overlap
let line_x_proj = Interval::new(line.p0.x, line.p1.x);
let line_y_proj = Interval::new(line.p0.y, line.p1.y);
druid::kurbo::PathSeg::Quad(quad) => {
rect.contains(quad.p0) || rect.contains(quad.p1) || rect.contains(quad.p2)
}
let rect_x_proj = Interval::new_ordered(rect.min_x(), rect.max_x());
let rect_y_proj = Interval::new_ordered(rect.min_y(), rect.max_y());
druid::kurbo::PathSeg::Cubic(cubic) => {
rect.contains(cubic.p0) || rect.contains(cubic.p1) || rect.contains(cubic.p2) || rect.contains(cubic.p3)
line_x_proj.overlaps(&rect_x_proj) && line_y_proj.overlaps(&rect_y_proj)
},
_ => {
unimplemented!();
}
}
}