Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get position of point on curve

Tags:

three.js

I have a CatmullRomCurve3 created from an array of Vector3 points.

const curve = new THREE.CatmullRomCurve3(points);

I would like to know the position of those same points on the curve (in a range from 0 to 1). Basically the inverse of .getPointAt() where the first point would be at 0, the last at 1.

I would like to do this in order to subdivide the curve in an equal number of segments between each of the points that I used to create the curve. So for example getting 10 subdivisions between point 0 and point 1, 10 between point 1 and point 2, and so on.

like image 892
Marcoq Avatar asked Oct 12 '25 18:10

Marcoq


1 Answers

I'm sure there's a mathematical approach to your question, but a simple workaround would be to:

  1. Create the original curve with an array or Vector3s.
  2. Create a duplicate curve with the same array, that stops at the Vector3 that you're searching for.
  3. Take the length of the second curve, divide by length of original curve, and you'll get your [0, 1] position.

In code:

// Create original curve
var curve = new THREE.CatmullRomCurve3( [
    new THREE.Vector3( -10, 0, 10 ),
    new THREE.Vector3( -5, 5, 5 ),
    new THREE.Vector3( 0, 0, 0 ),
    new THREE.Vector3( 5, -5, 5 ),
    new THREE.Vector3( 50, 0, 50 )
], false );

var searchPoint = new THREE.Vector3( 5, -5, 5 ); // Point we're looking for
var searchArray = [];   // Array for second curve
var uPosition = null; // Result is null for now

// Loop through curve.points to find our final point
for(var i = 0; i < curve.points.length; i++){
    searchArray.push(curve.points[i]);

    // Exit loop once point has been found
    if(searchPoint.equals(curve.points[i])){
        // Create shorter curve that stops at desired point
        var curve2 = new THREE.CatmullRomCurve3(searchArray);

        // Result is short length / original length
        uPosition = curve2.getLength() / curve.getLength();
        break;
    }
}

// Result is null if position not found
console.log(uPosition);