Part IV: Applied Math & Engineering
Applied Math & Engineering with OpenSCAD
A 3D printer becomes a math and engineering lab when paired with a code-based modeler. OpenSCAD turns geometry into programming — every shape is an equation, every position is a vector.
Install
sudo pacman -S openscad
Working with OpenSCAD
GUI Mode — Interactive Learning
# Open a .scad file in the GUI (code left, 3D preview right)
openscad ~/3dprints/scad/quijote.scad
-
Edit code on the left panel
-
F5 — quick preview (fast, approximate)
-
F6 — full render (slow, exact — required before export)
-
Ctrl+Shift+E — export STL from GUI
Change a number, hit F5, see the result instantly. That’s the learning loop.
Terminal Mode — Render and Validate
# Render .scad to .stl from command line (no GUI)
openscad -o output.stl source.scad
# Render + validate Z min in one pipeline
openscad -o model.stl source.scad && python3 -c "
with open('model.stl','r') as f:
zvals=[float(l.strip().split()[-1]) for l in f if 'vertex' in l]
print(f'Z min: {min(zvals):.3f} Z max: {max(zvals):.3f}')
print('BED OK' if min(zvals) >= 0 else 'ERROR: model below bed')
"
Edit with Your Text Editor
OpenSCAD files are plain text. Edit with nvim or any editor, then render from terminal:
nvim ~/3dprints/scad/quijote.scad
openscad -o ~/3dprints/quijote/quijote.stl ~/3dprints/scad/quijote.scad
Full Pipeline: Code → STL → G-code → Print
# 1. Edit the .scad file
nvim source.scad
# 2. Render to STL
openscad -o model.stl source.scad
# 3. Validate
python3 -c "
with open('model.stl','r') as f:
zvals=[float(l.strip().split()[-1]) for l in f if 'vertex' in l]
print(f'Z min: {min(zvals):.3f} Z max: {max(zvals):.3f}')
"
# 4. Load in OrcaSlicer → Slice plate → Export G-code
# 5. Print via pronsole
pronsole.py
# > connect /dev/ender3v3se 115200
# > settemp 210
# > load /full/path/to/model.gcode
# > print
# > monitor
Why OpenSCAD (Not a GUI Modeler)
-
Every operation maps to a math concept — no hiding behind click-and-drag
-
Scripts are reproducible, versionable, and teachable
-
Parametric design teaches variables and functions before "programming" ever comes up
-
The jump from OpenSCAD to Python/NumPy is almost trivial — the mental model transfers
The Math You’re Actually Doing
| OpenSCAD Operation | Math Concept | Grade Level |
|---|---|---|
|
Vector addition / translation matrix |
Middle school |
|
Rotation matrices, trigonometry |
High school |
|
Scalar multiplication, linear transforms |
Middle school |
|
Convex hull — computational geometry |
College intro |
|
Boolean set operations (union, intersection, complement) |
Middle school |
|
Polar coordinates, parametric curves |
High school |
|
Trigonometric functions — unit circle |
High school |
Nesting |
Matrix multiplication, transform composition |
Linear algebra |
Starter Projects by Skill Level
Beginner — Geometric Solids
Print the five Platonic solids. Measure faces, edges, vertices. Verify Euler’s formula: V - E + F = 2.
// Geometric Solids — Platonic solid exploration
// Print these, count faces/edges/vertices, verify Euler's formula: V - E + F = 2
// Cube — 6 faces, 8 vertices, 12 edges
cube([20, 20, 20], center=true);
// Sphere approximated by polyhedron
translate([40, 0, 0])
sphere(r=15, $fn=64);
// Cylinder — introduce pi, circumference, area
translate([80, 0, 0])
cylinder(h=30, r=10, $fn=6); // hexagonal prism
translate([120, 0, 0])
cylinder(h=30, r=10, $fn=64); // smooth cylinder
The $fn parameter directly teaches polygon approximation of curves — how a circle is really just a polygon with enough sides.
Intermediate — Parametric Comb
A functional comb — pure geometry, immediately useful:
// Parametric Comb — change variables, everything adapts
// Print on side, 100% infill. PETG for daily use, PLA for prototyping.
teeth = 30;
tooth_width = 1.2;
tooth_height = 25;
tooth_gap = 1.5;
base_height = 8;
base_depth = 4;
// Base bar
cube([teeth * (tooth_width + tooth_gap), base_depth, base_height]);
// Teeth — each one is a for-loop iteration
for (i = [0:teeth-1])
translate([i * (tooth_width + tooth_gap), 0, base_height])
cube([tooth_width, base_depth, tooth_height]);
Change one variable, the whole comb adapts. Print at 100% infill. PETG for durability, PLA for prototyping.
Intermediate — Metric Ruler
A precision measuring tool that validates your printer’s dimensional accuracy:
// Metric Ruler — precision test for your printer
// Print at 100% infill, 0.12mm layer height for sharp tick marks.
// Measure against a real ruler to validate dimensional accuracy.
length = 200; // mm
width = 25;
height = 2;
difference() {
cube([length, width, height]);
// Centimeter marks — tall
for (i = [0:10:length])
translate([i, 0, height-1.5])
cube([0.4, 8, 1.5]);
// Half-centimeter marks — medium
for (i = [5:10:length])
translate([i, 0, height-1.0])
cube([0.3, 5, 1.0]);
// Millimeter marks — short
for (i = [1:1:length])
if (i % 5 != 0)
translate([i, 0, height-0.6])
cube([0.2, 3, 0.6]);
// Numbers at each centimeter
for (i = [1:length/10])
translate([i*10-2, 10, height-0.5])
linear_extrude(height=0.5)
text(str(i), size=5, font="Liberation Sans");
}
Print it, measure it against a real ruler. The difference is your printer’s dimensional error.
Intermediate — Parametric Box with Lid
One variable changes everything:
// Parametric Box with Lid — change one variable, everything adapts
// Teaches: variables, expressions, spatial reasoning, tolerance
box_width = 40;
box_depth = 30;
box_height = 25;
wall = 2;
clearance = 0.3; // lid clearance — why does this matter?
// Box
difference() {
cube([box_width, box_depth, box_height]);
translate([wall, wall, wall])
cube([box_width - 2*wall,
box_depth - 2*wall,
box_height - wall]);
}
// Lid — offset for printing, includes clearance
translate([box_width + 10, 0, 0])
cube([box_width + clearance, box_depth + clearance, wall]);
This teaches: variables, expressions, spatial reasoning, tolerance (the lid needs clearance — why?).
Advanced — Gears and Trigonometry
// Involute Gear — every tooth position is sin/cos
// Print two with different tooth counts, mesh them, demonstrate gear ratios
module gear(teeth=20, pitch_radius=20, height=5) {
tooth_angle = 360 / teeth;
difference() {
cylinder(h=height, r=pitch_radius + 2, $fn=teeth*4);
for (i = [0:teeth-1]) {
rotate([0, 0, i * tooth_angle + tooth_angle/4])
translate([pitch_radius, 0, -1])
cylinder(h=height+2, r=pitch_radius * sin(tooth_angle/4), $fn=16);
}
}
// Center axle hole
difference() {
cylinder(h=height, r=pitch_radius + 2, $fn=teeth*4);
translate([0, 0, -1])
cylinder(h=height+2, r=3, $fn=32);
}
}
// 24-tooth gear
gear(teeth=24, pitch_radius=25, height=8);
// 12-tooth gear — 2:1 ratio
translate([55, 0, 0])
gear(teeth=12, pitch_radius=12.5, height=8);
Print two meshing gears. Physically demonstrate gear ratios — the math becomes something you can hold and turn.
Advanced — Display Dagger
hull() tapering a diamond cross-section to a point:
// Display Dagger — hull() tapering a diamond cross-section to a point
// Teaches: cross-sections, tapering, symmetry, Boolean operations
module dagger() {
// Blade — tapered diamond cross-section
hull() {
scale([1, 0.3, 1]) cylinder(h=1, r=8, $fn=4);
translate([0, 0, 100])
scale([1, 0.3, 1]) cylinder(h=1, r=0.5, $fn=4);
}
// Guard — cross piece
translate([0, 0, -2])
cube([40, 4, 4], center=true);
// Handle — octagonal for grip
translate([0, 0, -35])
cylinder(h=33, r=5, $fn=8);
// Pommel
translate([0, 0, -38])
sphere(r=6, $fn=32);
}
dagger();
Engineering — Load Testing
-
Design a bridge in OpenSCAD (parametric: span, thickness, truss pattern)
-
Print three variants with different infill (15%, 50%, 100%)
-
Load-test each with weights until failure
-
Record and graph: weight vs. deflection vs. material used
-
Iterate the design — this is the actual engineering method
Teaching Workflow
1. Pose a problem → "Design a phone stand for this specific phone" 2. Sketch on paper → dimensions, angles, constraints 3. Code in OpenSCAD → translate the sketch to transforms and primitives 4. Slice in OrcaSlicer → learn about layer height, infill, supports 5. Print → confront reality (tolerance, bridging, warping) 6. Measure and compare → calipers vs. design intent 7. Iterate → the gap between design and reality IS engineering
Every cycle through this loop reinforces: spatial reasoning, trigonometry, algebra, precision, and the scientific method. The printer makes the feedback loop physical and immediate — a wrong calculation isn’t a red X on a test, it’s a part that doesn’t fit.