1
$\begingroup$

The up reference is Y.

I have a bunch of vectors that are oriented relative to the XZ plane. I'm not sure if that makes sense, so just consider that these vectors all have positive Y values, and that these vectors are normalized.

My goal is to rotate these vectors so that they are oriented relative to a new plane, given that plane's normal.

This image may help: Applying orange vectors to a surface defined by a blue normal.

I want to take each of the orange vectors, and apply a rotation to them so that they lie on the plane segment whose edges have green lines attached to it, this plane is defined by a blue normal.

Let $v$ be an orange vector to rotate, whose length is 1, and whose y value is positive. Let $n$ be a blue surface normal, whose length is 1, and whose y value is positive.

Currently I do this by finding an axis and angle to rotate by, where the axis is $ u = n \times \{0,1,0\} $, and the angle is $ \theta = acos(\{0,1,0\} \cdot n) $.

Then I form an axis-angle rotation matrix, and multiply this matrix by $v$ to get the desired rotated vector.

The problem with this is that it is slow, so I need a faster way.

I thought that I might be able to form a rotation matrix by finding the tangent, binormal and having the given blue normal vector $n$.

So I tried this:

Tangent $t = n \times \{1,0,0\}$.

Binormal $b = t \times n$.

Then I normalize $t$ and $b$ and put them in a matrix like so:

$R = \begin{array}{ccc} t_x & b_x & n_x \\ t_y & b_y & n_y \\ t_z & b_z & n_z \end{array} $

Then I multiply the rotation matrix $R$ by $v$, but this doesn't rotate $v$ onto the plane as desired.

Is there a fast way to find the rotation matrix to rotate $v$ onto the plane defined by $n$? Does my tangent/normal/binormal matrix idea work, but I'm just making a small mistake, like calculating the binormal wrong?

  • 0
    P.S. Sorry for making this simple question so long. I'm just trying to be clear. Please let me know if anything is unclear.2011-04-25

2 Answers 2

1

The problem with your "binormal" idea is that it uses a different rotation axis than the angle/axis approach. You want a rotation matrix that maps $z = (0, 0, 1)^T$ to $n$ and leaves $t$ alone. To build this matrix, you need a third correspondence, say from $a = t \times z$ to $b = t \times n$. Set up two matrices (defined by their columns) $A := (z, t, a)$ and $B := (n, t, b)$. The rotation matrix you are looking for is given by $R = B A^{-1} = B A^T$. You can multiply this out explicitly, but this is probably as efficient as it gets.

  • 0
    Finally, thank you Andreas!2011-05-25
1

The simplest solution should be to combine two rotations along the axes. You are trying to find a rotation that brings the vector $(0,1,0)$ to $n$. Considering that rotation matrices along the axes are of the form :

$\begin{pmatrix} a & \sqrt{1-a^2} & 0 \\ -\sqrt{1-a^2} & a & 0 \\ 0 & 0 & 1\\ \end{pmatrix}$

You can solve a system of equations and find a rotation around the $z$ axis and a rotation around the $y$ axis that do what you need. If you combine both of the following rotations :

$\begin{pmatrix} \frac{n_1}{\sqrt{1-n_2^2}} & 0 & \sqrt{\frac{1-n_2^2-n_1^2}{1-n_2^2}} \\ 0 & 1 & 0 \\ -\sqrt{\frac{1-n_2^2-n_1^2}{1-n_2^2}} & 0 & \frac{n_1}{\sqrt{1-n_2^2}}\\ \end{pmatrix} \begin{pmatrix} n_2 & \sqrt{1-n_2^2} & 0 \\ -\sqrt{1-n_2^2} & n_2 & 0 \\ 0 & 0 & 1\\ \end{pmatrix}$

You get a rotation that does what you need, provided that $n=(n_1,n_2,n_3)$ is normalized.

  • 0
    When I posted this question a month ago, I was thinking that this isn't stackoverflow, so I didn't want to critisize this answer because there's no reason to expect software implementation details to be well known on Math.SE. Anyways +1 because this answer was ultimately helpful to my cause :)2011-05-25