Need Help Joining Corner Lines with Gaps in Dynamo (Fillet or Extend)

havent tried and not in dyn, but probably alphashape could work, have sometimes work for me, in these situations

1 Like

hi
Edit 2: Concave part

There’s a way around this (by drawing a spline around the part) and adapting the script; I’m not good enough at algorithms to write this one.


cordially
christian.stan

2 Likes

Hi, if any kind soul wants to help me correct my algorithm, you’re welcome.

The first three lines are in order, then something is a bit messy.

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

lin=IN[0]
fl=lin[0]
lin.pop(0)
stockorder=[]
stockorder.append(fl)
pext=fl.EndPoint
def reol(p,li,st):
    a=[l.ClosestPointTo(p) for l in li]
    b=[Geometry.DistanceTo(a,p) for a in a]
    i=b.index(min(b))
    st.append(li[i])
    c=li[i].ParameterAtPoint(a[i])
    li.pop(i)
    if c==0:
        return st[-1].PointAtParameter(1)
    else:
        return st[-1].PointAtParameter(0)

while len(lin)>1:
    reol(reol(pext,lin,stockorder),lin,stockorder)

OUT = stockorder,lin

I start from a random line that I put in stock, I look at the point closest to the next line, I erase it from the stock then start again from the opposite point then from near to near in order to exhaust the quota of starting lines

Thank you.
Sincerely,
Christian.stan

1 Like

I modified the script to make it work (concave or convex). There will likely be times when it won’t work.

Python script 1
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

lin=IN[0]
fl=lin[0]
lin.pop(0)
stockorder=[]
stockorder.append(fl)
pext=fl.EndPoint
def reol(p,li,st):
    a=[l.ClosestPointTo(p) for l in li]
    b=[Geometry.DistanceTo(a,p) for a in a]
    i=b.index(min(b))
    st.append(li[i])
    c=li[i].ParameterAtPoint(a[i])
    li.pop(i)
    if c==0:
        return st[-1].PointAtParameter(1)
    else:
        return st[-1].PointAtParameter(0)
b1=reol(pext,lin,stockorder)
boucles=[]
boucles.append(b1)
while len(lin)>0:
    boucles.append(reol(boucles[-1],lin,stockorder))
stockorder.append(stockorder[0])
OUT = stockorder
Python Script 2
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
lin=IN[0]
def pint(l1,l2):
    if round((l1.EndPoint.X - l1.StartPoint.X),3)==0:
        c=round((l2.EndPoint.Y - l2.StartPoint.Y),5)/round((l2.EndPoint.X - l2.StartPoint.X),5)
        d=l2.StartPoint.Y-c*l2.StartPoint.X
        return Point.ByCoordinates(l1.StartPoint.X,c*(l1.StartPoint.X)+d,l1.StartPoint.Z)
    if round((l2.EndPoint.X - l2.StartPoint.X),3)==0:
        a=round((l1.EndPoint.Y - l1.StartPoint.Y),5)/round((l1.EndPoint.X - l1.StartPoint.X),5)
        b=l1.StartPoint.Y-a*l1.StartPoint.X
        return Point.ByCoordinates(l2.StartPoint.X,a*(l2.StartPoint.X)+b,l2.StartPoint.Z)
    else:
        a=round((l1.EndPoint.Y - l1.StartPoint.Y),5)/round((l1.EndPoint.X - l1.StartPoint.X),5)
        b=l1.StartPoint.Y-a*l1.StartPoint.X
        c=round((l2.EndPoint.Y - l2.StartPoint.Y),5)/round((l2.EndPoint.X - l2.StartPoint.X),5)
        d=l2.StartPoint.Y-c*l2.StartPoint.X
        return Point.ByCoordinates((d-b)/(a-c),a*(d-b)/(a-c)+b,l1.StartPoint.Z)


OUT = [pint(lin[i+1],lin[i]) for i in range(0,len(lin)-1)]

(A new post for greater clarity.)
Python scripts are certainly improvable (everyone does it with their own skills).

Sincerely,
christian.stan

Thank you so much for your help! I really appreciate that you took the time to assist me.

I tried running the script you shared, but I’m getting an error in the script 2 and I’m not quite sure why. I’ll attach a screenshot of the error here in case you can help me figure out what might be going wrong.

Thanks again for your time and effort!

1 Like

Hi, did you copy and paste the code or did you retype it?

It’s weird, I deleted the division by zero thing for a line parallel to the y-axis. Do you have two successive lines in the same extension?

Send me a screenshot of your “pseudo zone.”

i tried it with this areas


edit:
I’m on the weekend in 5 minutes. I’ll check on Tuesday.
Have a good weekend everyone.

for this situation:


if i delete line //

Sincerely,
christian.stan

1 Like

Hi,

a test using Equations of Lines

# Load the Python Standard and DesignScript Libraries
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *


