use line intersection to improve precision
This commit is contained in:
parent
cf30027976
commit
9fd50e75fa
|
|
@ -70,17 +70,28 @@ impl BevelGearShape {
|
||||||
let angle = 2.0 * PI / self.points.len() as f32;
|
let angle = 2.0 * PI / self.points.len() as f32;
|
||||||
for (k, pt) in self.points.iter_mut().enumerate() {
|
for (k, pt) in self.points.iter_mut().enumerate() {
|
||||||
let dir = Vec2::from_angle(k as f32 * angle);
|
let dir = Vec2::from_angle(k as f32 * angle);
|
||||||
for line in cutting_line.iter().zip(&cutting_line[1..]) {
|
for (&a, &b) in cutting_line.iter().zip(&cutting_line[1..]) {
|
||||||
if line.0.dot(dir) <= 0. || line.1.dot(dir) <= 0. {
|
if let Some(intersect) = intersect_ray_segment(dir, (a, b))
|
||||||
continue;
|
&& intersect > 0.
|
||||||
}
|
{
|
||||||
if line.0.dot(dir.perp()) < 0. || line.1.dot(dir.perp()) > 0. {
|
*pt = pt.min(intersect);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*pt = pt.min(f32::min(line.0.length(), line.1.length()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the intersection point of a line (from the origin along `dir`) and a line segment (from `a` to `b`).
|
||||||
|
/// Returns the distance from the origin, in multiples of `dir`.
|
||||||
|
fn intersect_ray_segment(dir: Vec2, (a, b): (Vec2, Vec2)) -> Option<f32> {
|
||||||
|
const EPS: f32 = 1e-4;
|
||||||
|
let den = dir.perp_dot(b - a);
|
||||||
|
if den.abs() < EPS {
|
||||||
|
// parallel or almost parallel
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let u = a.perp_dot(dir) / den; // intersection = a + u * (b - a)
|
||||||
|
(0.0..1.0).contains(&u).then(|| a.perp_dot(b - a) / den)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user