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
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
Author
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?
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.
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