Shell and offset faces on cones and spheres too (a dome moves to a smaller sphere about its centre, a cone's apex slides along its axis); surface fitting robust to poles and half cylinders; a shell retries on the unhealed body when the healed one won't cut
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
fec99468d2
commit
0ee343b9e6
4 files changed
+166
-11
No files matched your search
@@ -1211,3 +1211,30 @@ fn fillet_three_edges_at_a_corner() {
|
||||
let m = measure(&f).unwrap().merged;
|
||||
assert_eq!(m.face_types.get("sphere"), Some(&1), "{m:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shell_with_spherical_and_conical_faces() {
|
||||
// A cylinder capped by a hemisphere (a dome), revolved, opened at the bottom.
|
||||
use solvecraft_geom::Seg2;
|
||||
let xz = Plane::new(Vec3::ZERO, Vec3::X, Vec3::new(0.0, 0.0, -1.0)).unwrap();
|
||||
let segs = vec![
|
||||
Seg2::Line { a: Vec2::new(0.0, 0.0), b: Vec2::new(10.0, 0.0) },
|
||||
Seg2::Line { a: Vec2::new(10.0, 0.0), b: Vec2::new(10.0, -20.0) },
|
||||
Seg2::Arc { center: Vec2::new(0.0, -20.0), radius: 10.0, start: 0.0, sweep: -PI / 2.0 },
|
||||
Seg2::Line { a: Vec2::new(0.0, -30.0), b: Vec2::new(0.0, 0.0) },
|
||||
];
|
||||
let b = revolve(&xz, &[Region2 { outer: Loop2 { segs }, holes: vec![] }], Vec2::ZERO, Vec2::new(0.0, -1.0), 2.0 * PI).unwrap().pop().unwrap();
|
||||
let s = shell(&b, &[Vec3::new(0.0, 0.0, 0.0)], 1.0).unwrap();
|
||||
let outer = PI * 100.0 * 20.0 + 2.0 / 3.0 * PI * 1000.0;
|
||||
let inner = PI * 81.0 * 20.0 + 2.0 / 3.0 * PI * 729.0;
|
||||
let v = measure(&s).unwrap().volume;
|
||||
assert!(rel(v, outer - inner) < 2e-3, "{v} vs {}", outer - inner);
|
||||
// A cone frustum (a revolved trapezoid), opened at its wide base.
|
||||
let prof =
|
||||
Region2 { outer: Loop2::polygon(&[Vec2::new(0.0, 0.0), Vec2::new(10.0, 0.0), Vec2::new(5.0, -10.0), Vec2::new(0.0, -10.0)]), holes: vec![] };
|
||||
let fr = revolve(&xz, &[prof], Vec2::ZERO, Vec2::new(0.0, -1.0), 2.0 * PI).unwrap().pop().unwrap();
|
||||
let v0 = measure(&fr).unwrap().volume;
|
||||
let s = shell(&fr, &[Vec3::new(0.0, 0.0, 0.0)], 1.0).unwrap();
|
||||
let v = measure(&s).unwrap().volume;
|
||||
assert!(v > 0.1 * v0 && v < 0.6 * v0, "{v} of {v0}");
|
||||
}
|
||||
Reference in new issue
Block a user