Normal to a rectangle 3d space and rotate

1.2k Views Asked by At

I have 4 vertices in 3d space that form a rectangle. My goal is to rotate these vertices around the normal of the rectangle.

So what I need is:

  1. How to calculate the normal vector of the 3d rectangle (origin in the center of the rect)
  2. How can I rotate the vertices around this normal vector in angles (e.g. 5 degrees)

Thx for your help.

1

There are 1 best solutions below

1
On BEST ANSWER

Let's say your four vertices are $$\bbox{ \vec{v}_1 = (x_1, y_1, z_1) } , \quad \bbox{ \vec{v}_2 = (x_2, y_2, z_2) } , \quad \bbox{ \vec{v}_3 = (x_3, y_3, z_3) } , \quad \bbox{ \vec{v}_4 = (x_4, y_4, z_4) } $$ with $\vec{v}_1$ and $\vec{v}_3$ diagonally opposite each other in the rectangle.

The center of the rectangle is at $\vec{c}$, $$\bbox{ \vec{c} = \frac{\vec{v}_1 + \vec{v}_2 + \vec{v}_3 + \vec{v}_4}{4} = \left ( \frac{x_1 + x_2 + x_3 + x_4}{4}, \frac{ y_1+y_2+y_3+y_4 }{4}, \frac{z_1+z_2+z_3+z_4}{4} \right ) }$$ and the normal of the plane that passes through vertices $\vec{v}_1$, $\vec{v}_2$, and $\vec{v}_3$ is $$\bbox{ \vec{p} = (\vec{v}_3 - \vec{v}_2) \times (\vec{v}_1 - \vec{v}_2) }$$ that is, $$\bbox{ \begin{aligned} \vec{p} &= ( x_p ,\, y_p ,\, z_p ) \\ x_p &= (y_3 - y_2)(z_1 - z_2) - (z_3 - z_2)(y_1 - y_2) \\ y_p &= (z_3 - z_2)(x_1 - x_2) - (x_3 - x_2)(z_1 - z_2) \\ z_p &= (x_3 - x_2)(y_1 - y_2) - (y_3 - y_2)(x_1 - x_2) \\ \end{aligned} }$$

In practice, you'll want to use the unit normal, the above scaled to length 1, $$\bbox{ \hat{n} = ( x_n ,\, y_n ,\, z_n ) = \left ( \frac{x_p}{\sqrt{x_p^2 + y_p^2 + z_p^2}} ,\; \frac{y_p}{\sqrt{x_p^2 + y_p^2 + z_p^2}} ,\; \frac{z_p}{\sqrt{x_p^2 + y_p^2 + z_p^2}} \right ) }$$

For the rotation around that unit normal, you can use Rodrigues' rotation formula. To rotate $\vec{v}$ by $\theta$ around axis $\hat{n}$, to $\vec{v}^\prime$, $$\bbox{ \vec{v}^\prime = \vec{v} \cos\theta + (\hat{n} \times \vec{v}) \sin\theta + \hat{n} ( \hat{n} \cdot \vec{v} )(1 - \cos\theta) }$$ where $\cdot$ denotes dot product, and $\times$ vector cross product.

In OP's case, the rotation is around $\vec{c}$: $$\bbox{ \vec{v}^\prime = \vec{c} + (\vec{v} - \vec{c}) \cos\theta + \bigr ( \hat{n} \times (\vec{v} - \vec{c}) \bigr ) \sin\theta + \hat{n} \bigr ( \hat{n} \cdot ( \vec{v} - \vec{c} ) \bigr ) (1 - \cos\theta) }$$

or in notation perhaps more familiar to programmers,

x_new = x_c + cos(theta)*(x_v - x_c) + sin(theta)*( y_c*z_n - y_n*z_c + y_n*z_v - y_v*z_n) + (cos(theta) - 1)*x_n*( x_c*x_n - x_n*x_v + y_c*y_n - y_n*y_v + z_c*z_n - z_n*z_v )
y_new = y_c + cos(theta)*(y_v - y_c) + sin(theta)*(-x_c*z_n + x_n*z_c - x_n*z_v + x_v*z_n) + (cos(theta) - 1)*y_n*( x_c*x_n - x_n*x_v + y_c*y_n - y_n*y_v + z_c*z_n - z_n*z_v )
z_new = z_c + cos(theta)*(z_v - z_c) + sin(theta)*( x_c*y_n - x_n*y_c + x_n*y_v - x_v*y_n) + (cos(theta) - 1)*z_n*( x_c*x_n - x_n*x_v + y_c*y_n - y_n*y_v + z_c*z_n - z_n*z_v )

where $\vec{v}$ = (x_v, y_v, z_v) is the point to rotate, $\hat{n}$ = (x_n, y_n, z_n) is the unit vector representing the rotation axis, $\vec{c}$ = (x_c, y_c, z_c) is the center of rotation, and theta is the angle rotated.

You can optimize the expression quite a bit by calculating many of the terms into temporary variables, so you don't do the same operations again and again needlessly.


If we have $\vec{a} = ( a_x , a_y , a_z )$ and $\vec{b} = ( b_x , b_y , b_z )$, then dot product is $$\bbox{ \vec{a} \cdot \vec{b} = a_x b_x + a_y b_y + a_z b_z }$$ and yields a scalar; and cross product is $$\bbox{ \vec{a} \times \vec{b} = ( a_y b_z - a_z b_y ,\, a_z b_x - a_x b_z ,\, a_x b_y - a_y b_x ) }$$ and yields a vector.