Create a Convex Hull in Three.js with ConvexGeometry

This article provides a step-by-step guide on how to use ConvexGeometry in Three.js to generate a 3D convex hull around a set of random points. You will learn how to import the necessary utility module, define your coordinates, generate the geometry, and display the resulting mesh in your 3D scene.

1. Import ConvexGeometry

The ConvexGeometry class is not included in the core Three.js bundle. You must import it separately from the addons folder. Ensure you are using a module bundler or an import map to resolve the path correctly.

import * as THREE from 'three';
import { ConvexGeometry } from 'three/addons/geometries/ConvexGeometry.js';

2. Generate a Set of Points

To create a convex hull, you need an array of THREE.Vector3 points. These points represent the outer boundaries that the convex hull will wrap around.

const points = [];

// Generate 30 random points within a 10x10x10 space
for (let i = 0; i < 30; i++) {
    const x = (Math.random() - 0.5) * 10;
    const y = (Math.random() - 0.5) * 10;
    const z = (Math.random() - 0.5) * 10;
    
    points.push(new THREE.Vector3(x, y, z));
}

3. Create the Convex Geometry

Pass the array of Vector3 points directly into the ConvexGeometry constructor. Under the hood, Three.js uses the QuickHull algorithm to calculate the outermost faces that enclose all the provided points.

const convexGeometry = new ConvexGeometry(points);

4. Create and Add the Mesh to the Scene

With the geometry generated, define a material and combine them into a THREE.Mesh. Adding a wireframe material or a semi-transparent material helps visualize the structure of the hull.

// Define a material
const material = new THREE.MeshBasicMaterial({ 
    color: 0x00ff00, 
    wireframe: true 
});

// Create the mesh
const convexHullMesh = new THREE.Mesh(convexGeometry, material);

// Add to your Three.js scene
scene.add(convexHullMesh);

Optional: Visualizing the Original Points

To see how the convex hull wraps the points, you can render the original points alongside the hull using THREE.Points.

const pointsGeometry = new THREE.BufferGeometry().setFromPoints(points);
const pointsMaterial = new THREE.PointsMaterial({ color: 0xff0000, size: 0.5 });
const pointCloud = new THREE.Points(pointsGeometry, pointsMaterial);

scene.add(pointCloud);