Find Closest Point on a Line Segment in Three.js
In 3D computer graphics, finding the nearest point on a line segment
to an arbitrary point in space is a common task used for collision
detection, pathfinding, and user interactions. The Three.js library
simplifies this mathematical challenge through its utility class,
Line3. This article explains how to utilize the
Line3 class, specifically its
closestPointToPoint method, to efficiently calculate this
closest point on a line segment with minimal code.
The Line3 class represents a 3D line segment defined by
a start point and an end point, both of which are Vector3
instances. Rather than manually calculating vector projections and dot
products, developers can leverage Line3’s built-in methods
to handle the geometry.
How the closestPointToPoint Method Works
The primary method used for this calculation is
closestPointToPoint(point, clampToLine, target). It takes
three arguments:
point(Vector3): The external point in 3D space from which you want to find the closest point on the line segment.clampToLine(Boolean):- If set to
true, the returned point is guaranteed to lie strictly on the segment between the start and end points. If the closest mathematical projection falls outside the segment, the method returns the nearest endpoint (start or end). - If set to
false, the method treats the segment as an infinite line extending in both directions and returns the projection of the point along that infinite line.
- If set to
target(Vector3): The vector where the resulting coordinates will be written. Passing a target vector avoids creating new object instances in memory, which is crucial for maintaining high performance in real-time rendering loops.
Code Example
Here is a practical example demonstrating how to set up a line segment and find the closest point to a target coordinate:
import * as THREE from 'three';
// 1. Define the start and end points of the line segment
const start = new THREE.Vector3(0, 0, 0);
const end = new THREE.Vector3(10, 0, 0);
// 2. Instantiate the Line3 object
const lineSegment = new THREE.Line3(start, end);
// 3. Define the external point in space
const externalPoint = new THREE.Vector3(5, 5, 0);
// 4. Create a target vector to store the result
const result = new THREE.Vector3();
// 5. Calculate the closest point, clamping it to the segment
lineSegment.closestPointToPoint(externalPoint, true, result);
console.log(result); // Output: Vector3 { x: 5, y: 0, z: 0 }In this example, the external point is directly above the midpoint of
the line segment. The closestPointToPoint method drops a
perpendicular line to the segment, accurately identifying
(5, 0, 0) as the closest point.
Underlying Mathematics
Under the hood, Line3 projects the vector pointing from
the start of the line to the external point onto the line segment’s
direction vector. By calculating the dot product, Three.js determines a
scalar projection value, \(t\). - When
clampToLine is true, this \(t\) value is clamped between 0
(the start point) and 1 (the end point). - The final
coordinates are calculated by interpolating along the line segment using
this clamped \(t\) value.
By encapsulating this linear algebra, the Line3 class
provides an optimized, readable, and error-free way to perform spatial
queries in Three.js applications.