Finding the average curve between two curves

Hi,
a trial by calculating an approximate curve (with scipy), then a search along the perpendiculars for points equidistant from the input curves.

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import numpy as np
from scipy.interpolate import interp1d
from scipy.ndimage import uniform_filter1d

curveA, curveB = IN[0]
plane = Plane.ByOriginNormal(Point.ByCoordinates(0, 0 , 0), Vector.ByCoordinates(0,0,1))
# ensure curves are Z zero
curveA = curveA.PullOntoPlane(plane)
curveB = curveB.PullOntoPlane(plane)
ptCurveA = [curveA.PointAtParameter(n) for n in np.linspace(0, 1, num=500)]
ptCurveB = [curveB.PointAtParameter(n) for n in np.linspace(0, 1, num=500)]
# merge, flatten points and keeping order
pts  = [pt for pairPts in zip(ptCurveA,ptCurveB) for pt in pairPts]

data = [[int(p.X), int(p.Y)] for p in pts]
x, y = [i for i in zip(*data)]
# compute the arithmetic average with scipy.ndimage.uniform_filter1d
y_smooth = uniform_filter1d(y,size=5, mode='wrap')
x_smooth = uniform_filter1d(x,size=5, mode='wrap')

rays = []
mid_Pts = []
ray_length = 6000 # example in millimeter
# compute an approximative average curve 
pts_uniform = [Point.ByCoordinates(x, y , 0) for x, y in zip(x_smooth, y_smooth)]
pts_uniform_iter = iter(pts_uniform[:])
dsPoints = [Point.ByCoordinates((pta.X + ptb.X) / 2, (pta.Y + ptb.Y) / 2, 0) for pta, ptb in zip(pts_uniform_iter, pts_uniform_iter)]
# remove extra points
dsPoints = dsPoints[1:-1]
aprox_average_curve = PolyCurve.ByPoints(dsPoints, False)
# with this curve compute an new average curve by normal curve intersection (ray) and compute middle points 
for n in np.linspace(0, 1, num=100):
    normal = aprox_average_curve.NormalAtParameter(n)
    pt = aprox_average_curve.PointAtParameter(n)
    ray_line = Line.ByStartPointDirectionLength(pt, normal, ray_length) 
    ray_line = ray_line.Translate(normal.Reverse(), ray_length / 2)
    if ray_line.DoesIntersect(curveA) and ray_line.DoesIntersect(curveB):
        ptInterA = ray_line.Intersect(curveA)[0]
        ptInterB = ray_line.Intersect(curveB)[0]
        midpt = Point.ByCoordinates((ptInterA.X + ptInterB.X) / 2, (ptInterA.Y + ptInterB.Y) / 2, 0)
        rays.append(ray_line)
        mid_Pts.append(midpt)

OUT = rays, PolyCurve.ByPoints(mid_Pts, False)
6 Likes