SDF Transformations & Curves
Deformation Operators:
f(T^-1(p)). Query point is shifted/rotated opposite to the desired movement. 2. Infinite Repetition: Spatial domain folding using a modulo operator mod(p, s) - 0.5s. 3. Twist / Bend: Varying the rotation angle dynamically as a function of the query point's coordinate (e.g. height y).1# Modifiers work by transforming the query point 'p' in reverse2def op_translate(p, offset):3 return p - offset45def op_repeat(p, size):6 # Map p to local repeated cell7 return Vector3(8 (p.x % size) - 0.5 * size,9 p.y,10 (p.z % size) - 0.5 * size11 )1213def op_twist(p, k):14 # Twist angle proportional to height (y)15 angle = p.y * k16 c, s = cos(angle), sin(angle)17 rx = p.x * c - p.z * s18 rz = p.x * s + p.z * c19 return Vector3(rx, p.y, rz)
Unlike boundary meshes, SDFs are transformed by applying the inverse transform to the query point p before evaluating the distance function. This lets us bend, twist, or duplicate geometry infinitely with zero memory overhead.
Projection Mathematics:
p onto the infinite line of the segment, then clamp to the boundaries [0, 1]. 2. Bezier Closest Point: The vector from the closest point on the Bezier curve B(t) to p must be orthogonal to the tangent vector B'(t), yielding dot(B(t) - p, B'(t)) = 0.1def sd_segment(p, a, b):2 pa = p - a3 ba = b - a4 # Clamped projection factor5 t = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0)6 return length(pa - ba * t)78def sd_quadratic_bezier(p, a, b, c, steps=16):9 # Find parameter t in [0, 1] minimizing dist(p, B(t))10 # where B(t) = (1-t)^2*a + 2(1-t)*t*b + t^2*c11 best_t = 0.012 min_dist = float('inf')13 for i in range(steps + 1):14 t = i / steps15 bt = (1.0 - t)**2 * a + 2.0 * (1.0 - t) * t * b + t**2 * c16 d = length(p - bt)17 if d < min_dist:18 min_dist, best_t = d, t1920 # Refine root of dot(B(t) - p, B'(t)) = 0 via Newton-Raphson21 t = best_t22 for _ in range(4):23 bt = (1.0 - t)**2 * a + 2.0 * (1.0 - t) * t * b + t**2 * c24 d1 = 2.0 * (1.0 - t) * (b - a) + 2.0 * t * (c - b)25 d2 = 2.0 * (c - 2.0 * b + a)26 denom = dot(d1, d1) + dot(bt - p, d2)27 if abs(denom) > 1e-8:28 t = clamp(t - dot(bt - p, d1) / denom, 0.0, 1.0)2930 closest_pt = (1.0 - t)**2 * a + 2.0 * (1.0 - t) * t * b + t**2 * c31 return length(p - closest_pt)
Calculating distances to curves is essential for outline rendering and wireframe effects. A line segment has a straightforward projection calculation. A quadratic Bezier curve is more complex, requiring us to solve a cubic equation to find the closest point.
Related Concepts
Binary Space Partitioning, polygon slicing, and CSG boundary classification rules.
Implicit geometry and mathematical shapes.
Analytical SDF primitives, domain transformations, finite-difference gradients, and closest-point projection.