Initializing 3D Canvas...

The Revolve

2 min read1 page

A Revolve operation (or Lathe) takes a 2D Profile Curve and spins it around a 3D axis. The first step is defining this profile in local coordinates. Usually, the Y-axis acts as the vertical height, and the X-axis acts as the horizontal radius from the center of rotation.

Profile Setup:

1. Define points in a 2D plane (e.g. XY plane). 2. Keep all points on one side of the rotation axis (e.g. X >= 0) to avoid self-intersection. 3. The distance from the axis defines the radius of the resulting shell at that height.
python
1# Defining the Profile Curve for Revolve
2# A revolve operation takes a 2D profile curve and sweeps it in a circle.
3
4def define_revolve_profile():
5 # A list of 2D points (x, y) where x is radius, y is height
6 # Commonly drawn in the positive X half-plane
7 profile = [
8 Point(1.0, 0.0), # Base outer edge
9 Point(1.5, 2.0), # Widest part
10 Point(0.5, 4.0), # Neck
11 Point(0.8, 5.0) # Rim
12 ]
13 return profile
Profile Complexity
6.00
1 min read1 page

To move the 2D profile into 3D, we must define an Axis of Rotation. This is an infinite line in 3D space, defined by an Origin Point and a normalized Direction Vector.

Axis Definition:

1. Specify an Origin point (Ox, Oy, Oz). 2. Specify a Direction vector (Dx, Dy, Dz). 3. Normalize the direction vector so its length is exactly 1.0.
python
1# 3D Axis of Rotation
2class Axis:
3 def __init__(self, origin, direction):
4 self.origin = origin # e.g. Point(0, 0, 0)
5 self.direction = direction # e.g. Vector(0, 1, 0)
6 self.direction.normalize()
7
8# The revolve sweeps the profile around this specific line in 3D space.
Direction X
0.00
Direction Y
1.00
Direction Z
0.00
2 min read1 page

