Orient function in RhinoCommon

Hi,

I was wondering if there is a function in Rhino Common for C# that is similar to Orient

I want to able to orient a polylinecurve such that one of the lines in the polyline curve is sitting flush with the x-axis as shown on the photos.

I have looked at the RhinoCommen APi, and I couldn’t find the function anywhere. Is there an Orient function in rhino common that i haven’t been able to find? Or is there an Alternative function that achieves the same goal?

Original PolylineCurve


Desired Result

Hi Jesper

You can see how Mcneel does that in rhinoscripsyntax.OrientObject()

( Here the files are in:
C:\Users\Pc\AppData\Roaming\McNeel\Rhinoceros\5.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rhinoscript )

HTH, regards

Hi Emilio,

Thanks for your response, i’m looking into your suggestion right now.
I have found the OrientObject function in the Object.py file, however it seems rather tedious to translate into C# code. Is there any native RhinoCommon methods to achieve the goal?

Best regards,
Jesper

It’s the “ChangeBasis” transform:

GeometryBase G; // your geometry; you can call Transform from any GeometryBase type.
Plane plane0;
Plane plane1;

Rhino.Geometry.Transform orient = Rhino.Geometry.Transform.ChangeBasis(plane0, plane1);

G.Transform(orient); // will reorient your object

I believe that the method is mislabeled in Rhinocommon: it says that plane0 should represent the plane that describes your geometry’s current coordinate system, and that plane1 should represent the target coordinatte system, but these appear to be reversed, so plane0 should be the target plane, and plane1 the current. However, it works fine. I’ve attached a simple grasshopper definition with the code implemented in a C# component.

orient.gh (6.7 KB)

OK, that is Python code, but it’s based on RhinoCommon methods ( although written in Python ), I think that code might show a way to solve the problem in RhinoCommon.

( I know no single method to do that … )

As far as I understand, for the 3-Point case basically the reference points picked by the user are used to build 2 planes,
and then these planes are used to transform the objects by the Transform.PlaneToPlane() method.

For 2-Points the input points are used to build 2 vectors, and then
Transform.Translation(), Transform.Scale() and Transform.Rotation() are used.

Or else you might use RhinoApp.RunScript() to call the Orient command.

Makes sense ? :slight_smile:

@Jesper_Ravn-Nielsen, @dave_stasiuk, @emilio:

To transform something form one coordinate system to another, create a transform object using Transform.ChangeBasis.

For example, if you need convert a 3-D point from world x-y coordinates to Windows screen coordinates, you would use a change of basis transformation.

If you had a point in Rhino’s camera coordinate system and you need it translated into world x-y coordinates, you would use a change of basis transformation.

If you had a point in 3-D point from world x-y coordinates and you wanted to report to the user what that point was in construction plane coordinates (of the active viewport), you would use a change of basis transformation.

If you wanted to orient an object oriented from one plane to another plane, you would not use a change of basis transformation. Rather, you use a plane-to-plane transformation using Transform.PlaneToPlane. This is because you are not looking to convert from one coordinate system to another. You are simply looking orient in the same coordinate system.

Hope this helps.

– Dale

3 Likes

That’s the kind of explanation that should go into the code documentation as well as the help-files. :slight_smile:

// Rolf

4 Likes

… putting the whole explanation in the documentation for both Transform.ChangeBasis and Transform.PlaneToPlane. :slight_smile:

1 Like

@dale @emilio @dave_stasiuk

Thank you all for your help.

I ended up using @emilio’s original suggestion of looking at the python file, and I converted the method to C# by using the methods already in RhinoCommon for C#.

It turned out that it wasn’t a big hassle after all, apart from the function calls v0.Unitize() and v1.Unitize(), i tried to look up what they did but had not luck, but as far as I have tested, the C# verion doesn’t need to unitize v0 and v1.

    private PolylineCurve Orient(PolylineCurve Contour, Point3d FromPoint0, Point3d FromPoint1)
    {
        // Choose Target points. 
        // I use two points along the X-axis 
        // since I wanted my shape to align with the X-axis
        Point3d ToPoint0 = new Point3d(0, 0, 0);
        Point3d ToPoint1 = new Point3d(1, 0, 0);


        Transform xform_move = Transform.Translation(ToPoint0 - FromPoint0);
        Transform xform_scale = Transform.Identity;
        var v0 = FromPoint1 - FromPoint0;
        var v1 = ToPoint1 - ToPoint0;
        Transform xform_rotate = Transform.Rotation(v0, v1, FromPoint0);
        Transform xform_final = xform_move * xform_scale * xform_rotate;
        Contour.Transform(xform_final);
        
        return Contour;
    }

Hi Jesper

Here it is:

http://developer.rhino3d.com/api/RhinoCommonWin/html/M_Rhino_Geometry_Vector3d_Unitize.htm

The purpose is unitizing a vector, that is making its length = 1.0

In your code Transform.Rotation() might work fine for any vector length …

Regards