Skip to content

Instantly share code, notes, and snippets.

@Aeium

Aeium/shapecutter.py

Last active Jun 18, 2019
Embed
What would you like to do?
Functions to assist using shapely and ezdzf
# Draws shape to modelspace
def drawShape(shape,msp):
if(shape.type == 'Polygon'):
drawLineRing(shape.exterior,msp)
for linering in shape.interiors:
#print(lineRing.type)
drawLineRing(linering,msp)
#smooth = smoothPoly(linering)
#drawLineRing(smooth.exterior,msp)
if(shape.type == 'MultiPolygon'):
for geom in web.geoms:
drawLineRing(geom.exterior,msp)
for linering in geom.interiors:
#print(lineRing.type)
drawLineRing(linering,msp)
#smooth = smoothPoly(linering)
#drawLineRing(smooth.exterior,msp)
def drawLineRing(lineRing, msp):
#polyline= dxf.polyline()
#polyline.add_vertex([xArr[-1],yArr[-1]])
xArr,yArr = lineRing.xy
msp.add_lwpolyline(zip(xArr,yArr))
def commonPoints(tri1, tri2):
tri1Set = set(tri1)
tri2Set = set(tri2)
if( len(tri1Set & tri2Set) > 1):
return True
else:
return False
def getDist(point1, point2):
return math.sqrt(math.pow(point1[0]-point2[0],2)+math.pow(point1[1]-point2[1],2))
def getCircumcenter(triangle, points):
triPoints = [points[triangle[0]],points[triangle[1]],points[triangle[2]]]
#print(triPoints)
d1 = getDist(triPoints[0],triPoints[1])
d2 = getDist(triPoints[1],triPoints[2])
dist = max(d1,d2)
c0 = Point(triPoints[0][0],triPoints[0][1]).buffer(dist).boundary
c1 = Point(triPoints[1][0],triPoints[1][1]).buffer(dist).boundary
c2 = Point(triPoints[2][0],triPoints[2][1]).buffer(dist).boundary
line1 = shapely.geometry.LineString(c0.intersection(c1))
line2 = shapely.geometry.LineString(c1.intersection(c2))
return line1.intersection(line2)
def towards4(x,y,angle,distance):
x = x + math.sin(angle) * distance
y = y + math.cos(angle) * distance
return [x,y]
def towards3(start,angle,distance):
x = start[0] + math.sin(angle) * distance
y = start[1] + math.cos(angle) * distance
return [x,y]
def findDistance(point1,point2):
pointDx = point1[0] - point2[0]
pointDy = point1[1] - point2[1]
return math.hypot(pointDx,pointDy)
def towardsPoint(start,point,distance):
totalDist = findDistance(start,point)
frac = distance / totalDist
x = start[0] * (1-frac) + point[0] * frac
y = start[1] * (1-frac) + point[1] * frac
return [x,y]
def smoothPoly(polygon, res = 100):
reach = max(polygon.bounds) - min(polygon.bounds)
center = polygon.centroid
samplePoints = []
sampleDists = np.zeros((res))
blurPoints = []
#print(center.type)
#print(center)
#print(center.x)
#print(center.y)
for i in range(res):
angle = i/res * 2 * math.pi
farPoint = towards4(center.x,center.y, angle, reach)
line = shapely.geometry.LineString([center,farPoint])
sample = line.intersection(polygon)
samplePoints.append(sample)
sampleDists[i] = (getDist([center.x,center.y],[sample.x,sample.y]))
blurDists = gaussian_filter1d(sampleDists,5,mode='wrap')
for i in range(res):
angle = i/res * 2 * math.pi
blurPoint = towards4(center.x,center.y,angle,blurDists[i])
blurPoints.append(blurPoint)
return shapely.geometry.Polygon(blurPoints)
if __name__ == "__main__":
print('main')
import ezdxf
import shapely
import math
from shapely import geometry
dwg = ezdxf.new('AC1015')
modelspace = dwg.modelspace()
preview = ezdxf.new('AC1015')
pModelspace = preview.modelspace()
positiveSpace = geometry.Polygon([[0,0],[0,30],[30,30],[30,0]])
negativeSpace = geometry.Polygon([[2,2],[2,28],[28,28],[28,2]])
#drawShape(positiveSpace,modelspace)
drawShape(positiveSpace,pModelspace)
#""" # uncomment for other demo
for i in range(3):
cut = geometry.Point(25,25).buffer(8 * (1+i))
cut = cut.intersection(negativeSpace)
drawShape(cut,pModelspace) # stack shapes on preview
# seperate layers in real cut
layerNegative = shapely.affinity.translate(cut,xoff=30*i)
drawShape(layerNegative,modelspace)
layerPositive = shapely.affinity.translate(positiveSpace,xoff=30*i)
drawShape(layerPositive,modelspace)
# """ # uncomment for other demo
""" # comment for fancier demo
for i in range(5):
circs = []
for j in range(290):
xPos = 30/2
yPos = 30/2
angle = (1 + 5 ** 0.5) / 2 * math.pi * j # golden ratio to get angles
point = towards4(xPos,yPos,angle, math.sqrt(j))
circs.append(geometry.Point(point[0],point[1]).buffer(.25 * (1+i)))
#circ1 = geometry.Point(25,25).buffer(3 * (1+i))
#circ2 = geometry.Point(20,9).buffer(3 * (1+i))
#circ3 = geometry.Point(7,12).buffer(3 * (1+i))
#cut = ops.cascaded_union([circ1,circ2,circ3])
cut = ops.cascaded_union(circs)
cut = cut.intersection(negativeSpace)
drawShape(cut,pModelspace) # stack shapes on preview
# seperate layers in real cut
layerNegative = shapely.affinity.translate(cut,xoff=30*i)
drawShape(layerNegative,modelspace)
layerPositive = shapely.affinity.translate(positiveSpace,xoff=30*i)
drawShape(layerPositive,modelspace)
""" # comment for fancier demo
dwg.saveas('layers.dxf')
preview.saveas('preview.dxf')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment