Rotate a model around its own axes

3d, geometry, math, wpf

Solution

Ok, spoke to a mathematician friend and he gave me the answer:

so i think what you need to do if you're rotating around the vector (1,0,0) by an angle of 'a' (i.e rotating around the x-axis so transforming your object in the y-z plane).

Further rotations are around

x' - (1,0,0) stays the same!

y' - (0,cosa,sina)

z' - (0,-sina,cosa)

a similar principle will hold for rotations in the x-z plane (0,1,0)

x' - (-sina,0, cosa)

y' - (0,1,0) - the same

z' - (sina,o,cosa)

and in the x-y plane around (0,0,1)

x' - (-sina,cosa,0)

y' - (cosa,sina,0)

z' - (0,0,1) stays the same

TADA!

UPDATE: I created a function to calculate a matrix which will rotate an object in all 3 axes. This can be used with a MatrixTransform3D.

    Matrix3D CalculateRotationMatrix(double x, double y, double z)
    {
        Matrix3D matrix = new Matrix3D();

        matrix.Rotate(new Quaternion(new Vector3D(1, 0, 0), x));
        matrix.Rotate(new Quaternion(new Vector3D(0, 1, 0) * matrix, y));
        matrix.Rotate(new Quaternion(new Vector3D(0, 0, 1) * matrix, z));

        return matrix;
    }

Problem

Suppose I have a simple WPF 3D scene set up with a single rectangle rotated -45 degrees around the X axis like so: ``` <Viewport3D> <Viewport3D.Camera> <PerspectiveCamera Position="0,0,4"/> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="White" Direction="-1,-1,-3" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D Positions="-1,-1,0 1,-1,0 -1,1,0 1,1,0" TriangleIndices="0,1,2 1,3,2"/> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <DiffuseMaterial Brush="Red"/> </GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> <ModelVisual3D.Transform> <Transform3DGroup> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D Axis="1,0,0" Angle="-45"/> </RotateTransform3D.Rotation> </RotateTransform3D> </Transform3DGroup> </ModelVisual3D.Transform> </ModelVisual3D> </Viewport3D> ``` This gives me the following: Now I want to rotate the image 45 degrees around the model's Z axis. If I just put a second RotateTransform3D in like so: ``` <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D Axis="0,0,1" Angle="45"/> </RotateTransform3D.Rotation> </RotateTransform3D> ``` It rotates around the scene's Z axis. For this particular X rotation I've worked out what I need is: ``` <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D Axis="0,1,1" Angle="45"/> </RotateTransform3D.Rotation> </RotateTransform3D> ``` But here my maths fails me. Could anyone tell me how to work this out for an arbitrary rotation "A" (and "B" if you would like to)?

Original source