11

I am trying to move an object along a path in Three.js. I'd like to build the path in a 'constructed' way, using the Path object like this:

var path = new THREE.Path([
    new THREE.Vector2(0, 0),
    new THREE.Vector2(0, inDistance)
]);

path.arc(arcRadius, 0, arcRadius,
    Geo.rad(180), Geo.rad(90), true);

path.lineTo(arcRadius + outDistance, arcRadius + inDistance);

Then I could use path.getPoint(t) and path.getTangent(t) to get an updated position for my object:

    let position = path.getPoint(percentTraveled);
    let tangent = path.getTangent(percentTraveled);

    state.model.position.x = position.x;
    state.model.position.y = position.y;

There are two problems with this:

  • Path is only 2D
  • The Path object can't be translated to the location and orientation of the object, so the positions / and tangents returned are absolute positions.

I've read this question, which discusses how to use a SplineCurve3 to move along a path, but this solution doesn't explain how to build a spline constructed from a set of lines and arcs.

How do you do that?

Community
  • 1
  • 1
JBCP
  • 13,109
  • 9
  • 73
  • 111
  • Was my answer not solving your issue? Is something missing? – Wilt Feb 25 '16 at 16:26
  • Sorry, the second answer is what I needed I think, buy I haven't had a chance to apply it yet. It's on my queue and I'll accept the answer once I've verified it makes sense to me! – JBCP Feb 25 '16 at 17:11

1 Answers1

18

For a straight movement I think all you need is a direction and a speed and then you can use that as a transformation ( in a matrix or to apply your objects position). The advantage is that you can easily change both the direction and the speed in this process independently.

// direction vector for movement
var direction = new THREE.Vector3( 1, 0, 0 );

// scalar to simulate speed
var speed = 0.5;

var vector = direction.multiplyScalar( speed, speed, speed );
object.x += vector.x;
object.y += vector.y;
object.z += vector.z;

Here is a fiddle to demonstrate this and to fool around with...


For a more fancy movement like following a path you can do as you proposed. A problem that you might have ran into is the fact that paths and shapes are always defined in 2D. So to be able to use vectors in your calculations you should always make them to 3D vectors (simply set z = 0). To make the movement relative you should calculate the differences. The easiest way to do this is to keep track of the previous position and previous angle and use the delta x and delta y for the translation and delta angle for rotation.

deltaX = point.x - previousPoint.x;
deltaY = point.y - previousPoint.y;
deltaAngle = angle - previousAngle;

Here a working fiddle for something you were after.

I made one box move on the absolute path the other moves relatively

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • @user3112634 Thanks for the notice. There were some breaking changes in latest library, I updated both fiddles, so now they should be fine again... – Wilt May 20 '21 at 19:21
  • No problem, here's a pen with a model and path: https://codepen.io/uiunicorn/pen/abJJKqw – user3112634 May 23 '21 at 13:47
  • Are you able to get this working on all 3 axis by any chance? say the curve has highs and lows like a rollercoaster – heroicsatsuma Jun 09 '21 at 13:37
  • @heroicsatsuma Maybe checkout [this example](https://observablehq.com/@rveciana/three-js-object-moving-object-along-path). – Wilt Jun 09 '21 at 18:35