4

First off, this is not a duplicate. All other seemingly related questions ask for the quaternion representing rotation between directions of 2 vectors, i.e. the solutions do not take into account norms of these 2 vectors.

Here is what I want. Imagine that I have non-unit vectors a = (0, 0, 2) and b = (3, 1, 2). Following the original Hamilton's definition of quaternion q = a / b (this definition is symbolic, since of course you cannot divide vectors). Refer to Wikipedia for this concept. From that I can infer (maybe it's naive) that somehow I can find such q that q * b = a.

In other words, given a and b I want to find a quaternion q which when multiplied by b will give me a. Please, pay attention to the fact that I'm not interested in plain rotating (unitary) quaternion which would simply rotate b into direction of a. In fact, in addition to rotation, I want norm of b to be scaled to the norm of a as well.

Yes, I know that I could do it in two stages: rotating b with standard unitary quaternion approach and then manually scaling the rotated b to the norm of a which would of course involve additional square roots (which is what I'm trying to avoid here). In fact, I want a computationally efficient composition of these 2 operations, and I feel like it's achievable, but the information is not widespread since it does not seem to be conventional use case.

Maybe I'm wrong. Please, share your experiences. Thank you.

Why not math.stackexchange.com?

Because I'm not interested in thorough mathematical derivation or explanation. My concern is computationally efficient algorithm for construction of such quaternion. Nevertheless, if such details will be included in the answer, I'd really appreciate that and probably others who stumble across the same issue in future too.

For Close Voters:

Go ahead and close Finding quaternion representing the rotation from one vector to another as well.

Furthermore, I have tagged my question properly. My question belongs to these highly-populated tags which are part of StackOverflow. As a result, your reasons for close do not make any sense.

Community
  • 1
  • 1
Alexander Shukaev
  • 16,674
  • 8
  • 70
  • 85
  • As far as quaternions are concerned, you have `conjugate(x)*x = norm(x)^2`. Real quaternions are central (commute with all quaternions), so `q = 1/norm(b)^2 * a * conjugate(b)` would satisfy `q*b = a`, and involve no square roots. – Daniel Fischer Jul 11 '13 at 20:56
  • 2
    This is probably a better fit for [math.stackexchange.com](http://math.stackexchange.com) – BlueRaja - Danny Pflughoeft Jul 11 '13 at 21:08
  • @BlueRaja: Nope, my question is more programming related, I'm interested in algorithm, rather than deep mathematical understanding (although that would be nice too, if included in the answer). – Alexander Shukaev Jul 11 '13 at 21:09
  • @Daniel Fischer: I'm sorry, I'm a bit confused by the `q = 1/norm(b)^2 * a * conjugate(b)` formula. `a` and `b` are vectors, not quaternions. Did I miss anything? How can you construct quaternion with vectors? For the same reason `conjugate(b)` looks strange. – Alexander Shukaev Jul 11 '13 at 21:16
  • I'm not 100% sure if I remember correctly, but isn't the use of quaternions for (3-d) geometry given by identifying a vector in `R^3` with a purely imaginary quaternion? – Daniel Fischer Jul 11 '13 at 21:20
  • I understand your answer can be used in programming, but you are asking how to divide quaternions, which is purely mathematics. – BlueRaja - Danny Pflughoeft Jul 11 '13 at 21:20
  • 1
    For all close voters: go ahead and close http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another as well. – Alexander Shukaev Jul 12 '13 at 02:40
  • To explain what Daniel Fischer is saying, if a quaternion is represented by ``, you form a quaternion from a vector by simply appending a 0 in the `w` slot. The only real component of a quaternion is `w`, so a vector is essentially a purely imaginary quaternion. Another good alternative method to finding rotation matrices between a set of vectors is [this algorithm](http://nghiaho.com/?page_id=671). It's not good if you just want the rotation between 2 vectors, but if you have a large set of vectors/points then it's perfect. I wish I could remember the algorithm's real name though – Suedocode Jul 12 '13 at 15:38

1 Answers1

1

Daniel Fischer's comment-answer is correct. It turns out that there are infinite ways to construct such a quaternion. The problem boils down to a linear system with three equations and four variables. It's under-constrained (if we assume we'll discard the [w] part of the result).

Perhaps I can clarify Fischer's answer.

When you treat two vectors as quaternions and multiply them, you get their cross-product in the [x,y,z] part and you get their negated dot-product in the [w] part:

    | 0| | 0| |-ax*bx-ay*by-az*bz|
a*b=|ax|*|bx|=|    ay*bz-az*by   |
    |ay| |by| |    az*bx-ax*bz   |
    |az| |bz| |    ax*by-ay*bx   |

When you left-multiply a full-quaternion with a vector, you get the same thing, but the [w] part scales the vector and adds it back to the cross-product:

    |qw| | 0| |-qx*bx-qy*by-qz*bz|
q*b=|qx|*|bx|=| qy*bz-qz*by+qw*bx|
    |qy| |by| | qz*bx-qx*bz+qw*by|
    |qz| |bz| | qx*by-qy*bx+qw*bz|

Recall that

a x b = |a||b|sin(Θ)n

where n is a unit vector that is orthogonal to a and b. And

a . b = |a||b|cos(Θ)

The quaternion conjugate of a vector is just its negation.

So if we look at Fischer's equation:

a = q*b = |b|^{-2} * a * b' * b

We can see that

a*b' = | -dotP(a,-b)| 
       |crossP(a,-b)|

And so

a*b'*b = |        -dotP(crossP(a,-b),b)         |
         | crossP(crossP(a,-b),b) - dotP(a,-b)b |

The top ([w]) portion of this quaternion must be zero because it is the dot-product between two orthogonal vectors. The bottom portion is a scaled version of a: The nested cross-products produce a vector that is orthogonal to both b and n and is the length of |a|*|b|*|b|. The dot-product portion adds in the projection of a onto b (scaled by the squared length of b). This brings it parallel to a. Once we divide out the squared length of b, all that's left is a.

Now, the question of whether or not this is actually useful is different. It's not very useful to finding a, since you need to have it to begin with. Furthermore, odds are good that q*c is not going to do what you're hoping, but you'd have to tell us what that is.

JCooper
  • 6,395
  • 1
  • 25
  • 31