mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-06 20:02:16 +00:00
Tests: the knife-edge R2 fillet is checked once, in closed form
fillet_the_knife_edge_at_the_tip (features_more_tests.rs) and blend_a_knife_edge_where_a_curved_wall_runs_out (tests/robustness.rs) build the same #851 part with the same script, round the same knife edge at (62 1/6, 0, 5) with R2 and measure the removed volume through the same display plan. The first integrated the removed area on a grid (5e-4); the second has it in closed form. Drop the first and keep its tolerance on the second. The ball 2 from the back face y = 0 and from the r 21 wall about (62 1/6, -21) is centred at (62 1/6 - sqrt(168), -2). The removed section is the trapezoid wall centre, tip, (kx, 0), ball centre (sqrt(168) wide, 21 and 2 high) less the wall's sector theta = acos(19/23) and the ball's sector pi - theta: 10 (11.5 sqrt(168) - 220.5 theta - 2 (pi - theta)) = 119.648812 mm^3 the constant the kept test has; the dropped test's grid gives 119.6487 at a 0.004 x 0.001 step. The kept test's fillet bound goes from 0.5 to 5e-4 of that (0.0598), the dropped test's. Its chamfer row (159.236451, the chord triangle less the wall's segment) already says the chamfer takes more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1725,38 +1725,6 @@ fn fillet_straight_edges_that_end_at_the_arc_wall() {
|
||||
}
|
||||
}
|
||||
|
||||
/// The vertical knife edge at the tip (the arc and the back face meeting at no angle) rounds to
|
||||
/// the ball 2 from both, about 13 back from the tip: the cusp beyond the ball, on the tip's side
|
||||
/// of its contacts, all the way up.
|
||||
#[test]
|
||||
fn fillet_the_knife_edge_at_the_tip() {
|
||||
let cx = 62.166666666666664;
|
||||
let (kx, ky) = (cx - (23.0f64 * 23.0 - 19.0 * 19.0).sqrt(), -2.0);
|
||||
let (hx, hy) = (0.002, 0.0005);
|
||||
let mut area = 0.0;
|
||||
let mut x = kx + hx / 2.0;
|
||||
while x < cx {
|
||||
let lo = -21.0 + (441.0 - (x - cx) * (x - cx)).max(0.0).sqrt();
|
||||
for j in 0..((0.0 - lo) / hy).ceil() as usize {
|
||||
let (y0, y1) = (lo + j as f64 * hy, (lo + (j + 1) as f64 * hy).min(0.0));
|
||||
let y = (y0 + y1) * 0.5;
|
||||
let a = (y - ky).atan2(x - kx);
|
||||
if (x - kx).hypot(y - ky) > 2.0 && a >= (-21.0 - ky).atan2(cx - kx) {
|
||||
area += (y1 - y0) * hx;
|
||||
}
|
||||
}
|
||||
x += hx;
|
||||
}
|
||||
let mut s = knife_edge_part();
|
||||
let before = planned(&s);
|
||||
run(&mut s, "solid.fillet", json!({"edges": [[cx, 0.0, 5.0]], "radius": 2}));
|
||||
let after = planned(&s);
|
||||
assert!(rel(before - after, area * 10.0) < 5e-4, "removed {} vs {}", before - after, area * 10.0);
|
||||
let mut s = knife_edge_part();
|
||||
run(&mut s, "solid.chamfer", json!({"edges": [[cx, 0.0, 5.0]], "distance": 2}));
|
||||
assert!(before - planned(&s) > before - after, "the chamfer takes the ball's bulge off too");
|
||||
}
|
||||
|
||||
/// Rounds of the edges at the arc's top front corner, two or all three together (r 2): they meet
|
||||
/// in creases (with all three, a piece of sphere fills the corner). Each set takes off its rounds
|
||||
/// alone, less what each alone takes in a box about the corner, plus what they take there
|
||||
|
||||
@@ -500,18 +500,20 @@ fn planned_volume(s: &Session) -> f64 {
|
||||
/// #851: the knife edge where the wall runs out has opposite normals on its two faces. It rounds
|
||||
/// to the ball that fits there and chamfers with the plane through that ball's contacts (the cusp
|
||||
/// area less the wall's sector and the ball's, or the chord triangle less the wall's segment,
|
||||
/// times the 10 mm height).
|
||||
/// times the 10 mm height). The ball 2 from both faces sits at (62⅙ − √168, −2); the round takes
|
||||
/// 10 (11.5 √168 − 220.5 θ − 2 (π − θ)), θ = acos(19/23), within 5e-4 of it.
|
||||
#[test]
|
||||
fn blend_a_knife_edge_where_a_curved_wall_runs_out() {
|
||||
let knife = json!([[62.1667, 0, 5]]);
|
||||
for (command, params, removed) in
|
||||
[("solid.fillet", json!({"edges": knife, "radius": 2}), 119.648_812), ("solid.chamfer", json!({"edges": knife, "distance": 2}), 159.236_451)]
|
||||
{
|
||||
for (command, params, removed, within) in [
|
||||
("solid.fillet", json!({"edges": knife, "radius": 2}), 119.648_812, 119.648_812 * 5e-4),
|
||||
("solid.chamfer", json!({"edges": knife, "distance": 2}), 159.236_451, 0.5),
|
||||
] {
|
||||
let mut s = knife_edge_part();
|
||||
let before = planned_volume(&s);
|
||||
s.execute(command, ¶ms).unwrap_or_else(|e| panic!("{command}: {e}"));
|
||||
let after = planned_volume(&s);
|
||||
assert!((before - after - removed).abs() < 0.5, "{command}: removed {}, expected {removed}", before - after);
|
||||
assert!((before - after - removed).abs() < within, "{command}: removed {}, expected {removed}", before - after);
|
||||
for b in &s.model.state().bodies {
|
||||
assert!(b.body.validity().is_empty(), "{command}: {:?}", b.body.validity());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user