mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-04 02:55:54 +00:00
Kernel tests: the round into a hole moves to the rig, with the hole cut the test's way
a_round_into_a_hole_is_cut_by_it (issue_324_tests.rs) built rig case fillets/324-fillet-over-hole-overlap's body, but cut its hole with a cylinder longer than the block (z -1 to 11) where the rig extrudes a sketch circle flush. The new case fillets/324-fillet-over-hole-cut-by-overlong-cylinder builds it that way (solid.cylinder, base z -1, height 12, cut) and holds it to the same hand-derived answer: block 40x20x10 less the r3 hole at (20, 14.5) (282.74) less the R4 round on the top edge at y = 20, 40 (16 - 4 pi) = 137.35, plus what both remove, the integral over y in [16, 17.5] of (4 - sqrt(16 - (y - 16)^2)) * 2 sqrt(9 - (y - 14.5)^2) = 0.375830 (re-derived with the substitution y = 17.5 - s^2, 200000 steps): V = 8000 - 90 pi - 40 (16 - 4 pi) + 0.375830 = 7580.287315, and G1 on the blend. It passes today (aarch64, SMLib), as the flush case does, so it needs no KNOWN_FAILING line; the unit test, a duplicate of the two cases, is dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,46 +0,0 @@
|
||||
//! #324: a round on a block's top edge that runs over a through hole: built as if the top went
|
||||
//! on, and cut by the hole.
|
||||
|
||||
use solidcraft_geom::Vec3;
|
||||
|
||||
use crate::{Body, BoolOp, build::box_solid, build::cylinder, ops::boolean};
|
||||
|
||||
/// A 40 x 20 x 10 block with a through hole of radius 3 at (20, `y`).
|
||||
fn block_with_hole(y: f64) -> Body {
|
||||
let block = box_solid(Vec3::new(0.0, 0.0, 0.0), Vec3::new(40.0, 20.0, 10.0)).unwrap();
|
||||
let hole = cylinder(Vec3::new(20.0, y, -1.0), Vec3::Z, 3.0, 12.0).unwrap();
|
||||
boolean(&block, &hole, BoolOp::Cut).unwrap().unwrap()
|
||||
}
|
||||
|
||||
/// The round on the top edge at y = 20 covers the top face from y = 20 - r, and the hole's
|
||||
/// wall reaches y = 17.5: a radius over 2.5 runs into the hole. R4 is built as if the top went
|
||||
/// on over the hole and cut from the block (the blend-overflow decision, 237f0ae74): the round
|
||||
/// takes 16 (1 - π/4) of the section along 40, less its part over the hole, where the round's
|
||||
/// height above its arc, 4 - √(16 - (y - 16)²), stands over the hole's width
|
||||
/// 2 √(9 - (y - 14.5)²) for y in [16, 17.5] (integrated with y = 17.5 - s², smooth in s).
|
||||
#[test]
|
||||
fn a_round_into_a_hole_is_cut_by_it() {
|
||||
use std::f64::consts::{FRAC_PI_4, PI};
|
||||
let b = block_with_hole(14.5);
|
||||
let edge = Vec3::new(10.0, 20.0, 10.0);
|
||||
let r = crate::fillet(&b, &[edge], 4.0).unwrap();
|
||||
assert!(r.validity().is_empty(), "{:?}", r.validity());
|
||||
let (n, top) = (20000, 1.5f64.sqrt());
|
||||
let over: f64 = (0..n)
|
||||
.map(|i| {
|
||||
let s = (i as f64 + 0.5) * top / n as f64;
|
||||
let y = 17.5 - s * s;
|
||||
2.0 * (9.0 - (y - 14.5).powi(2)).sqrt() * (4.0 - (16.0 - (y - 16.0).powi(2)).sqrt()) * 2.0 * s
|
||||
})
|
||||
.sum::<f64>()
|
||||
* top
|
||||
/ n as f64;
|
||||
let want = 8000.0 - PI * 9.0 * 10.0 - (40.0 * 16.0 * (1.0 - FRAC_PI_4) - over);
|
||||
let v = crate::measure(&r).unwrap().volume;
|
||||
assert!((v - want).abs() < 1e-7 * want, "{v} against {want}");
|
||||
// Clear of the hole (up to 2.5) the round keeps its whole section.
|
||||
let r = crate::fillet(&b, &[edge], 2.5).unwrap();
|
||||
let want = 8000.0 - PI * 9.0 * 10.0 - 40.0 * 2.5 * 2.5 * (1.0 - FRAC_PI_4);
|
||||
let v = r.volume_at(0.005).unwrap();
|
||||
assert!((v - want).abs() < 0.05, "{v} against {want}");
|
||||
}
|
||||
@@ -62,8 +62,6 @@ mod issue_1510_tests;
|
||||
#[cfg(test)]
|
||||
mod issue_2005_tests;
|
||||
#[cfg(test)]
|
||||
mod issue_324_tests;
|
||||
#[cfg(test)]
|
||||
mod issue_616_tests;
|
||||
#[cfg(test)]
|
||||
mod issue_674_tests;
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"sources": [
|
||||
"tangency-labs/solidcraft#324"
|
||||
],
|
||||
"what": "324-fillet-over-hole-overlap with the hole cut by a cylinder longer than the block (z -1 to 11), so the hole's wall is trimmed by both the top and the bottom face",
|
||||
"source": "analytic",
|
||||
"method": "the same body as 324-fillet-over-hole-overlap: block 40x20x10 minus a through hole of r=3 centred (20,14.5), then R4 on the top long edge at y=20. The round covers y=16..20 and removes 40*(16-4pi) = 137.35; the hole removes 9*pi*10 = 282.74; where both remove the same material (y in 16..17.5) add it back: overlap = integral over y from 16 to 17.5 of [4 - sqrt(16-(y-16)^2)] x 2 sqrt(9-(y-14.5)^2) dy = 0.3758. V = 8000 - 9*pi*10 - 40*(16-4*pi) + overlap = 7580.287.",
|
||||
"body_count": 1,
|
||||
"volume_mm3": 7580.287315360674,
|
||||
"continuity": {
|
||||
"order": "g1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"corner": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"length": 40,
|
||||
"width": 20,
|
||||
"height": 10,
|
||||
"body_name": "Block"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.cylinder",
|
||||
"params": {
|
||||
"base": [
|
||||
20,
|
||||
14.5,
|
||||
-1
|
||||
],
|
||||
"radius": 3,
|
||||
"height": 12,
|
||||
"operation": "cut"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.fillet",
|
||||
"params": {
|
||||
"edges": [
|
||||
[
|
||||
10,
|
||||
20,
|
||||
10
|
||||
]
|
||||
],
|
||||
"radius": "4 mm"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user