RhinoCommon Transform.ChangeBasis VS Transform.PlaneToPlane

Hello all,

I am just confused about the difference between the Transform.ChangePlane vs the Transform.PlaneToPlane.

Under the hood, this is what we have:

        //
        // Summary:
        //     Computes a change of basis transformation. A basis change is essentially a remapping
        //     of geometry from one coordinate system to another.
        //
        // Parameters:
        //   plane0:
        //     Coordinate system in which the geometry is currently described.
        //
        //   plane1:
        //     Target coordinate system in which we want the geometry to be described.
        //
        // Returns:
        //     A transformation matrix which orients geometry from one coordinate system to
        //     another on success. Transform.Unset on failure.
        public static Transform ChangeBasis(Plane plane0, Plane plane1)
        {
            Transform xf = Identity;
            if (!UnsafeNativeMethods.ON_Xform_PlaneToPlane(ref xf, ref plane0, ref plane1, rotation: false))
            {
                return Unset;
            }

            return xf;
        }

        //
        // Summary:
        //     Create a rotation transformation that orients plane0 to plane1. If you want to
        //     orient objects from one plane to another, use this form of transformation.
        //
        // Parameters:
        //   plane0:
        //     The plane to orient from.
        //
        //   plane1:
        //     the plane to orient to.
        //
        // Returns:
        //     The translation transformation if successful, Transform.Unset on failure.
        public static Transform PlaneToPlane(Plane plane0, Plane plane1)
        {
            Transform xf = Identity;
            UnsafeNativeMethods.ON_Xform_PlaneToPlane(ref xf, ref plane0, ref plane1, rotation: true);
            return xf;
        }

Both are calling the same native method, with the difference of the rotation being true or false. So I did the following simple code:

                    // Test:
                    Plane ptest = new Plane(
                        new Point3d(50, 50, 50),
                        //Point3d.Origin,
                        new Vector3d(StaticExtension.random.NextDouble(), StaticExtension.random.NextDouble(), StaticExtension.random.NextDouble()));

                    Transform planetoplane = Transform.PlaneToPlane(Plane.WorldXY, ptest);
                    Transform changebasis = Transform.ChangeBasis(ptest, Plane.WorldXY);

                    Point3d p_planetoplane = new Point3d(StaticExtension.random.NextDouble(), StaticExtension.random.NextDouble(), StaticExtension.random.NextDouble());
                    Point3d p_changebasis = p_planetoplane;

                    p_planetoplane.Transform(planetoplane);
                    p_changebasis.Transform(changebasis);

This is what I see in the debug window:


If you can’t see, note:
1- The Transform objects returned have the same values in the matrix. THE SAME. Even planetoplane == changebasis.
2- Well, then obviously the point transformed results are the same…

Is this really the expected behaviour? Is this a special case of some sort?

The description of the methods is ultra confusing, specially because BOTH versions have from/to, and they return the same matrix but in one case my ptest is the from and in the other it is the to.

+++++
From my tests, say you have something like a planar curve that you draw programatically on the WorldXY so that it is easier, then you want to orient it to at a given plane targetplane.

In this case, you may either - they are the same transformation
Transform.PlaneToPlane(Plane.WorldXY, targetPlane) - This one makes sense because the curve is on the WorldXY and you want it to be in the targetPlane. From/To are ok.
Transform.ChangeBasis(targetPlane, Plane.WorldXY) - Could you please help me understand what is going from the targetPlane to the WorldXY in this case?

Thanks!

Ha ! In encountered the ‘reversed’ behaviour of ChangeBasis a few days ago and was also confused to the point i thought this may be a bug… but I missed PlaneToPlane and this enlightens the difference.

If you have an object in p0 “coordinate system” and want to view it in p1 “coordinate system”, you are actually doing a PlaneToPlane of this object from p1 to p0, which explains why those transforms are inverse of each other.

Hi @magicteddy ,

Thanks for the help. Perhaps my mind is simply stupid, but I still don’t get it - specialyl what is the use of 2 functions that have the same name of their parameters and that return the same value - only the order of the parameters is the same.
That is why I asked if I am not looking at the full picture (special case).
Even if this is not a bug in the code, I truly believe that the documentation is deficient. As you said, you were also confused and I think I even saw a post from the creator of Grasshopper where he also says he is confused.

There has to be a way to make this less confusing, specially as this is such a basic transformation that we use all the time.

Have a good sunday!

1 Like

Hi @dale,

Thank you so much. I feel very stupid, to be honest. I have already had this issue in the past, and I had seen this very same answer of yours. But, I’m sure this already happened to you: I just forgot about it.

I feel that regardless of all this, the description of the documentation could be improved - both for the OpenNurbs and the RhinoCommon.

Thanks a lot.

1 Like