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
You can’t perform that action at this time.