mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 10:35:58 +00:00
Kernel tests: rim rounds meeting at a concave corner are mitred, not swept
The owner's final ruling of 2026-10-30 reverses the swept corner6539c070aand8dc344d22used: rim rounds meeting at a concave corner beside an unpicked sharp edge are mitred by default (a user who wants it swept rounds the corner edge too; a swept corner with a sharp inner edge is a future option). SMLib's swept result is the defect, so both tests now expect the mitre and fail today on it. rounds_that_fit_are_closed. At depth u the section is the outline moved in by d = r - sqrt(r^2 - (r - u)^2) with every corner mitred: the area less L d, plus d^2 at each of the six convex corners (the two strips overlap in a d x d square) and less d^2 at each of the six concave ones (the mitre also takes the d x d square beyond both strips), the overlap of the two spandrel prisms being r^3 (5/3 - pi/2) per corner over the round. Six and six cancel, so both ends remove 2 L r^2 (1 - pi/4) with L = 107.6: 11.545566 (the swept corners gave 11.514718). fillet_tabbed_plate_outer_loop_and_partial_selection_after_hole. Where both sides of a concave corner (+-4, sqrt(609)) move, the moved R25 arc and the moved side x = 4 - d now meet where they cross, y = sqrt((25 - d)^2 - (4 - d)^2), as where only one side moves; the swept arc branch goes. Check: A(0,0) - A(d,d) agrees with the Steiner form for a mitred outline, L d - d^2 (pi + theta - 2 tan(theta/2)), to second order (17.190976 against 17.190968 at d = 0.1; the arc's curvature moves the mitre point at third order, which the Green's-theorem area has exactly). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -51,15 +51,16 @@ fn overlapping_rounds_are_refused() {
|
||||
|
||||
/// Below half the wall the rounds fit: a closed solid with a round on every edge. Each end face's
|
||||
/// round section at depth u into the round is the end face's outline moved in by
|
||||
/// d = r − √(r² − (r − u)²), each edge parallel to itself: the area less L d (L the outline's
|
||||
/// and the window's length together, 2 · 41.5 + 2 · 12.3 = 107.6), plus d² at each of the six
|
||||
/// convex corners (two rounds mitred) and less π d² / 4 at each of the six concave ones, the two
|
||||
/// shoulders and the window's four corners (two rounds meeting at a concave corner beside an
|
||||
/// unpicked sharp edge are swept round it, the owner's ruling of 2026-10-30). Over the round,
|
||||
/// ∫ d = r² (1 − π/4) and ∫ d² = r³ (5/3 − π/2), at both ends.
|
||||
/// d = r − √(r² − (r − u)²), each edge parallel to itself and every corner mitred (two rounds
|
||||
/// meeting at a corner beside an unpicked sharp edge, convex or concave: the owner's ruling of
|
||||
/// 2026-10-30): the area less L d (L the outline's and the window's length together,
|
||||
/// 2 · 41.5 + 2 · 12.3 = 107.6), plus d² at each of the six convex corners (the two strips
|
||||
/// overlap) and less d² at each of the six concave ones (the two shoulders and the window's four
|
||||
/// corners: the mitre takes the d × d square beyond both strips). The corner terms cancel, so
|
||||
/// both ends remove 2 L ∫ d = 2 L r² (1 − π/4).
|
||||
#[test]
|
||||
fn rounds_that_fit_are_closed() {
|
||||
use std::f64::consts::{FRAC_PI_2, FRAC_PI_4};
|
||||
use std::f64::consts::FRAC_PI_4;
|
||||
let p = part();
|
||||
let r = 0.5;
|
||||
let b = crate::fillet(&p, &edges(), r).unwrap();
|
||||
@@ -69,8 +70,7 @@ fn rounds_that_fit_are_closed() {
|
||||
let part_volume = 14.0 * (21.5 * 10.0 + (top - a) * 10.0 - 5.2 * 7.1);
|
||||
assert!((crate::measure(&p).unwrap().volume - part_volume).abs() < 1e-9 * part_volume);
|
||||
let length = 2.0 * (21.5 + 20.0) + 2.0 * (5.2 + 7.1);
|
||||
let corners = 6.0 - 6.0 * FRAC_PI_4;
|
||||
let removed = 2.0 * (length * r * r * (1.0 - FRAC_PI_4) - corners * r * r * r * (5.0 / 3.0 - FRAC_PI_2));
|
||||
let removed = 2.0 * length * r * r * (1.0 - FRAC_PI_4);
|
||||
let v = crate::measure(&b).unwrap().volume;
|
||||
assert!((v - (part_volume - removed)).abs() < 1e-7 * part_volume, "{v} vs {}", part_volume - removed);
|
||||
}
|
||||
|
||||
@@ -1953,23 +1953,16 @@ fn fillet_sharp_arc_and_arc_loop() {
|
||||
/// with the R25 arc moved in by `da` and the tab's run (its sides, R2 corners and top) by `dt`,
|
||||
/// each element parallel to itself, by Green's theorem: an arc about c of radius ρ from a to b
|
||||
/// gives ½ (ρ² (b − a) + ρ (cx (sin b − sin a) − cy (cos b − cos a))), a segment p→q ½ (p × q).
|
||||
/// Where only one side of a concave corner at (±4, y) moves the elements meet where they cross
|
||||
/// (the round runs into the other wall); where both do, the corner is swept, an arc of radius d
|
||||
/// about the corner (the owner's ruling for rounds meeting at a concave corner, 2026-10-30).
|
||||
/// At the concave corners (±4, y) the moved elements meet where they cross: where one side moves
|
||||
/// the round runs into the other wall, where both do the two rounds are mitred (the owner's
|
||||
/// ruling for rounds meeting at a concave corner beside an unpicked sharp edge, 2026-10-30).
|
||||
fn tabbed_plate_area(da: f64, dt: f64) -> f64 {
|
||||
let (y, cy) = ((625.0_f64 - 16.0).sqrt(), 280.0 / 9.0);
|
||||
let theta = (4.0_f64 / 25.0).acos();
|
||||
let cy = 280.0 / 9.0;
|
||||
let (big, rho) = (25.0 - da, 2.0 - dt);
|
||||
let tab = rho * rho * PI + 2.0 * rho * (2.0 + cy) + 4.0 * (cy + rho);
|
||||
if da > 0.0 && dt > 0.0 {
|
||||
assert!((da - dt).abs() < 1e-15, "a swept corner of one size");
|
||||
let corner = -da * da * theta + da * (4.0 * theta.sin() + y * (1.0 - theta.cos()));
|
||||
0.5 * (big * big * (PI + 2.0 * theta) + 2.0 * corner + tab) + (4.0 - dt) * (cy - y)
|
||||
} else {
|
||||
let yc = (big * big - (4.0 - dt).powi(2)).sqrt();
|
||||
let at = yc.atan2(4.0 - dt);
|
||||
0.5 * (big * big * (PI + 2.0 * at) + tab) + (4.0 - dt) * (cy - yc)
|
||||
}
|
||||
let yc = (big * big - (4.0 - dt).powi(2)).sqrt();
|
||||
let at = yc.atan2(4.0 - dt);
|
||||
0.5 * (big * big * (PI + 2.0 * at) + tab) + (4.0 - dt) * (cy - yc)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user