Developable Surfaces
Developability Invariant:
κ_1 = 0, κ_2 ≠ 0). 2. Straight Ruling Lines: Ruled surface where the tangent plane is constant along each generator line. 3. Sheet Metal & Plywood: Enables rapid fabrication using standard 2D flat-bed CNC routing.1import numpy as np23def unroll_developable_strip(strip_triangles):4 """5 Isometrically unfolds a 3D developable triangle strip onto the 2D XY plane6 by rotating each successive triangle around its shared ruling edge via Rodrigues' formula.7 """8 def rodrigues_rotate(vec, axis, angle):9 axis = axis / np.linalg.norm(axis)10 return (vec * np.cos(angle) +11 np.cross(axis, vec) * np.sin(angle) +12 axis * np.dot(axis, vec) * (1.0 - np.cos(angle)))1314 unrolled = [np.asarray(strip_triangles[0], dtype=float)]15 for k in range(1, len(strip_triangles)):16 prev_tri = unrolled[-1]17 curr_tri = np.asarray(strip_triangles[k], dtype=float)18 # Shared ruling edge between (prev_tri[1], prev_tri[2]) and (curr_tri[0], curr_tri[1])19 n_prev = np.cross(prev_tri[1] - prev_tri[0], prev_tri[2] - prev_tri[0])20 n_curr = np.cross(curr_tri[1] - curr_tri[0], curr_tri[2] - curr_tri[0])21 n_prev /= np.linalg.norm(n_prev)22 n_curr /= np.linalg.norm(n_curr)23 hinge_axis = prev_tri[2] - prev_tri[1]24 dihedral = np.arctan2(np.dot(np.cross(n_curr, n_prev), hinge_axis / np.linalg.norm(hinge_axis)),25 np.dot(n_curr, n_prev))26 tip_vec = rodrigues_rotate(curr_tri[2] - curr_tri[0], hinge_axis, dihedral)27 unrolled.append(np.array([prev_tri[1], prev_tri[2], prev_tri[1] + tip_vec]))28 return unrolled
Developable Surfaces (Isometric 2D Unfolding): Curved sheets of plywood, aluminum, and steel cannot stretch like rubber; they can only bend along single-curvature rulings. By Gauss's Theorema Egregium, a surface can be flattened onto a 2D plane without in-plane membrane stretching or shear deformation if and only if its Gaussian curvature is identically zero (K = 0).
Geodesic Invariant for Timber:
1import numpy as np23def compute_geodesic_curvature(curve_points, surface_normals):4 """5 Computes discrete geodesic curvature kappa_g along a surface curve.6 Decomposes curve acceleration into normal curvature kappa_n (along N)7 and geodesic curvature kappa_g (along tangent binormal B_g = N x T).8 A timber lamella is geodesic iff kappa_g == 0 everywhere.9 """10 pts = np.asarray(curve_points, dtype=float)11 normals = np.asarray(surface_normals, dtype=float)12 kappa_g = np.zeros(len(pts) - 2)1314 for i in range(1, len(pts) - 1):15 e_prev = pts[i] - pts[i - 1]16 e_next = pts[i + 1] - pts[i]17 ds = 0.5 * (np.linalg.norm(e_prev) + np.linalg.norm(e_next))18 t_prev = e_prev / np.linalg.norm(e_prev)19 t_next = e_next / np.linalg.norm(e_next)2021 # Discrete curvature vector k * N_curve = dT / ds22 curvature_vec = (t_next - t_prev) / max(ds, 1e-8)23 tangent = (t_prev + t_next) / np.linalg.norm(t_prev + t_next)24 surf_normal = normals[i] / np.linalg.norm(normals[i])25 tangent_normal = np.cross(surf_normal, tangent)26 kappa_g[i - 1] = np.dot(curvature_vec, tangent_normal)27 return kappa_g
Bending-Active Geodesic Lamellas: Flat, straight timber planks cannot be bent across their wide edge without splintering or requiring costly steam-bending jigs. However, they easily bend perpendicular to their thin axis. On arbitrary double-curved surfaces, curves with zero geodesic curvature (κ_g = 0) are geodesics. Planks routed perfectly straight in 2D can be cold-bent along geodesic paths with zero in-plane strain.
Related Concepts
Planar quad meshes, conical offsets, developable unrolling, and geodesic grids.
CNC cutter radius compensation, corner relief, and 2D irregular nesting.
Interactive geometrical visualization of No-Fit Polygons and Bottom-Left-Fill sheet packing.