Initializing 3D Canvas...

Network Surfaces

2 min read1 page

A Network Surface (specifically a Coons Patch) generates a smooth surface bridging the gap between four intersecting boundary curves. The fundamental requirement is that the curves must meet at four distinct corner points.

Boundary Setup:

1. Define 2 curves for the U direction (bottom and top edges). 2. Define 2 curves for the V direction (left and right edges). 3. Ensure the endpoints of adjacent curves touch perfectly.
python
1# Defining 4 Boundary Curves
2# A Coons Patch requires 4 curves that share endpoints.
3
4def define_network_boundaries():
5 # Curve 0 (Bottom), Curve 1 (Top)
6 c0 = NurbsCurve(start=P(0,0,0), end=P(1,0,0))
7 c1 = NurbsCurve(start=P(0,1,0), end=P(1,1,0))
8
9 # Curve 2 (Left), Curve 3 (Right)
10 c2 = NurbsCurve(start=P(0,0,0), end=P(0,1,0))
11 c3 = NurbsCurve(start=P(1,0,0), end=P(1,1,0))
12
13 # Corners must match exactly:
14 # c0.start == c2.start
15 # c0.end == c3.start
16 # c1.start == c2.end
17 # c1.end == c3.end
Curve Warping
1.00
2 min read1 page

The first mathematical component of a Coons Patch is a bilinear interpolation of the 4 corner points. This creates a flat (or ruled) surface that connects the corners, completely ignoring the shape of the boundary curves.

Bilinear Term:

1. Given parameters u and v (both ranging from 0.0 to 1.0). 2. Linearly interpolate between the bottom corners based on u. 3. Linearly interpolate between the top corners based on u. 4. Linearly interpolate between those two results based on v.
python
1# Bilinear Interpolation of Corners
2def bilinear_surface(u, v, p00, p10, p01, p11):
3 """Interpolates a point based on 4 corner vertices."""
4 # Interpolate along bottom edge
5 bottom = p00 * (1 - u) + p10 * u
6 # Interpolate along top edge
7 top = p01 * (1 - u) + p11 * u
8
9 # Interpolate between bottom and top
10 return bottom * (1 - v) + top * v
U Parameter
0.50
V Parameter
0.50
2 min read1 page

The second mathematical component evaluates the shape of the U-direction curves (bottom and top boundaries). For a given parameter u, it finds the exact points on the bottom and top curves, and then draws a straight line (linear interpolation) between them based on v.

Ruled U Surface:

1. Find the point on Curve 0 (bottom) at parameter u. 2. Find the point on Curve 1 (top) at parameter u. 3. Linearly interpolate between those two points by factor v. 4. This creates a "Ruled Surface" that perfectly matches the U curves, but ignores V curves.
python
1# Ruled Surface in U Direction
2def blend_u(u, v, curve_bottom, curve_top):
3 """Interpolates between the U-direction curves."""
4
5 # Evaluate point on bottom curve at parameter u
6 pt_bottom = curve_bottom.evaluate(u)
7
8 # Evaluate point on top curve at parameter u
9 pt_top = curve_top.evaluate(u)
10
11 # Linearly interpolate between them based on v
12 return pt_bottom * (1 - v) + pt_top * v
U Parameter
0.50
V Parameter
0.50
2 min read1 page

The third mathematical component evaluates the shape of the V-direction curves (left and right boundaries). Similar to the U-blend, it finds the exact points on the left and right curves for parameter v, and then draws a straight line between them based on u.

Ruled V Surface:

1. Find the point on Curve 2 (left) at parameter v. 2. Find the point on Curve 3 (right) at parameter v. 3. Linearly interpolate between those two points by factor u. 4. This creates a "Ruled Surface" that perfectly matches the V curves, but ignores U curves.
python
1# Ruled Surface in V Direction
2def blend_v(u, v, curve_left, curve_right):
3 """Interpolates between the V-direction curves."""
4
5 # Evaluate point on left curve at parameter v
6 pt_left = curve_left.evaluate(v)
7
8 # Evaluate point on right curve at parameter v
9 pt_right = curve_right.evaluate(v)
10
11 # Linearly interpolate between them based on u
12 return pt_left * (1 - u) + pt_right * u
U Parameter
0.50
V Parameter
0.50
2 min read1 page

The brilliant insight of the Coons Patch is how it combines the three previous estimations. By adding the U-Ruled surface to the V-Ruled surface, we end up double-counting the corners. Subtracting the Bilinear surface perfectly cancels out this error, resulting in a smooth surface that exactly interpolates all four boundary curves.

Coons Formula:

