1

Consider fully determined unit vectors $a\,b\,c$, and aligning vector $b$ to $a$ by rotating $b$ and $c$ together so that $\mathrm{R}\times b = a$, where $\mathrm{R}$ is the rotation matrix, and I need to find out $\mathrm{R}\times c$.

the most straightforward method I can think of is using rotation $\mathrm{R}\times b = a$ and solve for $\mathrm{R}$

then obtain $c' = \mathrm{R}\times c$

However, this needs to be done on microcontroller in real-time at sub-human response rate so solving for $\mathrm{R}$ seems too expensive.

Is there a way to find out $c'$ without having to solve $\mathrm{R}$?

7E10FC9A
  • 113
  • 1
    Is this algorithm too slow for your situation? – durianice Apr 03 '23 at 17:14
  • @wnoise that is exactly the method I mentioned, but it's too expensive for microcontrollers, I'm wondering if we can find c' without solving R – 7E10FC9A Apr 03 '23 at 18:00
  • 1
    There are many possible rotations that will take a given unit-vector a to b. (Proof: given one R, you can pre-multiply it by a rotation around a, and post-multiply it by a rotation around b.) Your problem is thus under-determined. Do you have any other constraints on the rotation that you want to apply to c? – wnoise Apr 03 '23 at 18:33
  • @wnoise b and c are rigid, i.e. the relative position of b and c can never change. – 7E10FC9A Apr 03 '23 at 18:41
  • @durianice actually I'm writing in micopython and I have already implemented the said method, but it's too slow – 7E10FC9A Apr 03 '23 at 19:01
  • Being too slow for micropython is a lot more believable than being too slow for a microcontroller. A micrcontroller should be able to handle the linked algorithm just fine -- the only "slow" part is a single divide by (1 + cos theta). I really doubt the math is the slow part, but everything else for python to actually do the math is conceivably too much. What rate do you need, and what rate is an empty body that doesn't actually calculate anything? – wnoise Apr 03 '23 at 19:51

1 Answers1

1

As already mentioned, there are multiple rotations that satisfy this. The semi-standard thing to do is take the "smallest" rotation. It's well known how to construct this rotation, as Calculate Rotation Matrix to align Vector $A$ to Vector $B$ in $3D$? makes clear.

If you want to apply a rotation to c, that rotation has to be found and represented somehow. You claim that this is too expensive to be calculated on a microcontroller. I don't really buy that -- the most expensive thing is a single division (though significant multiplications and additions). Being too slow for micropython is a lot more believable than being too slow for a microcontroller. A microcontroller should be able to handle the linked algorithm just fine -- the only "slow" part is a single divide by (1 + cos theta). But everything else for python to actually do the math is conceivably too much.

But you're not going to get better than one division.

Any representation is going to have a normalization step somewhere, even when all inputs are unit vectors, so you're not going to get better than that. Listing them out:

  1. We've already covered the rotation matrix.

  2. A common kind of intermediate representation is "axis-angle" representations, but they're generally hard to apply to vectors. Going through one was how that rotation matrix was derived, because there was an obvious axis, and an easy way to get the cosine of the angle. But the axis isn't normalized, and the cosine of the angle is not what is usually used.

  • Unit-vector, and angle, or vector with angle as magnitude. Calculating any of this requires normalization of readily-available non-unit vector, requiring square-root, . Applying it to a vector is another nasty step.
  • Rodriguez -- unit vector multiplied by tan(\theta/2). There is a composition rule, but applying to vectors is still easiest done by converting to rotation matrix.
  • Euler parameters/unit quaternions are another popular choice, though they're essentially an axis-angle representation with a nicer way to apply to vectors. However, calculating their components requires the sine and cosine of half the angle which requires square-roots, which are another "slow" calculation. (And a unit axis, which also needs another square-root, and a division).
  1. Euler angles. No. Just no. There are like 688 different variants, and none of them are nice.

  2. Geometric Algebra/rotors. This is actually quite close to the Euler parameter/quaternion case in that the problem is half-angles in the representation. If you want to do twice the angle, then this would actually be straightforward, and fast. But getting normalized half-angles still involves square-roots and generic divisions. You can also try to calculate a set of vectors that are halfway there, but those will also require normalization...

Of these, the rotation matrix really does look to be the best choice.

wnoise
  • 2,281