How does CPlane command perp to Curve calculate orientation for XY axis?

Trying to emulate it in python.

for most cases
zdirection = tangent
xdirection = tangent x worldZ
… some special cases
ydirection = zdirection x xdirection

x crossProduct

cross product - wikipedia

and here Rhino - 1 Vector Mathematics

Hi @Asterisk,

This is probably close:

#! python 3
import Rhino
import scriptcontext as sc

def ConstructionPlaneToCurve():
    obj_type = Rhino.DocObjects.ObjectType.Curve
    rc, obj_ref = Rhino.Input.RhinoGet.GetOneObject("Select curve to orient CPlane perpendicular to", False, obj_type)
    if rc != Rhino.Commands.Result.Success: 
        return

    curve = obj_ref.Curve()
    if curve is None: 
        return

    gp = Rhino.Input.Custom.GetPoint()
    gp.SetCommandPrompt("CPlane origin or press Enter to accept default")
    gp.Constrain(curve, False)
    gp.Get();
    if gp.CommandResult() != Rhino.Commands.Result.Success: 
        return

    view = gp.View()
    if not view:
        return

    pt = gp.Point()
    rc, t = curve.ClosestPoint(pt)
    if rc == True and Rhino.RhinoMath.IsValidDouble(t):
        plane = Rhino.Geometry.Plane()
        origin = curve.PointAt(t)
        tangent = curve.TangentAt(t)
        xaxis = Rhino.Geometry.Vector3d.CrossProduct(Rhino.Geometry.Vector3d.ZAxis, tangent)
        if xaxis.Unitize():
            yaxis =  Rhino.Geometry.Vector3d.CrossProduct(tangent, xaxis)
            plane = Rhino.Geometry.Plane(origin, xaxis, yaxis)
        else:
            plane = Rhino.Geometry.Plane(origin, Rhino.Geometry.Vector3d.XAxis, Rhino.Geometry.Vector3d.YAxis)

        cp = view.ActiveViewport.GetConstructionPlane()
        cp.Plane = plane
        view.ActiveViewport.PushConstructionPlane(cp)
        view.Redraw()

if __name__ == "__main__":
    ConstructionPlaneToCurve()    

ConstructionPlaneToCurve.py (1.5 KB)

– Dale