test: reference cases for variable, chord-length and tapered fillets (#776)

Four analytic reference cases for variable, to-zero, chord-length and taper-to-fit fillets, with the formulas in tools/oracle-analytic.
This commit is contained in:
Irakli Kourtis authored and GitHub committed 2026-10-13 12:35:16 -04:00
1 parent 7b0a1b296c
commit 8cdefd4cd5
13 files changed
+1010 -7

No files matched your search

@@ -0,0 +1,25 @@
{
"source": "analytic",
"method": "box 40x30x20 with its top front edge (y=0, z=20) rounded at a radius running straight from 2 (x=0) to 5 (x=40): sections are quarter rounds, V = abc - (1 - pi/4) L (a^2 + ab + b^2) / 3; moments and the round's area integrated along the edge (tools/oracle-analytic/cases_fillets.py)",
"body_count": 1,
"volume_mm3": 23888.407044966672,
"area_mm2": 5133.743774393379,
"center_of_mass": [
19.974846161095797,
15.065997951540359,
9.957359184584975
],
"bbox": {
"min": [
0.0,
0.0,
0.0
],
"max": [
40.0,
30.0,
20.0
]
},
"faces": 7
}
@@ -0,0 +1,186 @@
{
"id": "77-fillet-variable-linear",
"name": "Variable fillet, linear radius",
"description": "40x30x20 box, the top front edge rounded with a radius running linearly from 2 mm (x = 0) to 5 mm (x = 40).",
"exercises": [
"extrude",
"fillet",
"variable radius"
],
"units": {
"length": "mm",
"angle": "deg",
"area": "mm2",
"volume": "mm3"
},
"conventions": {
"world": "right-handed; Z up. XY/XZ/YZ are the origin planes.",
"sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.",
"point_refs": "'<id>.start' / '<id>.end' / '<id>.center' reuse (share) that existing sketch point; 'at' is its position when referenced.",
"extrude_direction": "positive = along sketch plane normal unless stated",
"selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it."
},
"parameters": [],
"features": [
{
"op": "sketch",
"name": "Extrude1_sketch",
"plane": {
"ref": "XY",
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1.0,
0.0,
0.0
],
"y_dir": [
0.0,
1.0,
0.0
],
"normal": [
0.0,
0.0,
1.0
]
},
"entities": [
{
"type": "line",
"start": {
"at": [
0,
0
]
},
"end": {
"at": [
40,
0
]
},
"id": "l1"
},
{
"type": "line",
"start": {
"ref": "l1.end",
"at": [
40.0,
0.0
]
},
"end": {
"at": [
40,
30
]
},
"id": "l2"
},
{
"type": "line",
"start": {
"ref": "l2.end",
"at": [
40.0,
30.0
]
},
"end": {
"at": [
0,
30
]
},
"id": "l3"
},
{
"type": "line",
"start": {
"ref": "l3.end",
"at": [
0.0,
30.0
]
},
"end": {
"ref": "l1.start",
"at": [
0.0,
0.0
]
},
"id": "l4"
}
],
"constraints": [],
"dimensions": []
},
{
"op": "extrude",
"name": "Extrude1",
"operation": "new",
"profiles": [
{
"sketch": "Extrude1_sketch",
"loops": [
{
"outer": true,
"curves": [
"l1",
"l2",
"l3",
"l4"
]
}
]
}
],
"extent": {
"type": "distance",
"distance": 20,
"direction": "positive"
},
"result_bodies": [
"Part"
]
},
{
"op": "fillet",
"name": "Fillet1",
"type": "variable_radius",
"radius": 2.0,
"radius2": 5.0,
"start": [
0.0,
0.0,
20.0
],
"edges": [
{
"type": "line",
"start": [
0.0,
0.0,
20.0
],
"end": [
40.0,
0.0,
20.0
],
"point": [
20.0,
0.0,
20.0
]
}
]
}
]
}
@@ -0,0 +1,25 @@
{
"source": "analytic",
"method": "as 77 with the radius running from 4 (x=0) down to 0 (x=40), where the round closes to the corner: V = abc - (1 - pi/4) L a^2 / 3; the round is three-sided and the corner at x=40 stays",
"body_count": 1,
"volume_mm3": 23954.21827485812,
"area_mm2": 5162.286695397177,
"center_of_mass": [
20.019112176659895,
15.027387550737057,
9.98216853759289
],
"bbox": {
"min": [
0.0,
0.0,
0.0
],
"max": [
40.0,
30.0,
20.0
]
},
"faces": 7
}
@@ -0,0 +1,186 @@
{
"id": "78-fillet-variable-to-zero",
"name": "Variable fillet closing at a corner",
"description": "40x30x20 box, the top front edge rounded with a radius running linearly from 4 mm (x = 0) down to 0 at x = 40, where the round closes to the corner.",
"exercises": [
"extrude",
"fillet",
"variable radius"
],
"units": {
"length": "mm",
"angle": "deg",
"area": "mm2",
"volume": "mm3"
},
"conventions": {
"world": "right-handed; Z up. XY/XZ/YZ are the origin planes.",
"sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.",
"point_refs": "'<id>.start' / '<id>.end' / '<id>.center' reuse (share) that existing sketch point; 'at' is its position when referenced.",
"extrude_direction": "positive = along sketch plane normal unless stated",
"selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it."
},
"parameters": [],
"features": [
{
"op": "sketch",
"name": "Extrude1_sketch",
"plane": {
"ref": "XY",
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1.0,
0.0,
0.0
],
"y_dir": [
0.0,
1.0,
0.0
],
"normal": [
0.0,
0.0,
1.0
]
},
"entities": [
{
"type": "line",
"start": {
"at": [
0,
0
]
},
"end": {
"at": [
40,
0
]
},
"id": "l1"
},
{
"type": "line",
"start": {
"ref": "l1.end",
"at": [
40.0,
0.0
]
},
"end": {
"at": [
40,
30
]
},
"id": "l2"
},
{
"type": "line",
"start": {
"ref": "l2.end",
"at": [
40.0,
30.0
]
},
"end": {
"at": [
0,
30
]
},
"id": "l3"
},
{
"type": "line",
"start": {
"ref": "l3.end",
"at": [
0.0,
30.0
]
},
"end": {
"ref": "l1.start",
"at": [
0.0,
0.0
]
},
"id": "l4"
}
],
"constraints": [],
"dimensions": []
},
{
"op": "extrude",
"name": "Extrude1",
"operation": "new",
"profiles": [
{
"sketch": "Extrude1_sketch",
"loops": [
{
"outer": true,
"curves": [
"l1",
"l2",
"l3",
"l4"
]
}
]
}
],
"extent": {
"type": "distance",
"distance": 20,
"direction": "positive"
},
"result_bodies": [
"Part"
]
},
{
"op": "fillet",
"name": "Fillet1",
"type": "variable_radius",
"radius": 4.0,
"radius2": 0.0,
"start": [
0.0,
0.0,
20.0
],
"edges": [
{
"type": "line",
"start": [
0.0,
0.0,
20.0
],
"end": [
40.0,
0.0,
20.0
],
"point": [
20.0,
0.0,
20.0
]
}
]
}
]
}
@@ -0,0 +1,25 @@
{
"source": "analytic",
"method": "box 40x30x20, top front edge rounded 4 wide across (chord c): r = c / (2 cos 45 deg) = 2 sqrt 2; V = abc - (1 - pi/4) r^2 L, A = 2(ab + bc + ca) - 2 r L + (pi/2) r L - 2 (1 - pi/4) r^2",
"body_count": 1,
"volume_mm3": 23931.327412287184,
"area_mm2": 5148.007518160999,
"center_of_mass": [
20.0,
15.041230594339089,
9.973117249081739
],
"bbox": {
"min": [
0.0,
0.0,
0.0
],
"max": [
40.0,
30.0,
20.0
]
},
"faces": 7
}
@@ -0,0 +1,180 @@
{
"id": "79-fillet-chord-length",
"name": "Chord-length fillet",
"description": "40x30x20 box, the top front edge rounded so the round is 4 mm wide across (chord length).",
"exercises": [
"extrude",
"fillet",
"chord length"
],
"units": {
"length": "mm",
"angle": "deg",
"area": "mm2",
"volume": "mm3"
},
"conventions": {
"world": "right-handed; Z up. XY/XZ/YZ are the origin planes.",
"sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.",
"point_refs": "'<id>.start' / '<id>.end' / '<id>.center' reuse (share) that existing sketch point; 'at' is its position when referenced.",
"extrude_direction": "positive = along sketch plane normal unless stated",
"selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it."
},
"parameters": [],
"features": [
{
"op": "sketch",
"name": "Extrude1_sketch",
"plane": {
"ref": "XY",
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1.0,
0.0,
0.0
],
"y_dir": [
0.0,
1.0,
0.0
],
"normal": [
0.0,
0.0,
1.0
]
},
"entities": [
{
"type": "line",
"start": {
"at": [
0,
0
]
},
"end": {
"at": [
40,
0
]
},
"id": "l1"
},
{
"type": "line",
"start": {
"ref": "l1.end",
"at": [
40.0,
0.0
]
},
"end": {
"at": [
40,
30
]
},
"id": "l2"
},
{
"type": "line",
"start": {
"ref": "l2.end",
"at": [
40.0,
30.0
]
},
"end": {
"at": [
0,
30
]
},
"id": "l3"
},
{
"type": "line",
"start": {
"ref": "l3.end",
"at": [
0.0,
30.0
]
},
"end": {
"ref": "l1.start",
"at": [
0.0,
0.0
]
},
"id": "l4"
}
],
"constraints": [],
"dimensions": []
},
{
"op": "extrude",
"name": "Extrude1",
"operation": "new",
"profiles": [
{
"sketch": "Extrude1_sketch",
"loops": [
{
"outer": true,
"curves": [
"l1",
"l2",
"l3",
"l4"
]
}
]
}
],
"extent": {
"type": "distance",
"distance": 20,
"direction": "positive"
},
"result_bodies": [
"Part"
]
},
{
"op": "fillet",
"name": "Fillet1",
"type": "chord_length",
"radius": 4.0,
"edges": [
{
"type": "line",
"start": [
0.0,
0.0,
20.0
],
"end": [
40.0,
0.0,
20.0
],
"point": [
20.0,
0.0,
20.0
]
}
]
}
]
}
@@ -0,0 +1,25 @@
{
"source": "analytic",
"method": "plate (top 20 -> 2 wide over x 0..40, 15 high) with its top front edge filleted at 3, fit: taper. The radius is the taper law: a clamped cubic B-spline in u = x/40 on 8 equal spans, control radii min(3, 0.9 room) at the Greville abscissae, room = min(20 - 18u, 15) tan 45 deg (top face width, front face height): 3.0000, 3.0000, 3.0000, 3.0000, 3.0000, 3.0000, 3.0000, 3.0000, 3.0000, 2.4750, 1.8000. Sections are quarter rounds; V, moments and areas integrated along the edge",
"body_count": 1,
"volume_mm3": 6525.960225143974,
"area_mm2": 2415.0715445174765,
"center_of_mass": [
14.492429126634498,
6.796108235394649,
7.422397574623911
],
"bbox": {
"min": [
0.0,
0.0,
0.0
],
"max": [
40.0,
20.0,
15.0
]
},
"faces": 7
}
@@ -0,0 +1,180 @@
{
"id": "80-fillet-taper-to-fit",
"name": "Fillet tapered to the room along its edge",
"description": "Plate whose top narrows from 20 mm (x = 0) to 2 mm (x = 40), 15 high; its top front edge filleted at 3 mm with fit: taper, the radius following the room where 3 doesn't fit.",
"exercises": [
"extrude",
"fillet",
"fit taper"
],
"units": {
"length": "mm",
"angle": "deg",
"area": "mm2",
"volume": "mm3"
},
"conventions": {
"world": "right-handed; Z up. XY/XZ/YZ are the origin planes.",
"sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.",
"point_refs": "'<id>.start' / '<id>.end' / '<id>.center' reuse (share) that existing sketch point; 'at' is its position when referenced.",
"extrude_direction": "positive = along sketch plane normal unless stated",
"selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it."
},
"parameters": [],
"features": [
{
"op": "sketch",
"name": "Extrude1_sketch",
"plane": {
"ref": "XY",
"origin": [
0.0,
0.0,
0.0
],
"x_dir": [
1.0,
0.0,
0.0
],
"y_dir": [
0.0,
1.0,
0.0
],
"normal": [
0.0,
0.0,
1.0
]
},
"entities": [
{
"type": "line",
"start": {
"at": [
0,
0
]
},
"end": {
"at": [
40,
0
]
},
"id": "l1"
},
{
"type": "line",
"start": {
"ref": "l1.end",
"at": [
40.0,
0.0
]
},
"end": {
"at": [
40,
2
]
},
"id": "l2"
},
{
"type": "line",
"start": {
"ref": "l2.end",
"at": [
40.0,
2.0
]
},
"end": {
"at": [
0,
20
]
},
"id": "l3"
},
{
"type": "line",
"start": {
"ref": "l3.end",
"at": [
0.0,
20.0
]
},
"end": {
"ref": "l1.start",
"at": [
0.0,
0.0
]
},
"id": "l4"
}
],
"constraints": [],
"dimensions": []
},
{
"op": "extrude",
"name": "Extrude1",
"operation": "new",
"profiles": [
{
"sketch": "Extrude1_sketch",
"loops": [
{
"outer": true,
"curves": [
"l1",
"l2",
"l3",
"l4"
]
}
]
}
],
"extent": {
"type": "distance",
"distance": 15,
"direction": "positive"
},
"result_bodies": [
"Part"
]
},
{
"op": "fillet",
"name": "Fillet1",
"radius": 3.0,
"fit": "taper",
"edges": [
{
"type": "line",
"start": [
0.0,
0.0,
15.0
],
"end": [
40.0,
0.0,
15.0
],
"point": [
20.0,
0.0,
15.0
]
}
]
}
]
}