def _hexagons(*, space: float = 0, length: float = 0, height: float = 0) -> LineGroup: baseLine = LineGroup(None) baseLine.addLinesFromCoordinateList( [[0, 0], [sideLength, 0], [ sideLength + math.cos(math.pi / 4) * sideLength, math.cos(math.pi / 4) * sideLength ], [ sideLength * 2 + math.cos(math.pi / 4) * sideLength, math.cos(math.pi / 4) * sideLength ], [2 * (sideLength + math.cos(math.pi / 4) * sideLength), 0]]) fullLine = LineGroup(baseLine) while fullLine.maxX - fullLine.minX < length: baseLine = baseLine.translate(baseLine.maxX - baseLine.minX, 0) fullLine.addLineGroup(baseLine) mirrorLine = LineGroup(fullLine) mirrorLine = mirrorLine.mirror(c.X) mirrorLine = mirrorLine.translate(0, -space) fullLine.addLineGroup(mirrorLine) field = LineGroup(fullLine) while field.maxY - field.minY < height: fullLine = fullLine.translate( 0, fullLine.maxY - fullLine.minY + space) field.addLineGroup(fullLine) return field
def _hexagons(*, space: float=0, length: float=0, height: float=0) -> LineGroup: baseLine = LineGroup(None) baseLine.addLinesFromCoordinateList([[0,0], [sideLength, 0], [sideLength+math.cos(math.pi/4)*sideLength, math.cos(math.pi/4)*sideLength], [sideLength*2+math.cos(math.pi/4)*sideLength, math.cos(math.pi/4)*sideLength], [2*(sideLength+math.cos(math.pi/4)*sideLength), 0]]) fullLine = LineGroup(baseLine) while fullLine.maxX - fullLine.minX < length: baseLine = baseLine.translate(baseLine.maxX - baseLine.minX, 0) fullLine.addLineGroup(baseLine) mirrorLine = LineGroup(fullLine) mirrorLine = mirrorLine.mirror(c.X) mirrorLine = mirrorLine.translate(0, -space) fullLine.addLineGroup(mirrorLine) field = LineGroup(fullLine) while field.maxY - field.minY < height: fullLine = fullLine.translate(0, fullLine.maxY-fullLine.minY+space) field.addLineGroup(fullLine) return field
class Infill(LineGroup): def __init__(self, trimOutline, pathWidth, angleDegrees, shiftX=0, shiftY=0, design=None, designType=c.PARTIAL_ROW): LineGroup.__init__(self, None) self.shiftX = shiftX self.shiftY = shiftY self.designType = designType self.trimOutline = Outline(trimOutline) self.angleRad = (angleDegrees/360.0*2*np.pi) self.pathWidth = pathWidth lowerLeft = Point(self.trimOutline.minX, self.trimOutline.minY) upperRight = Point(self.trimOutline.maxX, self.trimOutline.maxY) self.trimDiagonal = (lowerLeft - upperRight)*1.1 self.operations = (self.extendDesign, self.createField, self.centerAndRotateField, self.trimField) try: self.design = design(space = self.pathWidth, length = self.trimDiagonal, height = self.trimDiagonal, ) self.designType = c.FULL_FIELD except Exception: self.design = LineGroup(design) # print('\nInfill times:') for i in range(self.designType, c.TRIMMED_FIELD): startTime = time.time() self.operations[i](); # print((self.operations[i].__name__ + # ''.ljust(maxLength - len(self.operations[i].__name__)) + # '%.2f sec' %(time.time()-startTime))) def extendDesign(self): tempDesign = LineGroup(self.design.lines) designWidth = self.design.maxX - self.design.minX while(designWidth <= self.trimDiagonal): shiftX = self.design[-1].end.x - tempDesign[0].start.x shiftY = self.design[-1].end.y - tempDesign[0].start.y self.design.addLineGroup(tempDesign.translate(shiftX, shiftY)) designWidth = self.design.maxX - self.design.minX def createField(self): tempDesign = self.design.translate(0, self.pathWidth) designHeight = 0 # abs(self.design.maxY - self.design.minY) while(designHeight < self.trimDiagonal): self.design.addLineGroup(tempDesign) tempDesign = tempDesign.translate(0, self.pathWidth) designHeight += self.pathWidth def centerAndRotateField(self): designCP = self.design.getMidPoint() trimOutlineCP = self.trimOutline.getMidPoint() transX = trimOutlineCP.x - designCP.x transY = trimOutlineCP.y - designCP.y self.design = self.design.transform(mt.combineTransformations( [mt.translateMatrix(transX+self.shiftX, transY+self.shiftY), mt.rotateMatrix(self.angleRad, trimOutlineCP)])) def trimField(self): trimStarts = self.trimOutline.starts trimVectors = self.trimOutline.vectors fieldStarts = self.design.starts fieldVectors = self.design.vectors trimLen = len(self.trimOutline) fieldLen = len(self.design) Q_Less_P = fieldStarts - trimStarts.reshape(trimLen,1,2) denom = np.cross(trimVectors, fieldVectors.reshape(fieldLen,1,2)) all_t = np.cross(Q_Less_P, trimVectors.reshape(trimLen,1,2)).transpose()/denom all_u = np.cross(Q_Less_P, fieldVectors).transpose()/denom for t, u, line in zip(all_t, all_u, self.design): if not self.trimOutline.lineOutsideBoundingBox(line): pointSet = set([line.start]) t = t[(0 <= u) & (u <= 1) & (0 <= t) & (t <= 1)] pointSet |= set(Point(line.start.x + line.vector[c.X]*value, line.start.y+line.vector[c.Y]*value) for value in t) pointSet.add(line.end) pointList = sorted(list(pointSet)) pointVectors = np.array([point.normalVector for point in pointList]) """ Calculation for midPoints from here: http://stackoverflow.com/questions/23855976/middle-point-of-each-pair-of-an-numpy-array """ midPoints = (pointVectors[1:] + pointVectors[:-1])/2.0 for i in range(len(midPoints)): if self.trimOutline.isInside(midPoints[i]): self.append(Line(pointList[i], pointList[i+1]))
class Infill(LineGroup): def __init__(self, trimOutline, pathWidth, angleDegrees, shiftX=0, shiftY=0, design=None, designType=c.PARTIAL_ROW): LineGroup.__init__(self, None) self.shiftX = shiftX self.shiftY = shiftY self.designType = designType self.trimOutline = Outline(trimOutline) self.angleRad = (angleDegrees / 360.0 * 2 * np.pi) self.pathWidth = pathWidth lowerLeft = Point(self.trimOutline.minX, self.trimOutline.minY) upperRight = Point(self.trimOutline.maxX, self.trimOutline.maxY) self.trimDiagonal = (lowerLeft - upperRight) * 1.1 self.operations = (self.extendDesign, self.createField, self.centerAndRotateField, self.trimField) try: self.design = design( space=self.pathWidth, length=self.trimDiagonal, height=self.trimDiagonal, ) self.designType = c.FULL_FIELD except Exception: self.design = LineGroup(design) # print('\nInfill times:') for i in range(self.designType, c.TRIMMED_FIELD): startTime = time.time() self.operations[i]() # print((self.operations[i].__name__ + # ''.ljust(maxLength - len(self.operations[i].__name__)) + # '%.2f sec' %(time.time()-startTime))) def extendDesign(self): tempDesign = LineGroup(self.design.lines) designWidth = self.design.maxX - self.design.minX while (designWidth <= self.trimDiagonal): shiftX = self.design[-1].end.x - tempDesign[0].start.x shiftY = self.design[-1].end.y - tempDesign[0].start.y self.design.addLineGroup(tempDesign.translate(shiftX, shiftY)) designWidth = self.design.maxX - self.design.minX def createField(self): tempDesign = self.design.translate(0, self.pathWidth) designHeight = 0 # abs(self.design.maxY - self.design.minY) while (designHeight < self.trimDiagonal): self.design.addLineGroup(tempDesign) tempDesign = tempDesign.translate(0, self.pathWidth) designHeight += self.pathWidth def centerAndRotateField(self): designCP = self.design.getMidPoint() trimOutlineCP = self.trimOutline.getMidPoint() transX = trimOutlineCP.x - designCP.x transY = trimOutlineCP.y - designCP.y self.design = self.design.transform( mt.combineTransformations([ mt.translateMatrix(transX + self.shiftX, transY + self.shiftY), mt.rotateMatrix(self.angleRad, trimOutlineCP) ])) def trimField(self): trimStarts = self.trimOutline.starts trimVectors = self.trimOutline.vectors fieldStarts = self.design.starts fieldVectors = self.design.vectors trimLen = len(self.trimOutline) fieldLen = len(self.design) Q_Less_P = fieldStarts - trimStarts.reshape(trimLen, 1, 2) denom = np.cross(trimVectors, fieldVectors.reshape(fieldLen, 1, 2)) all_t = np.cross(Q_Less_P, trimVectors.reshape(trimLen, 1, 2)).transpose() / denom all_u = np.cross(Q_Less_P, fieldVectors).transpose() / denom for t, u, line in zip(all_t, all_u, self.design): if not self.trimOutline.lineOutsideBoundingBox(line): pointSet = set([line.start]) t = t[(0 <= u) & (u <= 1) & (0 <= t) & (t <= 1)] pointSet |= set( Point(line.start.x + line.vector[c.X] * value, line.start.y + line.vector[c.Y] * value) for value in t) pointSet.add(line.end) pointList = sorted(list(pointSet)) pointVectors = np.array( [point.normalVector for point in pointList]) """ Calculation for midPoints from here: http://stackoverflow.com/questions/23855976/middle-point-of-each-pair-of-an-numpy-array """ midPoints = (pointVectors[1:] + pointVectors[:-1]) / 2.0 for i in range(len(midPoints)): if self.trimOutline.isInside(midPoints[i]): self.append(Line(pointList[i], pointList[i + 1]))