1. Point = Ruled_U(u,v) + Ruled_V(u,v) - Bilinear(u,v). 2. Matches bottom/top boundaries because at v=0 or v=1, the V-Ruled and Bilinear terms cancel each other out. 3. Matches left/right boundaries because at u=0 or u=1, the U-Ruled and Bilinear terms cancel out.
python
1# Coons Patch Equation
2def evaluate_coons_patch(u, v, c_bottom, c_top, c_left, c_right, corners):
3 """Calculates the final surface point at (u, v)."""
4
5 # Evaluate the U-ruled surface point
6 pt_u = blend_u(u, v, c_bottom, c_top)
7
8 # Evaluate the V-ruled surface point
9 pt_v = blend_v(u, v, c_left, c_right)
10
11 # Evaluate the Bilinear surface point
12 pt_bilinear = bilinear_surface(u, v, *corners)
13
14 # The Coons Patch formula:
15 # Final Point = (Ruled U) + (Ruled V) - (Bilinear)
16 return pt_u + pt_v - pt_bilinear
U Parameter
0.50
V Parameter
0.50
2 min read1 page

To render the mathematical Coons Patch as a 3D object, we must evaluate the formula across a 2D grid of (u, v) parameters, generating a structured array of vertices.

Grid Meshing:

1. Choose a resolution for U and V directions (e.g., 10x10). 2. Loop through u from 0.0 to 1.0, and v from 0.0 to 1.0. 3. Evaluate the Coons patch at each step to get 3D vertices. 4. Connect the grid into triangle pairs for rendering.
python
1# Generating the Surface Grid
2def generate_coons_mesh(c_bottom, c_top, c_left, c_right, u_segs, v_segs):
3 """Evaluates the patch across a grid to build a mesh."""
4 corners = get_corners(c_bottom, c_top, c_left, c_right)
5
6 vertices = []
7
8 # 1. Evaluate points at grid intersections
9 for i in range(v_segs + 1):
10 v = i / v_segs
11 for j in range(u_segs + 1):
12 u = j / u_segs
13
14 pt = evaluate_coons_patch(u, v, c_bottom, c_top, c_left, c_right, corners)
15 vertices.append(pt)
16
17 # 2. Build quad faces connecting the vertices
18 faces = build_grid_topology(u_segs, v_segs)
19
20 return Mesh(vertices, faces)
U Segments
10.00
V Segments
10.00
2 min read1 page

To render the Coons Patch smoothly and react properly to lighting, we need Surface Normals. Instead of calculating mathematically exact derivatives of the Coons equation (which can be expensive), we usually estimate normals directly from the generated mesh geometry.

Smooth Normal Estimation:

1. For each triangle, take two edges and calculate their cross product to find the perpendicular face normal. 2. For each vertex, sum all the face normals of the triangles it is attached to. 3. Normalize the resulting summed vector to a length of 1.0.
python
1# Surface Normals via Cross Products
2def calculate_vertex_normals(mesh):
3 """Calculates smoothed surface normals for rendering."""
4 normals = [Vector(0,0,0) for _ in mesh.vertices]
5
6 # 1. Calculate the face normal for every triangle
7 for face in mesh.faces:
8 v0, v1, v2 = mesh.vertices[face[0]], mesh.vertices[face[1]], mesh.vertices[face[2]]
9
10 # Edge vectors
11 edge1 = v1 - v0
12 edge2 = v2 - v0
13
14 # Face normal via Cross Product
15 face_normal = edge1.cross(edge2)
16
17 # 2. Add face normal to its 3 vertices
18 normals[face[0]] += face_normal
19 normals[face[1]] += face_normal
20 normals[face[2]] += face_normal
21
22 # 3. Normalize to length 1.0
23 for i in range(len(normals)):
24 normals[i].normalize()
25
26 return normals
Show Normal Vectors
1.00
2 min read1 page

Network surfaces are widely used in architecture (for tensile structures or canopy roofs) and in automotive design to smoothly fill complex multi-sided holes between other surfaces.

Dynamic Networks:

1. Because the surface is mathematically defined by its boundaries, updating the curves instantly updates the entire surface. 2. Real-time evaluation is fast enough for interactive tools and animations.
python
1# Interactive Grid Surface
2def update_surface(time):
3 """Animates the boundary curves of the network surface."""
4
5 # Animate control points of the curves based on time
6 c_bottom.control_points[1].z = math.sin(time) * 2.0
7 c_top.control_points[1].z = math.cos(time) * 2.0
8
9 c_left.control_points[1].y = math.sin(time * 0.5) * 2.0
10 c_right.control_points[1].y = math.cos(time * 0.5) * 2.0
11
12 # Re-evaluate Coons Patch mesh
13 return generate_coons_mesh(c_bottom, c_top, c_left, c_right, 20, 20)
Play Animation
1.00
Material (Solid/Wire)
0.00