mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-04 02:55:54 +00:00
Kernel tests: a round as tall as its wall and more builds on the disc
The owner's blend-overflow ruling of 2026-10-30: a round that runs past its face on its tangent side is built on the face continued and cut from the part, keeping its radius. loop_fillet_as_tall_as_its_wall_consumes_it still wanted R2.001 and R2.5 on the R13 x 2 disc refused as taller than the wall; they now must build, valid, with the exact volume. Proof. The round's section in (rho, z) is the r square at the top edge outside the circle about (13 - r, 2 - r), clipped to z >= 0. With t = z - (2 - r) = r sin(theta), the round's inner radius is rho(theta) = 13 - r + r cos(theta), theta from asin((r - 2) / r) to pi/2, and the disc keeps pi (169 * 2 - integral (169 - rho^2) dz), dz = r cos(theta) dtheta (midpoint rule, 20000 steps). At r = 2 it is Pappus, 2 pi 169 - (1 - pi/4) 4 * 2 pi (13 - c), c = 2 (10 - 3 pi) / (3 (4 - pi)) (checked to 1e-9 in the test); at r = 2.5 it is 957.692239 mm3, the ruling's number, the same integral as rounds_past_the_bottom_of_a_wall_are_cut_from_the_part's. Graded at 1e-6 as that test is. Today SMLib fails the R2.001 round (status 1001): a convex round past its face is not yet built by subtraction, the cause fillets/KNOWN_FAILING gives 4782 and 5158. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -311,10 +311,32 @@ fn loop_fillet_as_tall_as_its_wall_consumes_it() {
|
||||
let m = measure(&f).unwrap();
|
||||
assert!(rel(m.volume, want) < 2e-4, "{} vs {want}", m.volume);
|
||||
assert!(f.validity().is_empty(), "{:?}", f.validity());
|
||||
// Taller than the wall: still refused, the body unchanged.
|
||||
// Taller than the wall the round overflows on its tangent side, past the wall's bottom
|
||||
// edge: it is built on the wall continued down and cut from the disc (the owner's
|
||||
// blend-overflow ruling, 2026-10-30), keeping its radius. Its section in (ρ, z) is the r
|
||||
// square at the edge outside the circle about (13 − r, 2 − r), above z = 0: with
|
||||
// t = z − (2 − r) = r sin θ and ρ(θ) = 13 − r + r cos θ the disc keeps
|
||||
// π (169·2 − ∫ (169 − ρ²) dz), θ from asin((r − 2) / r) (957.692239 at r = 2.5).
|
||||
let kept = |r: f64| {
|
||||
let (n, lo) = (20000, ((r - 2.0) / r).asin());
|
||||
let taken: f64 = (0..n)
|
||||
.map(|i| {
|
||||
let th = lo + (f64::from(i) + 0.5) * (PI / 2.0 - lo) / f64::from(n);
|
||||
let rho = 13.0 - r + r * th.cos();
|
||||
(169.0 - rho * rho) * r * th.cos()
|
||||
})
|
||||
.sum::<f64>()
|
||||
* (PI / 2.0 - lo)
|
||||
/ f64::from(n);
|
||||
PI * (169.0 * 2.0 - taken)
|
||||
};
|
||||
assert!(rel(kept(2.0), PI * 169.0 * 2.0 - spandrel(2.0).0 * 2.0 * PI * (13.0 - spandrel(2.0).1)) < 1e-9);
|
||||
assert!((kept(2.5) - 957.692239).abs() < 1e-6, "{}", kept(2.5));
|
||||
for r in [2.0 + 1e-3, 2.5] {
|
||||
let e = fillet(&disc, &[Vec3::new(0.0, 13.0, 2.0), Vec3::new(0.0, -13.0, 2.0)], r).unwrap_err();
|
||||
assert!(e.to_string().contains("taller than the walls"), "{r}: {e}");
|
||||
let f = fillet(&disc, &[Vec3::new(0.0, 13.0, 2.0), Vec3::new(0.0, -13.0, 2.0)], r).unwrap_or_else(|e| panic!("{r}: {e}"));
|
||||
assert!(f.validity().is_empty(), "{r}: {:?}", f.validity());
|
||||
let v = measure(&f).unwrap().volume;
|
||||
assert!(rel(v, kept(r)) < 1e-6, "{r}: {v} vs {}", kept(r));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user