Average between two planes

Thank you for posting this Example! I was completely unfamiliar with Quaternions before this! For the sake of a learning exercise, I took a shot at converting your C# component to python. While I still am WAY out of my depth in regards to quaternions… What I ended up learning was how to use clr.StrongBox (or clr.Reference…both of which don’t autocomplete and took some digging to find!), to mimic C# out parameters! Reference mentioned here: (thanks @AndersDeleuran and @piac for posting that info!)

For the sake of completing the learning exercise, I thought I would share my results. Below is an un-optimized python implementation of your c# component. (Rhino 6, SDK mode). Please note that this was just a learning exercise and may not follow python/ironpython best practices. The one thing I got stuck on was recasting(?) the axis vector from a StrongBox Vector3d, back to a “regular” Vector3d.
"expected Vector3d, got StrongBox[Vector3d] in line 51
(Workaround is noted in code.)

from ghpythonlib.componentbase import executingcomponent as component
import Grasshopper, GhPython
import System
import Rhino
import clr
import math

class Tween2Planes(component):
    
    def RunScript(self, P1, P2, t):
        # always declare output variables
        a = None
        b = None
        c = None

        #Quaternion Rotation
        q = Rhino.Geometry.Quaternion.Rotation(P1, P2)
        
        # using StrongBox/Reference to mimic C# out parameters
        angle = clr.Reference[System.Double]()
        axis = clr.Reference[Rhino.Geometry.Vector3d]()
        
        # this returns the angle and axis, in C# it would be q.GetRotation(out angle, out axis);
        q.GetRotation(angle, axis)

        #when using axis, was getting error "expected Vector3d, got StrongBox[Vector3d] in line 51
        #workaround was to make new vector.  I didn't know how to "recast?" back as non-strongbox vector?
        axis2 = Rhino.Geometry.Vector3d(axis.X, axis.Y, axis.Z)
                
        OutputPlane = P1
        angle = float(angle) - 2 * math.pi if float(angle) > math.pi else float(angle)
        OutputPlane.Rotate(t * angle, axis2, OutputPlane.Origin)
        Translation = Rhino.Geometry.Vector3d(P2.Origin - P1.Origin)
        OutputPlane.Translate(Translation * t)
        
        #set values for output params
        a = OutputPlane
        b = angle
        c = axis2
                
        # return outputs:
        return a, b, c

I overly commented the code in the attached file for those that may be interested.
Quaternion_strongbox_GHpy.gh (11.1 KB)

Rhino ver: (6.9.18261.20431, 09/18/2018)

2 Likes