Linear Interpolation of 2 Vector3 by unit of distance rather than factor in THREE.js

Viewed 455

Apologies for any wording and incorrect references, 3 dimensional maths is new to me!

Problem:

  • I have two points in 3D space A: (1,2,3) and B: (6,5,4)
  • I have a distance L: 10
  • What is the 3D point C as defined as A TOWARDS B at a UNIT of L?

Notes:

  • Distance of L is not a factor of the distance between A or B, there .lerp() is not the right tool here
  • L can be both greater and smaller than the distance between A and B.

I'm using THREE.js, but any language examples are welcome!

Workings so far:

  • Calculate distance between A & B -> D
  • Get factor of D in relation to our target value L -> R
  • Apply .lerp() with A towards B with factor R
function lerpUnit (x1,y1,z1,x2,y2,z3,distance) {
   ... ???
   return {x3,y3,z3}
}

2 Answers

You could achieve this with just the methods provided by THREE.Vector3()

  • First you could subtract vecB - vecA to get a parallel vector that originates at (0, 0, 0).
  • Second, use normalize() to turn this vector into a "unit vector", which means no matter which way it's pointing, its length will always be 1.
  • Third, multiply the vector by L, so length = 1 * L
  • Lastly, move this new parallel vector back to its initial position with + vecA to get the final position. It will land somewhere inside or beyond the line segment created by A and B

var vecA = new THREE.Vector3(1, 2, 3);
var vecB = new THREE.Vector3(6, 5, 4);
var L = 10;

// Create new vector
var direction = new THREE.Vector3();

// Assign positionB
direction.copy(vecB);

// Subtract positionA to get a vector starting at (0, 0, 0)
direction.sub(vecA);

// Normalize to get a vector of lengh = 1
direction.normalize();

// Multiply by new length
direction.multiplyScalar(L);

// Add positionA to return vector to initial start point
direction.add(vecA);

// Output to log to see result
console.log(direction.toArray());
<script src="https://cdn.jsdelivr.net/npm/three@0.117.1/build/three.min.js"></script>

Thanks, I just expanded on by workings far by using .lerp() but passing in a ratio's value, eg:

function lerpUnit (vectorA, vectorB, intendedDistance ) {
   const aToBDistance = vectorA.distanceTo(vectorB)
   const adjustedFactor = intendedDistance / aToBDistance
   return new THREE.Vector3().lerpVectors(vectorA, vectorB, adjustedFactor)
}

or 1 liner: const vectorC = new THREE.Vector3().lerpVectors(vectorA, vectorB, intendedDistance / vectorA.distanceTo(vectorB))

Related