def compute_intersection(lineA, lineB):
    """Compute intersection point of 2 lines"""
    x1, y1 = lineA.StartPoint.X, lineA.StartPoint.Y
    x2, y2 = lineA.EndPoint.X, lineA.EndPoint.Y
    x3, y3 = lineB.StartPoint.X, lineB.StartPoint.Y
    x4, y4 = lineB.EndPoint.X, lineB.EndPoint.Y

    denom = (x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)
    print(denom)
    if abs(denom) < 0.001:
        return None, None  # lines are parallel

    px = ((x1*y2 - y1*x2)*(x3 - x4) - (x1 - x2)*(x3*y4 - y3*x4)) / denom
    py = ((x1*y2 - y1*x2)*(y3 - y4) - (y1 - y2)*(x3*y4 - y3*x4)) / denom
    return px, py

def ordered_curves(lines):
    ordered_curves = [lines.pop(0)]
    n = 1
    while lines and n < 200:
        n += 1
        lines.sort(key = lambda x : ordered_curves[-1].DistanceTo(x))
        ordered_curves.append(lines.pop(0))
    return ordered_curves

lines = IN[0]
perimeter_points = []
lines_ordered = ordered_curves(lines)
lines_ordered.append(lines_ordered[0])
for idx, lineB in enumerate(lines_ordered):
    if idx > 0:
        lineA = lines_ordered[idx - 1]
        x, y = compute_intersection(lineA, lineB)
        if x is None:
            perimeter_points.extend([lineA.StartPoint, lineA.EndPoint, lineB.StartPoint, lineB.EndPoint])
        else:
            perimeter_points.append(Point.ByCoordinates(x, y, lineB.StartPoint.Z))

polygon = Polygon.ByPoints(perimeter_points)

OUT = polygon, perimeter_points
2 Likes

Hello and thank you for the code, better thought out and done, congratulations.
Sincerely
christian.stan

2 Likes

Hi, to avoid manual deletion, here’s PythonScript1, modified and nodes added (I had a problem with the pop and range methods).


Python script1

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

lin=IN[0]
fl=lin[0]
lin.pop(0)
stockorder=[]
stockorder.append(fl)
pext=fl.EndPoint
def reol(p,li,st):
    a=[l.ClosestPointTo(p) for l in li]
    b=[Geometry.DistanceTo(a,p) for a in a]
    i=b.index(min(b))
    st.append(li[i])
    c=li[i].ParameterAtPoint(a[i])
    li.pop(i)
    if c==0:
        return st[-1].PointAtParameter(1)
    else:
        return st[-1].PointAtParameter(0)
b1=reol(pext,lin,stockorder)
boucles=[]
boucles.append(b1)
while len(lin)>0:
    boucles.append(reol(boucles[-1],lin,stockorder))
stockorder.append(stockorder[0])



idx=[i for i in range(len(stockorder)-1) if round(abs(Vector.AngleAboutAxis(stockorder[i].Direction,stockorder[i+1].Direction,Vector.ByCoordinates(0,0,1))),0)==0 or round(abs(Vector.AngleAboutAxis(stockorder[i].Direction,stockorder[i+1].Direction,Vector.ByCoordinates(0,0,1))),0)==180 ]

OUT =stockorder,idx
Python script2
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
lin=IN[0]
def pint(l1,l2):
    if round((l1.EndPoint.X - l1.StartPoint.X),3)==0:
        c=round((l2.EndPoint.Y - l2.StartPoint.Y),5)/round((l2.EndPoint.X - l2.StartPoint.X),5)
        d=l2.StartPoint.Y-c*l2.StartPoint.X
        return Point.ByCoordinates(l1.StartPoint.X,c*(l1.StartPoint.X)+d,l1.StartPoint.Z)
    if round((l2.EndPoint.X - l2.StartPoint.X),3)==0:
        a=round((l1.EndPoint.Y - l1.StartPoint.Y),5)/round((l1.EndPoint.X - l1.StartPoint.X),5)
        b=l1.StartPoint.Y-a*l1.StartPoint.X
        return Point.ByCoordinates(l2.StartPoint.X,a*(l2.StartPoint.X)+b,l2.StartPoint.Z)
    else:
        a=round((l1.EndPoint.Y - l1.StartPoint.Y),5)/round((l1.EndPoint.X - l1.StartPoint.X),5)
        b=l1.StartPoint.Y-a*l1.StartPoint.X
        c=round((l2.EndPoint.Y - l2.StartPoint.Y),5)/round((l2.EndPoint.X - l2.StartPoint.X),5)
        d=l2.StartPoint.Y-c*l2.StartPoint.X
        return Point.ByCoordinates((d-b)/(a-c),a*(d-b)/(a-c)+b,l1.StartPoint.Z)


OUT = [pint(lin[i+1],lin[i]) for i in range(0,len(lin)-1)]

Sincerely,
christian.stan

1 Like