Last active
June 18, 2019 23:38
-
-
Save nathan-sixnines/011f1dece20cd43a87cfd8899bcc8223 to your computer and use it in GitHub Desktop.
Functions to assist using shapely and ezdzf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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