Home > Blockchain >  Given a position and rotation, how can I find a point that extends X distance from it?
Given a position and rotation, how can I find a point that extends X distance from it?

Time:02-04

I have a point in 3D space, and that point has an orientation. I want to get the end point of a line X distance from the origin point, following in orientation. How would I do this?

The answer doesn't have to be specific to any library, but I am using Three.JS.

CodePudding user response:

In regards to Three.JS, depending on what you're starting with, or your comfort, there are several solutions.

Object3D

It provides you with extra utility methods that lets Three.js figure out the math for you:

// Create an Object3D
const element = new THREE.Object3D();

// Set position and orientation
element.position.copy(startPosition);
element.rotation.copy(eulerRotations);

// Move "forward" by the desired distance
element.translateZ(distance);

// Now we have our final position!
console.log(element.position);

I think the key to your question is the Object3D.translateZ() method, you can read more about it in the docs.

Vector3

Internally, what Object3D just did was Vector3 math. If you're only dealing with points and orientations, it might make more sense to use Vector3 directly:

const finalPosition = new Vector3(0, 0, 1)
  .applyQuaternion(quaternionRotations)
  .multiplyScalar(distance)
  .add(startPosition);

Math

If you only want the math, this is what Three.JS is doing under the hood:

let x = 0;
let y = 0;
let z = 1;

const ix =   quaternionW * x   quaternionY * z - quaternionZ * y;
const iy =   quaternionW * y   quaternionZ * x - quaternionX * z;
const iz =   quaternionW * z   quaternionX * y - quaternionY * x;
const iw = - quaternionX * x - quaternionY * y - quaternionZ * z;

x = ix * quaternionW   iw * - quaternionX   iy * - quaternionZ - iz * - quaternionY;
y = iy * quaternionW   iw * - quaternionY   iz * - quaternionX - ix * - quaternionZ;
z = iz * quaternionW   iw * - quaternionZ   ix * - quaternionY - iy * - quaternionX;

x = x * distance   originalPositionX;
y = y * distance   originalPositionY;
z = z * distance   originalPositionZ;

Which can be simplified to this:

function ray(position, distance, direction) {
  const dy2 = 2 * direction.y;
  const dx2 = 2 * direction.x;
  const x = position.x   distance * (dy2 * direction.w   dx2 * direction.z);
  const y = position.y   distance * (dy2 * direction.z - dx2 * direction.w);
  const z =
    position.z  
    distance *
      (-1 * Math.pow(direction.y, 2)  
        Math.pow(direction.z, 2)  
        Math.pow(direction.w, 2) -
        Math.pow(direction.x, 2));

  return {x, y, z};
}
  •  Tags:  
  • Related