Average between two planes

Hi does anyone know a way to create a plane based on the average of two other planes?

I’m look for a way to build circles along a curve that have perfect angle between two segments.

Thanks!
Average.gh (7.3 KB)

Pufferfish plugin has tween planes.

2 Likes

You can do it natively by averaging vectors (average component)

1 Like

Extract the z-axis vectors of both planes and add them together. Since the axis vectors have unit length this will give you the average direction. You can then create a new plane using the same origin point and the new averages z-axis. This will result in potentially different x and y directions, but for circles maybe that doesn’t matter.

1 Like

or just create a curve and take perpendicular frames at the kinks…
planes2.gh (9.7 KB)

1 Like

Careful with this - averaging the XYZ vectors of two planes does not give their average plane!


averagePlane.gh (15.6 KB)

You can always get from one plane to another with a translation and a rotation about a single axis. This script uses Rhino’s quaternion class to find that rotation axis. Note how when you compare the Y axis of the average plane found this way with the Y axes of the 2 input planes it forms an equal angle with each of them, whereas this is not the case for the plane you get from just averaging the basis vectors separately.

4 Likes

Thanks guys!!

Not necessarily. Like @DanielPiker suggests you will want to use Quaternions. Pufferfish tween planes has Quaternions built in.

One main issue with simply averaging is Gimbal lock (try averaging two planes which x or y axis directly oppose each other, you will see the plane will just flip when it goes past halfway).

Check this video for some interesting test with Quaternions using drones.

1 Like

Thanks guys for all the comments, Puffer Fish worked great!
I also solved the next step of my project from your example of deconstructing angles from the planes!

2 Likes

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