2

currently I'm dealing with the following problem. I am working with javascript and I cannot (and dont want to) use any third party .js libraries.

I am writing a function and I have two standard transformation matrices on the input - A and B:

var A = [
    [a, c, e],
    [b, d, f],
    [0, 0, 1]
];

var B = [
    [a, c, e],
    [b, d, f],
    [0, 0, 1]
];

and a theta value T between or equal to 0 and 1. The numbers a,b,c,d correspond to rotation and scaling and e and f are equal to x and y position.

I need to interpolate between these two matrices and I was wondering, what is the best approach (performance-wise) as this function will be called very often. I have already sorted out the x and y part using lerp. Now I'm wondering what would be the least intensive way to do this. These are the options I found so far:

  • 1st Option - use quaternions and slerp - from what I found on the net and heard from my coleagues, this option involves a lot of computing. I am also not very familiar with this approach and I don't know how to implement it to suit this scenario.
  • 2nd Option - decompose the two matrices, get the Translation, Rotation and Scale values for A and B and store them, then lerp by T these and compute the resulting matrix.

Is there any other approach maybe less CPU intensive I can use that I missed?

Spektre
  • 49,595
  • 11
  • 110
  • 380
JKurcik
  • 230
  • 1
  • 12
  • 1
    2nd option as you described would give incorrect results - you would still have to "Slerp" between the rotational parts; however, this is in-fact quite easy to do in the 2D case, because there is only one angle and also no concept of "rotation axis" – meowgoesthedog Nov 13 '17 at 11:21
  • @meowgoesthedog can you please explain how would I "Slerp" between the rotational parts? I am still lost in the math behind it – JKurcik Nov 13 '17 at 11:51
  • 3
    Here is one way to do it. Suppose `A` and `B` are two rotations, then `C = B * inv(A)` gives the total rotation "delta" to go from `A` to `B`. You need to raise `C` to the power of your interpolation parameter and post-multiply by `A`. To do so, you can compute the (*signed*) rotation angle delta of `C` (using e.g. `atan2`), multiply it by the parameter, and construct a new matrix with this new angle. – meowgoesthedog Nov 13 '17 at 12:06

1 Answers1

0

If I see it right you got 2D transform:


(a,b) is X axis direction vector
(c,d) is Y axis direction vector
(e,f) is origin position

so let define scalar parameter t in range t=<0.0,1.0> interpolating from A(a0,b0,...) to B(a1,b1,...).

The position can be interpolated directly:

e(t)=e0+(e1-e0)*t
f(t)=f0+(f1-f0)*t

Now the direction vectors have angle ax,ay and size sx,sy:

ax = atan2(b,a)
ay = atan2(d,c)
sx = sqrt(a^2 + b^2)
sy = sqrt(c^2 + d^2)

So you can interpolate that:

ax(t)=ax0+(ax1-ax0)*t
ay(t)=ay0+(ay1-ay0)*t
sx(t)=sx0+(sx1-sx0)*t
sy(t)=sy0+(sy1-sy0)*t

And construct matrix back:

a=sx*cos(ax)
b=sx*sin(ax)
c=sy*cos(ay)
d=sy*sin(ay)

That should do the trick ...

For more info see:

Spektre
  • 49,595
  • 11
  • 110
  • 380