Rotate a 3D object around its center and own axes in WPF 3D

In WPF 3D, various transformations could be applied to an object. One particular problem that I occasionally run into is when I want to apply a rotation transformation to an object and rotate it around its own center and axes.

The way I do it is as follows. First I apply 3 identity RotateTransform3D‘s to the object with AxisAngleRotation3D‘s objects underneath: one for the X axis, one for the Y axis and one for the Z axis. Then whenever I want to rotate the object around a certain axis, I obtain the corresponding RotateTransform3D object, set its center according to the (possibly) translated center of the object, and apply the rotation angle to the underlying AxisAngleRotation3D object. Some code will make this more clear.

First apply the 3 identity transforms to the object:

Transform3DGroup transforms = new Transform3DGroup();
// Rotation around X
transforms.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 0)));
// Rotation around Y 
transforms.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0)));
// Rotation around Z
transforms.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), 0))); 
// Translate transform (if required)
transforms.Children.Add(new TranslateTransform3D());
MyObject.Transform = transforms;

Let’s say the function SetRotation is to be used for setting the rotation of the object. It will work as follows:

public void SetRotation(double amountX, double amountY, double amountZ)
{
	// Suppose we have a function that gives us all the transforms
	// applied to this object
	Transform3DGroup transfomrs = GetTransforms();
	TranslateTransform3D translation = transforms.Children[3];
	// Suppose GetCenter() obtains the center point of an object
	// in Point3D format
	Point3D translatedCenter = translation.Transform(GetCenter());

	RotateTransform3D rotX = (transforms.Children[0] as RotateTransform3D);
	RotateTransform3D rotY = (transforms.Children[1] as RotateTransform3D);
	RotateTransform3D rotZ = (transforms.Children[2] as RotateTransform3D);

	// Set the center point of transformation to the translated center of the object
	rotX.CenterX = rotY.CenterX = rotZ.CenterX = translatedCenter.X;
	rotX.CenterY = rotY.CenterY = rotZ.CenterY = translatedCenter.Y;
	rotX.CenterZ = rotY.CenterZ = rotZ.CenterZ = translatedCenter.Z;

	// Apply the angle amounts
	(rotX.Rotation as AxisAngleRotation3D).Angle = amountX;
	(rotY.Rotation as AxisAngleRotation3D).Angle = amountY;
	(rotZ.Rotation as AxisAngleRotation3D).Angle = amountZ;
}

4 comments

Skip to comment form

    • Eric on April 6, 2017 at 3:26 AM
    • Reply

    Hello,

    thanks a lot for the info!

    when I am rotating my cube (with 6 parallel sides of Course but height != depth !=width) the Rotation around Y (Rotation lying on ground) works perfect, but when I rotate around Z (Up vector is 0,1,0), the Rotation Looks strange, works but after it the height is still the base height before, the width is still the base width as before and not switched those two…

    Any idea what’s wrong?

    Thanks a lot!
    Eric

    1. What do you mean “strange”? I’m not sure I understand what you mean by “after it the height is still the base height before, the width is still the base width as before and not switched those two…”. Could you post some images?

    • Robert Morgan on August 28, 2018 at 7:57 PM
    • Reply

    I tried the example and noticed that my Z doesn’t transform like the others. X and Y seem to interact with the other perfectly but Z gives me a problem. No matter which way I move X or Y, Z is using always using my world coordinates which is point up.

  1. It’s all very clear!
    But how do you get all the transform of the object and the center point? (the methods that you supposed in the comments).
    Can you give me a hint?

    thank you very much

Leave a Reply

Your email address will not be published.