kernel-cases: sweeps coil and surface cases from #793-#4056

Coils split and trimmed by a plane, cut with a negative pitch, joined flush round a cylinder, intersected with a cylinder, cut as a thread groove into a bore, and placed with a square wire outside the diameter (screw-motion Pappus); surface revolve, sweep and loft sheets with areas worked out by integration, and a rail-guided surface loft in either section order.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Brennen Herbruck
2026-10-21 06:21:00 -04:00
committed by jyviko
parent 5f131cb888
commit 434a68bbc2
24 changed files with 1219 additions and 0 deletions
@@ -0,0 +1,10 @@
{
"sources": [
"tangency-labs/solidcraft#1411"
],
"what": "a 4-turn coil (centre diameter 40, wire 3 mm, pitch 8) intersected with a cylinder of radius 25 and height 40 that holds it (crash report: unclean exit in solid.coil)",
"source": "analytic",
"method": "the wire (radius 20 +- 1.5, z -1.5..33.5) lies wholly inside the cylinder (r 25, z -2..38), so the intersection is the coil: V = pi 1.5^2 * 2 pi 20 * 4 = 3553.1.",
"body_count": 1,
"volume_mm3": 3553.057584392169
}
@@ -0,0 +1,30 @@
{
"commands": [
{
"command": "solid.cylinder",
"params": {
"radius": 25,
"height": 40,
"base": [
0,
0,
-2
],
"axis": "Z",
"body_name": "Blank"
}
},
{
"command": "solid.coil",
"params": {
"diameter": 40,
"revolutions": 4,
"pitch": 8,
"section_size": 3,
"section": "circular",
"section_position": "center",
"operation": "intersect"
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [
"tangency-labs/solidcraft#2552"
],
"what": "a square-wire coil (diameter 10, section 0.9 inside, pitch 1.5, height 10) cut as a helical groove into the wall of a bore of radius 4.1 in a 30 x 30 x 12 block (crash report: unclean exit in solid.coil)",
"source": "analytic",
"method": "the coil section is 0.9 x 0.9 with centre radius 5 - 0.45 = 4.55, so it spans r 4.1 to 5.0 (its inner face is the bore wall) and turns 10/1.5 = 6.667 times: V_groove = 0.81 * 2 pi 4.55 * 6.667 = 154.4; V = 30 * 30 * 12 - pi 4.1^2 12 - V_groove = 10011.9. The groove opens into the bore (one body).",
"body_count": 1,
"volume_mm3": 10011.900066920465
}
@@ -0,0 +1,56 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 30,
"width": 30,
"height": 12,
"corner": [
-7,
-7,
-1
],
"body_name": "Block"
}
},
{
"command": "solid.cylinder",
"params": {
"radius": 4.1,
"height": 12,
"base": [
8,
8,
-1
],
"operation": "cut",
"targets": [
"Block"
]
}
},
{
"command": "solid.coil",
"params": {
"axis": "Z",
"base": [
8,
8,
0
],
"diameter": 10,
"height": 10,
"pitch": 1.5,
"section": "square",
"section_position": "inside",
"section_size": 0.9,
"name": "Helical thread groove",
"operation": "cut",
"targets": [
"Block"
]
}
}
]
}
@@ -0,0 +1,23 @@
{
"sources": [
"tangency-labs/solidcraft#3088",
"tangency-labs/solidcraft#3758"
],
"what": "a 4-turn square coil (4 mm wire, pitch 9, outer diameter 30.8, section inside) joined round a cylinder of radius 15 and height 40, its ends flush with the cylinder end faces (hang of several minutes, crash report)",
"source": "analytic",
"method": "the wire is a 4 x 4 square, radial 11.4..15.4, axial +-2 about a path rising from z = 2 to 38, so its end faces touch z = 0 and z = 40. Inside r = 15 it merges with the cylinder; the ridge outside r = 15 is a 0.4 x 4 section at centroid radius 15.2 turned 4 times by the screw: V = pi 15^2 40 + 1.6 * 2 pi 15.2 * 4 = 28885.5. bbox r 15.4, z 0..40.",
"body_count": 1,
"volume_mm3": 28885.562148990564,
"bbox": {
"min": [
-15.4,
-15.4,
0
],
"max": [
15.4,
15.4,
40
]
}
}
@@ -0,0 +1,41 @@
{
"commands": [
{
"command": "solid.cylinder",
"params": {
"radius": 15,
"height": 40,
"base": [
0,
0,
0
],
"axis": "Z",
"body_name": "Body2"
}
},
{
"command": "solid.coil",
"params": {
"axis": "Z",
"base": [
0,
0,
2
],
"clockwise": true,
"diameter": 30.8,
"height": 36,
"name": "HoseThread",
"operation": "join",
"pitch": 9,
"section": "square",
"section_position": "inside",
"section_size": 4,
"targets": [
"Body2"
]
}
}
]
}
@@ -0,0 +1,11 @@
{
"sources": [
"tangency-labs/solidcraft#3832"
],
"what": "a 7-turn coil (centre diameter 80, wire 1 mm, pitch -2 so it winds downward) cut from a cylinder that holds it entirely (boolean Cut: no result)",
"source": "analytic",
"method": "cylinder r 45, z -20..20 holds the wire (r 40 +- 0.5, z 0 down to -14) wholly, leaving a helical tunnel sealed inside (a body with an internal void: the expected shell count is 2, which the rig cannot grade, so valid is false): V = pi 45^2 40 - pi 0.5^2 * 2 pi 40 * 7 = 253087.3.",
"valid": false,
"body_count": 1,
"volume_mm3": 253087.26032462073
}
@@ -0,0 +1,35 @@
{
"commands": [
{
"command": "solid.cylinder",
"params": {
"radius": 45,
"height": 40,
"base": [
0,
0,
-20
],
"axis": "Z",
"body_name": "Blank"
}
},
{
"command": "solid.coil",
"params": {
"diameter": 80,
"revolutions": 7,
"pitch": -2,
"section_size": 1,
"section": "circular",
"section_position": "center",
"base": [
0,
0,
0
],
"operation": "cut"
}
}
]
}
@@ -0,0 +1,23 @@
{
"sources": [
"tangency-labs/solidcraft#3862",
"tangency-labs/solidcraft#3915"
],
"what": "a clockwise 5-turn coil of 4 mm square wire placed outside a 40 mm diameter, pitch 8 (the section, position and direction parameters)",
"source": "analytic",
"method": "outside puts the wire centre at radius 20 + 2 = 22 (radial 20..24); the 4 x 4 section turned 5 times by the screw: V = 16 * 2 pi 22 * 5 = 11060.6. bbox r 24, z from -2 to 40 + 2.",
"body_count": 1,
"volume_mm3": 11058.40614063607,
"bbox": {
"min": [
-24,
-24,
-2
],
"max": [
24,
24,
42
]
}
}
@@ -0,0 +1,18 @@
{
"commands": [
{
"command": "solid.coil",
"params": {
"diameter": 40,
"revolutions": 5,
"pitch": 8,
"section_size": 4,
"section": "square",
"section_position": "outside",
"clockwise": true,
"name": "Spring",
"operation": "new"
}
}
]
}
@@ -0,0 +1,24 @@
{
"sources": [
"tangency-labs/solidcraft#4056",
"tangency-labs/solidcraft#4080"
],
"what": "a surface loft between a vertical line on XZ (bow) and a slanted line in the plane x = 100 (stern), bow to stern, guided by a keel rail lying in the bow sketch plane and a sheer rail at z = 20 (refused: \"a guide rail crosses section 2's plane\")",
"source": "analytic",
"method": "with straight sections and straight rails the surface is the bilinear patch S(t,s) = (100 t, 40 t s, 20 s), which contains both rails (s = 0: keel, s = 1: sheer) and both sections (t = 0, 1); S_t = (100, 40 s, 0), S_s = (0, 40 t, 20), cross = (800 s, -2000, 4000 t); A = double integral of its length = 2995.833 (Gauss-Legendre). One face, open (valid false); bbox 0..100, 0..40, 0..20. The loft is independent of the order of the sections.",
"valid": false,
"area_mm2": 2995.832811766292,
"faces": 1,
"bbox": {
"min": [
0,
0,
0
],
"max": [
100,
40,
20
]
}
}
@@ -0,0 +1,221 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Bow"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
0,
20
]
],
"infer": false,
"ids": [
"b1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
100.0,
0.0,
0.0
],
"x_dir": [
0,
1,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Stern"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
40,
20
]
],
"infer": false,
"ids": [
"s1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Keel"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
100,
0
]
],
"infer": false,
"ids": [
"k1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
20.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "Sheer"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
100,
40
]
],
"infer": false,
"ids": [
"h1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "surface.loft",
"params": {
"sections": [
{
"sketch": "Bow",
"curves": [
"b1"
]
},
{
"sketch": "Stern",
"curves": [
"s1"
]
}
],
"rails": [
{
"sketch": "Keel",
"curves": [
"k1"
]
},
{
"sketch": "Sheer",
"curves": [
"h1"
]
}
]
}
}
]
}
@@ -0,0 +1,24 @@
{
"sources": [
"tangency-labs/solidcraft#4056",
"tangency-labs/solidcraft#4080"
],
"what": "a surface loft between a vertical line on XZ (bow) and a slanted line in the plane x = 100 (stern), stern to bow, guided by a keel rail lying in the bow sketch plane and a sheer rail at z = 20 (refused: \"a guide rail crosses section 2's plane\")",
"source": "analytic",
"method": "with straight sections and straight rails the surface is the bilinear patch S(t,s) = (100 t, 40 t s, 20 s), which contains both rails (s = 0: keel, s = 1: sheer) and both sections (t = 0, 1); S_t = (100, 40 s, 0), S_s = (0, 40 t, 20), cross = (800 s, -2000, 4000 t); A = double integral of its length = 2995.833 (Gauss-Legendre). One face, open (valid false); bbox 0..100, 0..40, 0..20. The loft is independent of the order of the sections.",
"valid": false,
"area_mm2": 2995.832811766292,
"faces": 1,
"bbox": {
"min": [
0,
0,
0
],
"max": [
100,
40,
20
]
}
}
@@ -0,0 +1,221 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Bow"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
0,
20
]
],
"infer": false,
"ids": [
"b1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
100.0,
0.0,
0.0
],
"x_dir": [
0,
1,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Stern"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
40,
20
]
],
"infer": false,
"ids": [
"s1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Keel"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
100,
0
]
],
"infer": false,
"ids": [
"k1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
20.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "Sheer"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
100,
40
]
],
"infer": false,
"ids": [
"h1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "surface.loft",
"params": {
"sections": [
{
"sketch": "Stern",
"curves": [
"s1"
]
},
{
"sketch": "Bow",
"curves": [
"b1"
]
}
],
"rails": [
{
"sketch": "Keel",
"curves": [
"k1"
]
},
{
"sketch": "Sheer",
"curves": [
"h1"
]
}
]
}
}
]
}
@@ -0,0 +1,24 @@
{
"sources": [
"tangency-labs/solidcraft#757",
"tangency-labs/solidcraft#847"
],
"what": "a surface loft between the line (0,0,0)-(10,0,0) and the line (0,0,20)-(10,6,20): a ruled (bilinear) strip",
"source": "analytic",
"method": "S(u,v) = (1-v)(10u,0,0) + v(10u,6u,20): S_u = (10, 6v, 0), S_v = (0, 6u, 20), S_u x S_v = (120 v, -200, 60 u); A = double integral over the unit square of sqrt(14400 v^2 + 40000 + 3600 u^2) = 214.2336 (Gauss-Legendre, 48 points each way). One face, open (valid false).",
"valid": false,
"area_mm2": 214.23356244227966,
"faces": 1,
"bbox": {
"min": [
0,
0,
0
],
"max": [
10,
6,
20
]
}
}
@@ -0,0 +1,115 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "A"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
10,
0
]
],
"infer": false,
"ids": [
"c1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
20.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "B"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
10,
6
]
],
"infer": false,
"ids": [
"c2"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "surface.loft",
"params": {
"sections": [
{
"sketch": "A",
"curves": [
"c1"
]
},
{
"sketch": "B",
"curves": [
"c2"
]
}
]
}
}
]
}
@@ -0,0 +1,24 @@
{
"sources": [
"tangency-labs/solidcraft#757",
"tangency-labs/solidcraft#824"
],
"what": "a line from (5,0) to (10,20) revolved a full turn into a surface body (a cone frustum wall, no caps)",
"source": "analytic",
"method": "lateral area of a frustum: pi (r1 + r2) slant = pi 15 sqrt(5^2 + 20^2) = 971.48; one conical face; open at both ends, so not a solid (valid false); bbox r 10, z 0..20.",
"valid": false,
"area_mm2": 971.4838757561392,
"faces": 1,
"bbox": {
"min": [
-10,
-10,
0
],
"max": [
10,
10,
20
]
}
}
@@ -0,0 +1,60 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "P"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
5,
0
],
[
10,
20
]
],
"infer": false,
"ids": [
"l1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "surface.revolve",
"params": {
"curves": [
"l1"
],
"axis": "y",
"angle": "360 deg"
}
}
]
}
@@ -0,0 +1,24 @@
{
"sources": [
"tangency-labs/solidcraft#757",
"tangency-labs/solidcraft#843"
],
"what": "a slanted line (from (20,0,0) to (30,0,10)) swept as a surface round a quarter circle of radius 20 about Z",
"source": "analytic",
"method": "the profile lies in a plane through the Z axis and the path is a circle about that axis, so the sheet is a quarter of a cone frustum wall: A = (1/4) pi (r1 + r2) slant = (1/4) pi 50 sqrt(200) = 555.4; one face; open (valid false); bbox x, y 0..30, z 0..10.",
"valid": false,
"area_mm2": 555.3603672697958,
"faces": 1,
"bbox": {
"min": [
0,
0,
0
],
"max": [
30,
30,
10
]
}
}
@@ -0,0 +1,107 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "Path"
}
},
{
"command": "sketch.arc.center_point",
"params": {
"center": [
0,
0
],
"start": [
20,
0
],
"end": [
0,
20
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Sec"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
20,
0
],
[
30,
10
]
],
"infer": false,
"ids": [
"c1"
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "surface.sweep",
"params": {
"sketch": "Sec",
"curves": [
"c1"
],
"path_sketch": "Path",
"path": [
"a1"
]
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [
"tangency-labs/solidcraft#793"
],
"what": "the same coil trimmed flat by cutting away everything above z = 12.5 with a box (trimming a coil to length)",
"source": "analytic",
"method": "a disc of radius 1 whose centre rises with the screw (z0 = 4 theta / 2 pi) keeps the part below z = 12.5, symmetric about its vertical diameter, so its centroid stays at radius R = 20: V = R (2 pi / p) integral over z0 in [0,24] of Ak(12.5 - z0) dz0 with Ak(h) = rs^2 (t sqrt(1-t^2) + asin t + pi/2), t = h/rs, clamped to 0 below -rs and pi rs^2 above rs: V = 1234.893 (Gauss-Legendre).",
"body_count": 1,
"volume_mm3": 1234.8927457642485
}
@@ -0,0 +1,46 @@
{
"commands": [
{
"command": "solid.coil",
"params": {
"diameter": 40,
"revolutions": 6,
"pitch": 4.0,
"section_size": 2.0,
"section": "circular",
"section_position": "center",
"base": [
0,
0,
0
],
"operation": "new",
"body_name": "Spring"
}
},
{
"command": "solid.box",
"params": {
"length": 60,
"width": 60,
"height": 20,
"corner": [
-30,
-30,
12.5
],
"body_name": "Above"
}
},
{
"command": "solid.combine",
"params": {
"target": "Spring",
"tools": [
"Above"
],
"operation": "cut"
}
}
]
}
@@ -0,0 +1,22 @@
{
"sources": [
"tangency-labs/solidcraft#793"
],
"what": "a 6-turn coil (centre diameter 40, wire 2 mm, pitch 4) split by the plane z = 12.5 square to its axis (\"boolean Intersect: no result\")",
"source": "analytic",
"method": "the wire is a circle of radius 1 turned by a screw motion about Z (section in a plane through the axis): V = pi r^2 * 2 pi R * N = pi * 2 pi 20 * 6 = 2368.7. Splitting does not change the total, the plane cuts the helix obliquely and each half stays one connected spiral: two bodies whose volumes add up to the coil.",
"body_count": 2,
"volume_mm3": 2368.705056261446,
"bbox": {
"min": [
-21,
-21,
-1
],
"max": [
21,
21,
25
]
}
}
@@ -0,0 +1,40 @@
{
"commands": [
{
"command": "solid.coil",
"params": {
"diameter": 40,
"revolutions": 6,
"pitch": 4.0,
"section_size": 2.0,
"section": "circular",
"section_position": "center",
"base": [
0,
0,
0
],
"operation": "new",
"body_name": "Spring"
}
},
{
"command": "solid.split_body",
"params": {
"body": "Spring",
"plane": {
"origin": [
0,
0,
12.5
],
"normal": [
0,
0,
1
]
}
}
}
]
}