henit
henit

Reputation: 1170

Calculate current position between two points based on distance left

Ok, I have two positions in 3d space:

var fromX = 1,
    fromY = 2,
    fromZ = 3,
    toX = 15,
    toY = 16,
    toZ = 17;

Then I need to calculate the current position, when someone/something is moving in a straight line from the from-coordinates, to the to-coordinates. I know the distance left is 2, what would be the formula for calculating the current position?

I guess this is more of a math question than a javascript question, but it is for a javascript application, so I'm hoping that is not a problem.

Upvotes: 0

Views: 1702

Answers (3)

Salix alba
Salix alba

Reputation: 7824

You need to use 3D Pythagoras to find the distance between two points. If x1,y1,z1 and x2,y2,z2 are your points then the distance is sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2). There are several ways of finding the desired point. We can find the distance from the starting point to the ending point and then calculate the proportion of that distance which will give 2 as a result using linear interpolation.

var fromX = 1,
  fromY = 2,
  fromZ = 3,
  toX = 15,
  toY = 16,
  toZ = 17;
// find the difference
var dx = toX-fromX, dy = toY-fromY, dz=toZ-fromZ;
// find the total length
var dist = Math.hypot(dx,dy,dz);

// find the proportion of this length
var lambda = (dist-2.0) / dist;

// do the linear interpolation
var x = fromX + lambda * dx,
    y = fromY + lambda * dy,
    z = fromZ + lambda * dz;
console.log(x,y,z);

// Just to check
var dx2 = toX-x, dy2 = toY-y, dz2=toZ-z;
var dist2 = Math.hypot(dx2,dy2,dz2);
console.log(dist2);

We get the result 13.845299461620748 14.845299461620748 15.845299461620748 and the final distance is 2.0000000000000013.

Note I've uses Math.hypot this is a new feature which works in Chrome/firefox/opera but not in IE. There is a work-around to enable it in other browsers if needed. You just use Math.sqrt(dx*dx+dy*dy+dz*dz) instead.

Upvotes: 1

RobG
RobG

Reputation: 147403

There are already 2 answers with the correct algorithm, this one's no different, just a bit neater.

// Distance between two points is the square root of the sum
// of the squares of the differences
function get3dDistance(startCoords, endCoords) {
  var dx = Math.pow((startCoords[0] - endCoords[0]), 2);
  var dy = Math.pow((startCoords[1] - endCoords[1]), 2);
  var dz = Math.pow((startCoords[2] - endCoords[2]), 2);
  return Math.sqrt(dx + dy + dz);
}

// The coordinates of a point some distance from the end is
// proportional to the distance left and total distance.
function getCoordsFromDistanceLeft(startCoords, endCoords, distanceLeft) {
  var distance = get3dDistance(startCoords, endCoords);
  var f = (distance - distanceLeft)/distance;
  return [startCoords[0] + f*(endCoords[0] - startCoords[0]),
          startCoords[1] + f*(endCoords[1] - startCoords[1]),
          startCoords[2] + f*(endCoords[2] - startCoords[2])];
}

// Test case
var start = [1,2,3];
var end   = [15,16,17];
var distanceLeft = 2;

// Distance between the two points
var dist = get3dDistance(start, end)

document.write('distance: ' + dist + '<br>');
// distance: 24.24871130596428

// Get the coords
var x = getCoordsFromDistanceLeft(start, end, distanceLeft);

document.write('x: ' + x + ' is ' + distanceLeft + ' to end<br>');
// x: 13.845299461620748,14.845299461620748,15.845299461620748 is 2 to end

document.write('From x to end: ' + get3dDistance(x, end) + '<br>');
// From x to end: 2.0000000000000013

Salix alba has introduced Math.hypot, which is interesting but since it's a new feature in ECMAScript 2015 it would be wise to include a polyfill.

Upvotes: 1

nathanvda
nathanvda

Reputation: 50057

Given two points, fromPt and toPt, the distance between two points can easily be calculated:

distanceX = Math.pow(fromPt.x - toPt.x, 2)
distanceY = Math.pow(fromPt.y - toPt.y, 2)
distanceZ = Math.pow(fromPt.z - toPt.z, 2)
total_distance = Math.sqrt(distanceX + distanceY + distanceZ) 

and now finding the correct point along the line is just a case of correct interpolation :)

newPt = {}
newPt.x = fromPt.x + ((toPt.x - fromPt.x) * (wantedDistance / total_distance))
newPt.y = fromPt.y + ((toPt.y - fromPt.y) * (wantedDistance / total_distance))
newPt.z = fromPt.z + ((toPt.z - fromPt.z) * (wantedDistance / total_distance))  

Upvotes: 2

Related Questions