views:

1331

answers:

2

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:

alt text

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 X (and Y if you would like to) rotation?

+1  A: 

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;
    }
Groky