Audit: Perspective Grid lines counted not summed; Liquify subdivision stays under its anchor ceiling

This commit is contained in:
Dylan M. Taylor
2026-10-24 04:13:37 +07:00
committed by bflatastic
parent aa160b969b
commit 1bb904c147
3 changed files with 20 additions and 11 deletions
+5 -1
View File
@@ -39,7 +39,11 @@ impl Side {
/// The side's length.
fn length(&self) -> f64 {
if self.straight() { self.curve.p0.distance(self.curve.p3) } else { crate::path::measured_arclen(&kurbo::PathSeg::Cubic(self.curve), ARCLEN_ACCURACY) }
if self.straight() {
self.curve.p0.distance(self.curve.p3)
} else {
crate::path::measured_arclen(&kurbo::PathSeg::Cubic(self.curve), ARCLEN_ACCURACY)
}
}
/// The parameter `s` along the side from the corner, the point there and the direction the
+2 -1
View File
@@ -388,7 +388,8 @@ fn subdivide(sp: &mut SubPath, prm: &LiquifyParams, c: Point, spacing: f64) {
continue;
}
let len = cub.arclen(1e-3);
let k = (len / spacing).ceil() as usize;
// (No more pieces than the anchors left under the ceiling.)
let k = ((len / spacing).ceil() as usize).min(MAX_ANCHORS.saturating_sub(sp.anchors.len()) + 1);
if k <= 1 {
seg += 1;
continue;
+13 -9
View File
@@ -549,6 +549,11 @@ impl PerspectiveGrid {
let Some(h) = self.homography(plane) else { return vec![] };
let d = self.domain(plane);
let mut out = vec![];
// A stored grid is not checked: no spacing, or an extent that isn't a number, has no lines.
let (w, h_len) = (d.width(), d.height());
if !(self.cell.is_finite() && self.cell > 0.0 && w.is_finite() && h_len.is_finite()) {
return out;
}
let step = |len: f64| {
let mut s = self.cell;
while len / s > 120.0 {
@@ -556,20 +561,19 @@ impl PerspectiveGrid {
}
s
};
let (su, sv) = (step(d.width()), step(d.height()));
let mut u = 0.0;
while u <= d.width() + 1e-9 {
if let (Some(a), Some(b)) = (h.apply(Point::new(u, 0.0)), h.apply(Point::new(u, d.height()))) {
let (su, sv) = (step(w), step(h_len));
// Counted, not summed: a count in whole lines (at most 121 a way).
for i in 0..=((w + 1e-9) / su).floor() as usize {
let u = i as f64 * su;
if let (Some(a), Some(b)) = (h.apply(Point::new(u, 0.0)), h.apply(Point::new(u, h_len))) {
out.push((a, b));
}
u += su;
}
let mut v = 0.0;
while v <= d.height() + 1e-9 {
if let (Some(a), Some(b)) = (h.apply(Point::new(0.0, v)), h.apply(Point::new(d.width(), v))) {
for i in 0..=((h_len + 1e-9) / sv).floor() as usize {
let v = i as f64 * sv;
if let (Some(a), Some(b)) = (h.apply(Point::new(0.0, v)), h.apply(Point::new(w, v))) {
out.push((a, b));
}
v += sv;
}
out
}