Get the rotation of instance object

For some reasons I need to find out if my instance object is rotated and get the angel of rotation along X,Y and Z and get the bounding box of the block based on that.
I’ve searched and founded getaywpichroll , but I couldn’t find how to work with that… can you give me an example please?
is there any better way other than that?

Hi,

Transform.GetYawPitchRoll will only be successful if the Transform is a rotation matrix. I’m guessing that you’re referencing the InstanceXform, but there’s no guarantee that transform will be a rotation. In fact that can be any kind of transformation (scaling, shearing, translation, etc). You can check with Transform.IsRotation if you expect it to be a rotation transformation but I doubt that’s what you’re looking for.

Are you sure you need the rotation? I’m guessing you just want a Box that isn’t world align and wraps the instance object in the same way. You can do that with the Rhino.Geometry.Box by constructing it from the original objects bounding box. Then you can transform it with the InstanceXform and that will give you a box with the same alignment around the instance.

Hope that help!

1 Like

Hi Joshua,

First of all thanks for your reply and your clear explanation.

In fact I have an InstanceObject that contains InstanceObjects inside of it as SubObjects what I need is angel of rotation of the main InstanceObject (specially in Z axis), from the origin, in case of finding the right XYplan to get the bounding box and then length and height out of it…

so what I need is:
1- Angel of rotation in Z , Y and X axis
2- Length width and height of aligned BoundongBox,

and what I thought I could do was:
1- Getting the Rotation of InstanceObject,
2- make a rotated Plane,
3- Get the BoundingBox based on that plan.

so if I’m thinking wrong I would be thankful if you let me know, and if not could you please explain to me how GetYawPitchRoll() works?
thanks a lot.

The method I previously should allow you to get the height, width, and length. The rotation is a different story. A transformation matrix can represent any of several kinds of transformation or combination of them. This makes decomposing them into a series of simpler transformations, like rotations, difficult. Here’s one way you can attempt to get a rotation but it is far from perfect.

Transform t = /*Your transform*/;
t.Affineize();

if(t.IsRigid(/*Your tolerance*/) == TransformRigidType.Rigid)
{
    //Zero out the translation
    t.M03 = 0.0;
    t.M13 = 0.0;
    t.M23 = 0.0;

    t.GetYawPitchRoll(out double yaw, out double pitch, out double roll);
}

Affineize will discard any perspective in the transform by setting the last row to 0, 0, 0, 1. If a transform is rigid it can be broken down into just a rotation and translation. So to make it a pure rotation matrix you discard the last column (the translation portion). From there you can finally extract the rotation. This method will break down if there is any scaling or shearing. For that you’ll need a more complex method of breaking down your transformation matrix. “Decomposing a Matrix into Simple Transformations” on page 320 of Graphics Gems II (if you Google a PDF is available) has an algorithm you can use. There’s also an open source example here. Even this isn’t perfect. If there is any mirroring in the transform you can expect it to fail.

1 Like

Thanks a lot,
I tested your code and it works perfectly,
I also searched more and found this method useful:

        public Dictionary<string,double> GetBlockRotation(InstanceObject block)
        {
            Dictionary<string, double> rotation = new Dictionary<string, double>();

            if (block != null)
            {

            var xform = block.InstanceXform;

            var rotX = Math.Atan2(-xform.M21, xform.M22);
            var rotY = Math.Asin(xform.M20);
            var rotZ = Math.Atan2(xform.M10, xform.M00);
            
            rotation.Add("X",Math.Round(180 / Math.PI * rotX,10));
            rotation.Add("Y",Math.Round(180 / Math.PI * rotY,10));
            rotation.Add("Z",Math.Round(180 / Math.PI * rotZ,10));

            }
            return rotation;
        }

It calculated the degree near the right one, for example if the rotation is 90 it gives you 89.999999999946 , so I had to round it.