1

I've seen a couple of lerp functions, mainly for lerping vectors, and they seem to go like this:

vector lerp(float bias, vector start, vector end)
{ return (1-bias) * start + bias * end; }

Whereas my naive way of doing it would be:

vector lerp(float bias, vector start, vector end)
{ return (end - start) * bias + start;

I following shows the breakdown of the two methods:

two float by vector multiplications | one vector addition                            | one float subtraction | 
one float by vector multiplication  | one vector addition and one vector subtraction | 

Simplified, that means:

6 float multiplications  | 3 additions | one float subtraction
3 float multiplications  | 6 additions | 

Am I mixed and have got the wrong idea that these are equivalent? I struggle sometimes with simple math concepts.

Edit: I just realised, in my case I need a halfway lerp, which is even cheaper to be done by getting the average of the two vectors' components. That's simply one addition and one multiplication for each axis, X, Y, Z. I think I'll do that.

Zebrafish
  • 11,682
  • 3
  • 43
  • 119

2 Answers2

1

This is a tradition that comes from Mathematics and has to do with affine transformations, a sort of transformations that map vectors in vectors in a linear way without the restriction of having to map the origin onto itself.

Linear transformations satisfy

f(a1*v1 + ... + an*vn) = a1*f(v1) + ... + an*f(vn)

Affine transformations satisfy the same provided that

a1 + a2 + ... + an = 1.

Why? Because an affine transformation happens to be of the form f() + c, for some linear transformation f() and some constant c.

An affine combination is an expression of the form

a1*v1 + ... + an*vn  

where the sum of the ai is 1. They are a special case of liner combinations.

Now, if you have only two points A and B in whatever dimension (1, 2, 3, etc.) the straight line defined by A to B can be seen as the place where all affine combinations live:

 s*A + t*B  (s + t = 1)

In this special case of only two points, you can also express them with only one parameter

 (1 - t)*A + t*B.

When t = 0 your are in point A, when t=0.5 you are right in the middle between A and B and when t=1, you are in B.

So, you can think of t as the time, and consider that you are traveling from A to B when t goes from 0 to 1. Negative values of the parameter t correspond to points on the line but not in the segment, and the same holds for t > 1.

In other words, it is totally ok to use (B - A)*t + A (which again, is valid in any dimension) except that (1-t)*A + t*B makes it apparent the link with affine geometry.

Leandro Caniglia
  • 14,495
  • 4
  • 29
  • 51
  • Thanks. I didn't quite appreciate the earlier stuff you said, but looking at it in terms of that formula I could picture it. I pictured it as adding t percent of one vector and 1-t of the other vector, they seemed to always (visually) point on the line. – Zebrafish Nov 24 '16 at 08:34
  • That's fine. Just be aware that what you pictured corresponds to a more general Mathematical concept, and that's why some people try to make the relationship explicit. – Leandro Caniglia Nov 24 '16 at 11:55
0

There is a certain symmetrical elegance in the

(1-bias) * start + bias * end

form. It means that neither start or end have a particular significance.

If we look at the speed of operations multiplication is not drastically slower than addition. (See for example Does each Floating point operation take the same time?) If we treat each operation as the same time then to a first approximation both methods have the same operation count.

I've not come across a case where it's the lerp code proves to be a significant bottleneck in the code so there is a case of premature optimisation, here.

Community
  • 1
  • 1
Salix alba
  • 7,536
  • 2
  • 32
  • 38