To generate the swept geometry, we must rotate every point of the profile around the axis. Rotating around an arbitrary 3D line requires a combination of translation (moving the axis to the origin), rotation (using Rodrigues' rotation formula or quaternions), and translating back.

Arbitrary Rotation:

1. Subtract Axis Origin from Point. 2. Apply Quaternion or Matrix rotation around Axis Direction. 3. Add Axis Origin back to the Point.
python
1# Rotation Matrix around Arbitrary Axis
2def rotate_around_axis(point, axis_origin, axis_dir, angle_rad):
3 """Rotates a 3D point around an arbitrary 3D line."""
4 import numpy as np
5
6 # 1. Translate point so axis origin is at (0,0,0)
7 p_translated = point - axis_origin
8
9 # 2. Build Rodrigues' rotation formula matrix
10 cos_a = math.cos(angle_rad)
11 sin_a = math.sin(angle_rad)
12 ux, uy, uz = axis_dir.x, axis_dir.y, axis_dir.z
13
14 # (Matrix math omitted for brevity)
15 R = build_rodrigues_matrix(ux, uy, uz, cos_a, sin_a)
16
17 # 3. Rotate translated point
18 p_rotated = np.dot(R, p_translated)
19
20 # 4. Translate back
21 return p_rotated + axis_origin
Rotation Angle
1.57
2 min read1 page

By dividing the total rotation angle (usually 360 degrees) into discrete segments, we repeat the rotation process to generate a grid of vertices in 3D space. Each point on the original profile traces a circular path around the axis.

Vertex Generation:

1. Define number of radial segments (e.g. 16). 2. Calculate angle step = Total Angle / Segments. 3. Loop through segments, rotating the full profile curve at each step. 4. Store the resulting 2D array of vertices: [segment_index][profile_index].
python
1# Sweeping Vertices in Circles
2def generate_revolve_vertices(profile, axis, segments, angle_total=2*math.pi):
3 """Calculates all 3D points for the revolved shell."""
4 all_vertices = []
5
6 # Angle step per segment
7 step = angle_total / segments
8
9 for i in range(segments + 1):
10 current_angle = i * step
11
12 # Rotate the entire profile by current_angle
13 current_profile = []
14 for p in profile:
15 p_rot = rotate_around_axis(p, axis.origin, axis.direction, current_angle)
16 current_profile.append(p_rot)
17
18 all_vertices.append(current_profile)
19
20 return all_vertices
Radial Segments
12.00
Sweep Angle
6.28
2 min read1 page

The grid of vertices generated by the sweep must be connected to form a surface. We iterate through the 2D grid, connecting sets of 4 adjacent points into "Quads", which are then split into two triangles for hardware rendering.

Quad Meshing:

1. Treat vertices as a 2D grid: grid[segment_idx][profile_idx]. 2. Find 4 corners: (i,j), (i,j+1), (i+1,j), (i+1,j+1). 3. Flatten 2D indices to 1D index: idx = i * profile_length + j. 4. Create 2 triangles per quad ensuring consistent counter-clockwise winding.
python
1# Mesh Topology Indexing for Revolve
2def build_revolve_mesh(vertex_grid, num_segments, num_profile_pts):
3 """Connects the vertex grid into a solid mesh surface."""
4 faces = []
5
6 # Iterate through grid cells (quads)
7 for i in range(num_segments):
8 for j in range(num_profile_pts - 1):
9 # Calculate 1D array indices for the 4 corners of the quad
10 current = (i * num_profile_pts) + j
11 next_p = current + 1
12 above = ((i + 1) * num_profile_pts) + j
13 above_n = above + 1
14
15 # Split quad into two triangles (Winding order matters!)
16 faces.append([current, next_p, above_n])
17 faces.append([current, above_n, above])
18
19 return faces
Radial Segments
16.00
Show Wireframe
1.00
3 min read1 page

When a revolve completes a full 360-degree sweep, the last segment touches the first. If we duplicate the vertices at 0° and 360°, lighting engines will treat them as a sharp edge because vertex normals won't average across the gap. We must weld the seam by indexing the last segment directly to the vertices of the first segment.

Seam Welding:

1. Only generate vertices from 0 up to (Segments - 1). 2. When meshing the final segment, wrap the indices back to 0. 3. The rendering engine can now calculate smooth, continuous normals across the seam.
python
1# Seam Welding for Full Revolves
2def weld_revolve_seam(vertices, faces, num_segments, num_profile_pts):
3 """Fuses the last segment back to the first for a seamless 360 shell."""
4
5 # We do NOT generate a new set of vertices for segment N.
6 # Instead, when i == num_segments - 1, we connect to i == 0.
7
8 for i in range(num_segments):
9 for j in range(num_profile_pts - 1):
10 current = (i * num_profile_pts) + j
11 next_p = current + 1
12
13 # If at the last segment, wrap 'above' index back to 0
14 if i == num_segments - 1:
15 above = j
16 else:
17 above = ((i + 1) * num_profile_pts) + j
18
19 above_n = above + 1
20
21 faces.append([current, next_p, above_n])
22 faces.append([current, above_n, above])
23
24 return Mesh(vertices, faces)
Weld Seam
1.00
2 min read1 page

The revolve algorithm is extremely powerful for generating axially symmetric objects like bottles, vases, engine parts, and architectural columns.

Interactive Revolve:

1. A complex 2D profile is generated. 2. The 3D geometry is swept and meshed in real-time. 3. Surface normals are calculated and seams are welded for smooth PBR rendering.
python
1# Revolute Shell Viewer
2def generate_wine_glass():
3 """Example application: Generating a wine glass profile."""
4 profile = [
5 Point(0.8, 0.0), # Base outer
6 Point(0.2, 0.2), # Base inner
7 Point(0.1, 1.5), # Stem
8 Point(0.6, 2.5), # Bowl bottom
9 Point(1.2, 3.5), # Bowl middle
10 Point(1.0, 4.5), # Rim
11 ]
12
13 axis = Axis(Point(0,0,0), Vector(0,1,0))
14 return revolve(profile, axis, segments=32)
Spin Speed
0.50
Glass Material
0.00