Three.js Cylindrical Coordinate System Guide

This article provides an overview of the Cylindrical coordinate system class in Three.js, explaining its mathematical foundation, key parameters, and practical use cases. You will learn how to instantiate this class, convert coordinates between Cartesian and cylindrical systems, and apply it to position objects dynamically in 3D space.

Understanding Cylindrical Coordinates

In 3D computer graphics, positions are typically represented using Cartesian coordinates \((x, y, z)\). However, some geometric layouts—such as towers, carousels, spirals, and orbits—are much easier to define using cylindrical coordinates.

The cylindrical coordinate system defines a point in 3D space using three values: * Radius (r): The radial distance from the origin (specifically, the distance from the central vertical Y-axis in the XZ plane). * Theta (\(\theta\)): The counterclockwise angle in radians around the Y-axis, starting from the positive Z-axis. * Y: The height along the vertical Y-axis (equivalent to the Cartesian \(y\)).

The THREE.Cylindrical Class

Three.js provides the THREE.Cylindrical class as a utility to represent these coordinates and easily convert them to and from standard THREE.Vector3 Cartesian coordinates.

Constructor

You can instantiate a cylindrical coordinate object with the following syntax:

const cylindrical = new THREE.Cylindrical(radius, theta, y);

Key Methods

Converting to Cartesian (Vector3)

Since Three.js objects (like meshes and cameras) position themselves using Cartesian coordinates, you must convert cylindrical coordinates to a Vector3 to apply them to your scene.

To do this, use the setFromCylindrical method available on THREE.Vector3:

import * as THREE from 'three';

// Create a cylindrical coordinate (Radius: 5, Angle: 45 degrees in radians, Height: 2)
const radius = 5;
const theta = Math.PI / 4; // 45 degrees
const y = 2;
const cylindrical = new THREE.Cylindrical(radius, theta, y);

// Convert to Cartesian Vector3
const position = new THREE.Vector3();
position.setFromCylindrical(cylindrical);

// Apply to a 3D object mesh
myMesh.position.copy(position);

Practical Use Cases in Three.js

1. Placing Objects in a Circle

If you need to arrange objects (like columns, trees, or lights) in a perfect circle, using cylindrical coordinates simplifies the math. You keep the radius and height constant while incrementing the theta angle:

const radius = 10;
const height = 0;
const totalObjects = 12;

for (let i = 0; i < totalObjects; i++) {
    const theta = (i / totalObjects) * Math.PI * 2;
    const cyl = new THREE.Cylindrical(radius, theta, height);
    
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.setFromCylindrical(cyl);
    scene.add(mesh);
}

2. Creating Spirals and Helices

To generate spiral paths (such as a spiral staircase, DNA strand, or particle vortex), you can continuously increase both the height (y) and the angle (theta):

const radius = 3;
const totalPoints = 100;

for (let i = 0; i < totalPoints; i++) {
    const theta = i * 0.2; // Continuous rotation
    const y = i * 0.1;     // Continuous rise
    const cyl = new THREE.Cylindrical(radius, theta, y);
    
    const point = new THREE.Vector3().setFromCylindrical(cyl);
    // Use the point to position a particle or add to a line path
}

3. Camera Orbit Control

Cylindrical coordinates are highly useful for custom camera systems where you want the camera to revolve around a central target at a fixed height and distance. By updating the theta value of a cylindrical coordinate over time, you can achieve smooth circular panning.