0
\$\begingroup\$

I am struggling to figure out how to lerp one vector2 to a target vector2 at a constant rate. I can do it as a percentage of the total x, y distance like so:

lerp(start, current, target, pctSpeed) {
  return current + pctSpeed * (target - start);
}

calling it as such:

speed = .02

// game loop
Update(timestamp) {
  x = lerp(startX, x, targetX, speed)
  y = lerp(startY, y, targetY, speed)
  resultingVector2 = {x: x, y: y}
}

which correctly lerps x and y by 2% of the distance between the start and target vector2 each frame. How do you do this at a constant rate, i.e instead of 2% a value of 2 or .2 or 3, etc. Thanks

\$\endgroup\$
2
  • \$\begingroup\$ If the function interpolates target vector by 2% of target vector, you are interpolating it at costant rate already. \$\endgroup\$ – liggiorgio Apr 1 '18 at 20:42
  • \$\begingroup\$ True, the behavior I am trying to avoid is that for larger distances the interpolation will occur more quickly than for shorter distances in terms of speed as it is percentage based. 2% of 1000 is > 2% of 25. I would rather like it to be a fixed distance interpolation, say of 5 instead of 2% of the total distance. \$\endgroup\$ – shell Apr 1 '18 at 20:55
0
\$\begingroup\$

I'd recommend not redefining a common method like Lerp. Linear interpolation has a standard definition:

Lerp(a, b, t) {
    return (1-t) * a + t * b;
}

If you redefine it to describe any old movement along a line, your code will become very hard to understand for anyone who's used to this standard.

Instead, if you want to move at a constant speed, define a new method for that:

Approach(current, target, maxStepDistance) {
    toTarget = target - current;

    // Clamp our travel so we never move further than our allowed step.
    squareMagnitude = dot(toTarget, toTarget);
    if(squareMagnitude > maxStepDistance * maxStepDistance) {
        toTarget *= maxStepDistance/sqrt(squareMagnitude)
    }

    return current + toTarget;
}

Which you can use like so:

Update(timestamp) {
    // Make sure you're using a high precision source for your timestamp
    // when calculating deltaTime - a float will lose precision after hours of play.
    deltaTime = timeStamp - lastFrameTimestamp;
    lastFrameTimestamp = timestamp;

    // Multiply speed by the timestep to get the distance travelled this frame.
    current = Approach(current, target, speed * deltaTime);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.