Current zaxis rotation

Is there a simple way to get the zaxis rotation?
I guess I want the “get” equivalent of

Geom::Transformation.rotation(Geom::Point3d.new(x,y,z),vector,degreesToRotate)

Something like

rotationDegrees = componentInstance.transformation.zaxis.getDegrees???

I have seen similar questions whose solution says to use

componentInstance.transformation.zaxis.angle_between(Z_AXIS)
or
componentInstance.transformation.rotz

But these both return 0. I have also seen some crazy long math equations that say they will get results that are not entirely accurate.

Any help would be greatly appreciated. Otherwise I will have to modify my component programmatically and then make the user rotate it manually. I also want to use this to rotate other component instances to match the selected entity’s rotation. Doing that manually is not a good option.

componentInstance.transformation.zaxis.angle_between(Z_AXIS).radians

should return the angle [in degrees] - in the local context
if it’s 0 it means it’s not rotated !?

I am not sure what I am doing wrong. I rotate the element -90 degrees. It looks good. But when I make that call, I still get 0.

Here is the sketchup console of what I did…

rotz = Geom::Transformation.rotation(Geom::Point3d.new(0,0,0),Geom::Vector3d.new(0,0,1),-90.degrees)
#Geom::Transformation:0x000001d701d39440
Sketchup.active_model.selection[0].transformation = rotz
#Geom::Transformation:0x000001d701d39440
Sketchup.active_model.selection[0].transformation.zaxis.angle_between(Z_AXIS).radians
0.0

But if I use transformation.xaxis.angle_between(Z_AXIS).radians
then I get 90.0. Which is much closer but still not -90. Unfortunately I get 90 no matter how many degrees I rotate it. So I am sure that is a math thing that is irrelevant to the conversation.

Listen, you are rotating about the Z_AXIS vector, from the X_AXIS vector (which you think of as 0.)

So the test will be the angle between the X_AXIS (0) and the resultant rotation (in the XY plane.)

Try …

rotz = Geom::Transformation.rotation(ORIGIN, Z_AXIS, -90.degrees)
obj = Sketchup.active_model.selection[0]
obj.transformation = rotz
obj.transformation.xaxis.angle_between(X_AXIS).radians

Works except for the negative.

rotz = Geom::Transformation.rotation(ORIGIN, Z_AXIS, -90.degrees)
#Geom::Transformation:0x000001d701d1e230
obj = Sketchup.active_model.selection[0]
#Sketchup::ComponentInstance:0x000001d70194f2d0
obj.transformation = rotz
#Geom::Transformation:0x000001d701d1e230
obj.transformation.xaxis.angle_between(X_AXIS).radians
90.00000000000003

Yes. I see. The issue is the #angle_between method, (besides being limited to 180 degrees,) … we are after all asking for the angle between. So we are getting the correct result.

We need to use another method here.

Turns out that it’s the cross product of the vectors that we need to test.

The cross product, also called the vector product, is an operation on two vectors. The cross product of two vectors produces a third vector which is perpendicular to the plane in which the first two lie.

cross = obj.transformation.xaxis.cross(X_AXIS)

If your direction of rotation is negative, then cross.z is positive.
(Ie, the resultant vector points upward.)

If your direction of rotation is positive, then cross.z is negative.
(Ie, the resultant vector points downward.)

Just an FYI … vector[0] is the same as vector.x, … vector[2] the same as vector.z, etc.

In my example above, I suggested using vector.z as it is better understood than vector[2].


Your test will likely also need to test the condition where the rotation is equal to 0.

1 Like

This code allows you to calculate all the rotational angles from a transformation. This method relies on some other methods, so it can be useful to grab the whole file, but you can of course also look into what individual methods it uses. There is also a shorthand rotz method that only returns the Z rotation.

Regarding radians vs degrees I’d recommend to stick to radians for as long as possible. Generally computers use radians and it is what the Ruby trigonometric methods use. You can convert to degrees, round according to the model unit settings and set the decimal mark (point vs comma) just before you print the value to the user, but internally in your code use radians.

For the record, this method is not part of our Ruby API, but is added by Dynamic Components monkey patching the API classes. This is no longer allowed but this is a very old extension. In addition to not being formal API, this method also formats the angle in degrees and rounds the value to an integer, making it very unreliable for anything other than printing the value to the UI.

You can disable shipped extensions in the Extension Manager to get a clean dev environment without these unofficial methods.

2 Likes