how to rotate point around a line in 3D

804 Views Asked by At

I have a body with origin at point A which is represented in homogeneous coordinate of matrix 4x4 and I would like to rotate it around an arbitrary vector in 3d space. I understand how to rotate the body around its own frame axis, but Im not sure how to rotate it around any vector in space.

2

There are 2 best solutions below

0
On

I don't understand the entire question, but I can tell you how to rotate $\mathbb{R}^3$ about a vector $v \in \mathbb{R}^3$. It's very easy if you choose a convenient basis.

Basically, we build an orthonormal basis for $\mathbb{R}^3$ beginning with $\frac{v}{\|v\|}$. There's a few ways to do this. You could "choose" a vector that's orthogonal to $v$ (just intuitively by looking at the vector), then cross product it with $v$ to get a third orthogonal vector, then normalise them all. You could also take the standard basis, replace one of the vectors by $v$ (provided $v$ is not in the span of the other two), rearrange so that $v$ is the first vector in the new basis, then apply Gram-Schmidt.

Either way, we obtain an orthonormal basis $B = (e_1, e_2, e_3)$ so that $e_1 = \frac{v}{\|v\|}$. Note that $\operatorname{span}(e_2, e_3)$ is the plane orthogonal to $v$, which makes it the plane in which we are rotating. We define the transformation by its action on $B$. That is, we define the transformation $T$ by its matrix $\mathcal{M}(T, B, B)$. We let, $$\mathcal{M}(T, B, B) = \left(\begin{array}{ccc}1 & 0 & 0 \\ 0 & \cos(\theta) & -\sin(\theta) \\ 0 & \sin(\theta) & \cos(\theta)\end{array}\right).$$ Basically, $T$ fixes the line spanned by $V$, and rotates $e_2$ towards $e_3$ by $\theta$.

Let $S$ denote the standard basis. To get a standard matrix for $T$, we can use a change of basis matrix $U$, which we define as $$U = \mathcal{M}(I, B, S) = \left( e_1^T | e_2^T | e_3^T \right)$$ Then as the columns of $U$ are an orthonormal basis, it is an orthogonal matrix, so $U^{-1} = U^T$. Thus the standard matrix is given by, $$\mathcal{M}(T, S, S) = U \mathcal{M}(T,S,S) U^T.$$ Hope that helps.

0
On

example source code from Unreal engine:

/**
 * Rotates around Axis (assumes Axis.Size() == 1).
 *
 * @param Angle Angle to rotate (in degrees).
 * @param Axis Axis to rotate around.
 * @return Rotated Vector.
 */
inline FVector FVector::RotateAngleAxis(const float AngleDeg, const FVector& Axis) const
{
    float S, C;
    FMath::SinCos(&S, &C, FMath::DegreesToRadians(AngleDeg));

    const float XX  = Axis.X * Axis.X;
    const float YY  = Axis.Y * Axis.Y;
    const float ZZ  = Axis.Z * Axis.Z;

    const float XY  = Axis.X * Axis.Y;
    const float YZ  = Axis.Y * Axis.Z;
    const float ZX  = Axis.Z * Axis.X;

    const float XS  = Axis.X * S;
    const float YS  = Axis.Y * S;
    const float ZS  = Axis.Z * S;

    const float OMC = 1.f - C;

    return FVector(
        (OMC * XX + C) * X + (OMC * XY - ZS) * Y + (OMC * ZX + YS) * Z,
        (OMC * XY + ZS) * X + (OMC * YY + C) * Y + (OMC * YZ - XS) * Z,
        (OMC * ZX - YS) * X + (OMC * YZ + XS) * Y + (OMC * ZZ + C) * Z
        );
}
```