def addSkinnedInfillBoundary(self, infillBoundaries, offsetY, upperZ, z): 'Add skinned infill boundary.' aroundInset = 0.24321 * self.skinInfillInset arounds = [] aroundWidth = 0.24321 * self.skinInfillInset endpoints = [] pixelTable = {} rotatedLoops = [] for infillBoundary in infillBoundaries: infillBoundaryRotated = euclidean.getRotatedComplexes(self.reverseRotation, infillBoundary) if offsetY != 0.0: for infillPointRotatedIndex, infillPointRotated in enumerate(infillBoundaryRotated): infillBoundaryRotated[infillPointRotatedIndex] = complex(infillPointRotated.real, infillPointRotated.imag - offsetY) rotatedLoops.append(infillBoundaryRotated) infillDictionary = triangle_mesh.getInfillDictionary( aroundInset, arounds, aroundWidth, self.skinInfillInset, self.skinInfillWidth, pixelTable, rotatedLoops) for infillDictionaryKey in infillDictionary.keys(): xIntersections = infillDictionary[infillDictionaryKey] xIntersections.sort() for segment in euclidean.getSegmentsFromXIntersections(xIntersections, infillDictionaryKey * self.skinInfillWidth): for endpoint in segment: endpoint.point = complex(endpoint.point.real, endpoint.point.imag + offsetY) endpoints.append(endpoint) infillPaths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.skinInfillWidth, pixelTable, aroundWidth) for infillPath in infillPaths: infillRotated = euclidean.getRotatedComplexes(self.rotation, infillPath) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, infillRotated[0], upperZ) self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, infillRotated, self.travelFeedRateMinute, z) lastPointRotated = infillRotated[-1] self.oldLocation = Vector3(lastPointRotated.real, lastPointRotated.imag, upperZ) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, lastPointRotated, upperZ)
def addSkinnedInfillBoundary(self, infillBoundaries, offsetY, upperZ, z): 'Add skinned infill boundary.' arounds = [] aroundWidth = 0.34321 * self.skinInfillInset endpoints = [] pixelTable = {} rotatedLoops = [] for infillBoundary in infillBoundaries: infillBoundaryRotated = euclidean.getRotatedComplexes(self.reverseRotation, infillBoundary) if offsetY != 0.0: for infillPointRotatedIndex, infillPointRotated in enumerate(infillBoundaryRotated): infillBoundaryRotated[infillPointRotatedIndex] = complex(infillPointRotated.real, infillPointRotated.imag - offsetY) rotatedLoops.append(infillBoundaryRotated) infillDictionary = triangle_mesh.getInfillDictionary( arounds, aroundWidth, self.skinInfillInset, self.skinInfillWidth, pixelTable, rotatedLoops) for infillDictionaryKey in infillDictionary.keys(): xIntersections = infillDictionary[infillDictionaryKey] xIntersections.sort() for segment in euclidean.getSegmentsFromXIntersections(xIntersections, infillDictionaryKey * self.skinInfillWidth): for endpoint in segment: endpoint.point = complex(endpoint.point.real, endpoint.point.imag + offsetY) endpoints.append(endpoint) infillPaths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.skinInfillWidth, pixelTable, aroundWidth) for infillPath in infillPaths: infillRotated = euclidean.getRotatedComplexes(self.rotation, infillPath) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, infillRotated[0], upperZ) self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, infillRotated, self.travelFeedRateMinute, z) lastPointRotated = infillRotated[-1] self.oldLocation = Vector3(lastPointRotated.real, lastPointRotated.imag, upperZ) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, lastPointRotated, upperZ)
def addSkinnedInfillBoundary(self, infillBoundaries, offsetY, upperZ, z): "Add skinned infill boundary." arounds = [] aroundWidth = 0.34321 * self.skinInfillInset endpoints = [] pixelTable = {} rotatedLoops = [] for infillBoundary in infillBoundaries: infillBoundaryRotated = euclidean.getRotatedComplexes(self.reverseRotation, infillBoundary) if offsetY != 0.0: for infillPointRotatedIndex, infillPointRotated in enumerate(infillBoundaryRotated): infillBoundaryRotated[infillPointRotatedIndex] = complex( infillPointRotated.real, infillPointRotated.imag - offsetY ) rotatedLoops.append(infillBoundaryRotated) infillDictionary = triangle_mesh.getInfillDictionary( arounds, aroundWidth, self.skinInfillInset, self.skinInfillWidth, pixelTable, rotatedLoops ) for infillDictionaryKey in infillDictionary.keys(): xIntersections = infillDictionary[infillDictionaryKey] xIntersections.sort() for segment in euclidean.getSegmentsFromXIntersections( xIntersections, infillDictionaryKey * self.skinInfillWidth ): for endpoint in segment: endpoint.point = complex(endpoint.point.real, endpoint.point.imag + offsetY) endpoints.append(endpoint) infillPaths = euclidean.getPathsFromEndpoints( endpoints, 5.0 * self.skinInfillWidth, pixelTable, self.sharpestProduct, aroundWidth ) for infillPath in infillPaths: addPointBeforeThread = True infillRotated = euclidean.getRotatedComplexes(self.rotation, infillPath) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: feedRateMinute = self.travelFeedRateMinute infillRotatedFirst = infillRotated[0] location = Vector3(infillRotatedFirst.real, infillRotatedFirst.imag, upperZ) distance = abs(location - self.oldLocation) if distance > 0.0: deltaZ = abs(upperZ - self.oldLocation.z) zFeedRateComponent = feedRateMinute * deltaZ / distance if zFeedRateComponent > self.maximumZFeedRateMinute: feedRateMinute *= self.maximumZFeedRateMinute / zFeedRateComponent self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedRateMinute, infillRotatedFirst, upperZ) self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, infillRotatedFirst, z) addPointBeforeThread = False if addPointBeforeThread: self.distanceFeedRate.addGcodeMovementZ(infillRotated[0], z) self.distanceFeedRate.addLine("M101") for point in infillRotated[1:]: self.distanceFeedRate.addGcodeMovementZ(point, z) self.distanceFeedRate.addLine("M103") lastPointRotated = infillRotated[-1] self.oldLocation = Vector3(lastPointRotated.real, lastPointRotated.imag, upperZ) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.maximumZFeedRateMinute, lastPointRotated, upperZ )
def addSkinnedInfillBoundary(self, infillBoundaries, offsetY, upperZ, z): 'Add skinned infill boundary.' arounds = [] aroundWidth = 0.34321 * self.skinInfillInset endpoints = [] pixelTable = {} rotatedLoops = [] for infillBoundary in infillBoundaries: infillBoundaryRotated = euclidean.getRotatedComplexes(self.reverseRotation, infillBoundary) if offsetY != 0.0: for infillPointRotatedIndex, infillPointRotated in enumerate(infillBoundaryRotated): infillBoundaryRotated[infillPointRotatedIndex] = complex(infillPointRotated.real, infillPointRotated.imag - offsetY) rotatedLoops.append(infillBoundaryRotated) infillDictionary = triangle_mesh.getInfillDictionary( arounds, aroundWidth, self.skinInfillInset, self.skinInfillWidth, pixelTable, rotatedLoops) for infillDictionaryKey in infillDictionary.keys(): xIntersections = infillDictionary[infillDictionaryKey] xIntersections.sort() for segment in euclidean.getSegmentsFromXIntersections(xIntersections, infillDictionaryKey * self.skinInfillWidth): for endpoint in segment: endpoint.point = complex(endpoint.point.real, endpoint.point.imag + offsetY) endpoints.append(endpoint) infillPaths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.skinInfillWidth, pixelTable, self.sharpestProduct, aroundWidth) for infillPath in infillPaths: addPointBeforeThread = True infillRotated = euclidean.getRotatedComplexes(self.rotation, infillPath) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: feedRateMinute = self.travelFeedRateMinute infillRotatedFirst = infillRotated[0] location = Vector3(infillRotatedFirst.real, infillRotatedFirst.imag, upperZ) distance = abs(location - self.oldLocation) if distance > 0.0: deltaZ = abs(upperZ - self.oldLocation.z) zFeedRateComponent = feedRateMinute * deltaZ / distance if zFeedRateComponent > self.maximumZFeedRateMinute: feedRateMinute *= self.maximumZFeedRateMinute / zFeedRateComponent self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedRateMinute, infillRotatedFirst, upperZ) self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, infillRotatedFirst, z) addPointBeforeThread = False if addPointBeforeThread: self.distanceFeedRate.addGcodeMovementZ(infillRotated[0], z) self.distanceFeedRate.addLine('M101') for point in infillRotated[1 :]: self.distanceFeedRate.addGcodeMovementZ(point, z) self.distanceFeedRate.addLine('M103') lastPointRotated = infillRotated[-1] self.oldLocation = Vector3(lastPointRotated.real, lastPointRotated.imag, upperZ) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, lastPointRotated, upperZ)
def getBoundaryIndexes(self, begin, boundaries, end, points): 'Get boundary indexes and set the points in the way of the original line segment.' boundaryIndexes = [] points.append(begin) switchX = [] segment = euclidean.getNormalized(end - begin) segmentYMirror = complex(segment.real, -segment.imag) beginRotated = segmentYMirror * begin endRotated = segmentYMirror * end y = beginRotated.imag for boundaryIndex in xrange(len(boundaries)): boundary = boundaries[boundaryIndex] boundaryRotated = euclidean.getRotatedComplexes( segmentYMirror, boundary) euclidean.addXIntersectionIndexesFromLoopY(boundaryRotated, boundaryIndex, switchX, y) switchX.sort() maximumX = max(beginRotated.real, endRotated.real) minimumX = min(beginRotated.real, endRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: point = segment * complex(xIntersection.x, y) points.append(point) boundaryIndexes.append(xIntersection.index) points.append(end) return boundaryIndexes
def getOverhangDirection(belowOutsetLoops, segmentBegin, segmentEnd): 'Add to span direction from the endpoint segments which overhang the layer below.' segment = segmentEnd - segmentBegin normalizedSegment = euclidean.getNormalized( complex(segment.real, segment.imag)) segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) segmentBegin = segmentYMirror * segmentBegin segmentEnd = segmentYMirror * segmentEnd solidXIntersectionList = [] y = segmentBegin.imag solidXIntersectionList.append( euclidean.XIntersectionIndex(-1.0, segmentBegin.real)) solidXIntersectionList.append( euclidean.XIntersectionIndex(-1.0, segmentEnd.real)) for belowLoopIndex in xrange(len(belowOutsetLoops)): belowLoop = belowOutsetLoops[belowLoopIndex] rotatedOutset = euclidean.getRotatedComplexes(segmentYMirror, belowLoop) euclidean.addXIntersectionIndexesFromLoopY(rotatedOutset, belowLoopIndex, solidXIntersectionList, y) overhangingSegments = euclidean.getSegmentsFromXIntersectionIndexes( solidXIntersectionList, y) overhangDirection = complex() for overhangingSegment in overhangingSegments: overhangDirection += getDoubledRoundZ(overhangingSegment, normalizedSegment) return overhangDirection
def getDistance(self): "Get distance between point and closest intersection or bottom point along line." self.pointMinusBottomY = self.alongAway.point.y - self.alongAway.minimumY self.diagonalDistance = self.pointMinusBottomY * self.diagonalRatio if self.alongAway.pointIndex == None: return self.getDistanceToBottom() rotatedLoop = euclidean.getRotatedComplexes( self.intersectionYMirror, euclidean.getComplexPath(self.alongAway.loop)) rotatedPointComplex = rotatedLoop[self.alongAway.pointIndex] beginX = rotatedPointComplex.real endX = beginX + self.diagonalDistance + self.diagonalDistance xIntersectionIndexList = [] for pointIndex in self.alongAway.awayIndexes: beginComplex = rotatedLoop[pointIndex] endComplex = rotatedLoop[(pointIndex + 1) % len(rotatedLoop)] xIntersection = euclidean.getXIntersectionIfExists( beginComplex, endComplex, rotatedPointComplex.imag) if xIntersection != None: if xIntersection >= beginX and xIntersection < endX: xIntersectionIndexList.append( euclidean.XIntersectionIndex(pointIndex, xIntersection)) self.closestXDistance = 987654321.0 self.closestXIntersectionIndex = None for xIntersectionIndex in xIntersectionIndexList: xDistance = abs(xIntersectionIndex.x - beginX) if xDistance < self.closestXDistance: self.closestXIntersectionIndex = xIntersectionIndex self.closestXDistance = xDistance if self.closestXIntersectionIndex != None: return self.closestXDistance return self.getDistanceToBottom()
def getDistance(self): "Get distance between point and closest intersection or bottom point along line." self.pointMinusBottomY = self.alongAway.point.y - self.alongAway.minimumY self.diagonalDistance = self.pointMinusBottomY * self.diagonalRatio if self.alongAway.pointIndex == None: return self.getDistanceToBottom() rotatedLoop = euclidean.getRotatedComplexes( self.intersectionYMirror, euclidean.getComplexPath( self.alongAway.loop ) ) rotatedPointComplex = rotatedLoop[ self.alongAway.pointIndex ] beginX = rotatedPointComplex.real endX = beginX + self.diagonalDistance + self.diagonalDistance xIntersectionIndexList = [] for pointIndex in self.alongAway.awayIndexes: beginComplex = rotatedLoop[pointIndex] endComplex = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ] xIntersection = euclidean.getXIntersectionIfExists( beginComplex, endComplex, rotatedPointComplex.imag ) if xIntersection != None: if xIntersection >= beginX and xIntersection < endX: xIntersectionIndexList.append( euclidean.XIntersectionIndex( pointIndex, xIntersection ) ) self.closestXDistance = 987654321.0 self.closestXIntersectionIndex = None for xIntersectionIndex in xIntersectionIndexList: xDistance = abs( xIntersectionIndex.x - beginX ) if xDistance < self.closestXDistance: self.closestXIntersectionIndex = xIntersectionIndex self.closestXDistance = xDistance if self.closestXIntersectionIndex != None: return self.closestXDistance return self.getDistanceToBottom()
def addLoopXSegmentIntersections(lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y): "Add intersections of the loop with the x segment." rotatedLoop = euclidean.getRotatedComplexes(segmentYMirror, loop) for pointIndex in xrange(len(rotatedLoop)): pointFirst = rotatedLoop[pointIndex] pointSecond = rotatedLoop[(pointIndex + 1) % len(rotatedLoop)] addLineXSegmentIntersection(lineLoopsIntersections, segmentFirstX, segmentSecondX, pointFirst, pointSecond, y)
def getPathsBetween(self, begin, end): "Insert paths between the perimeter and the fill." aroundBetweenPath = [] points = [begin] lineX = [] switchX = [] segment = euclidean.getNormalized(end - begin) segmentYMirror = complex(segment.real, -segment.imag) beginRotated = segmentYMirror * begin endRotated = segmentYMirror * end y = beginRotated.imag boundaries = self.getBoundaries() for boundaryIndex in xrange(len(boundaries)): boundary = boundaries[boundaryIndex] boundaryRotated = euclidean.getRotatedComplexes( segmentYMirror, boundary) euclidean.addXIntersectionIndexesFromLoopY(boundaryRotated, boundaryIndex, switchX, y) switchX.sort() maximumX = max(beginRotated.real, endRotated.real) minimumX = min(beginRotated.real, endRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: point = segment * complex(xIntersection.x, y) points.append(point) lineX.append(xIntersection) points.append(end) lineXIndex = 0 # pathBetweenAdded = False while lineXIndex < len(lineX) - 1: lineXFirst = lineX[lineXIndex] lineXSecond = lineX[lineXIndex + 1] loopFirst = boundaries[lineXFirst.index] if lineXSecond.index == lineXFirst.index: pathBetween = self.getPathBetween( loopFirst, points[lineXIndex:lineXIndex + 4]) pathBetween = self.getSimplifiedAroundPath( points[lineXIndex], points[lineXIndex + 3], loopFirst, pathBetween) aroundBetweenPath += pathBetween lineXIndex += 2 else: lineXIndex += 1 # isLeavingPerimeter = False # if lineXSecond.index != lineXFirst.index: # isLeavingPerimeter = True # pathBetween = self.getPathBetween( points[ lineXIndex + 1 ], points[ lineXIndex + 2 ], isLeavingPerimeter, loopFirst ) # if isLeavingPerimeter: # pathBetweenAdded = True # else: # pathBetween = self.getSimplifiedAroundPath( points[ lineXIndex ], points[ lineXIndex + 3 ], loopFirst, pathBetween ) # pathBetweenAdded = True # aroundBetweenPath += pathBetween # lineXIndex += 2 return aroundBetweenPath
def addLoopXSegmentIntersections(lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y): 'Add intersections of the loop with the x segment.' rotatedLoop = euclidean.getRotatedComplexes(segmentYMirror, loop) for pointIndex in xrange(len(rotatedLoop)): pointFirst = rotatedLoop[pointIndex] pointSecond = rotatedLoop[(pointIndex + 1) % len(rotatedLoop)] addLineXSegmentIntersection(lineLoopsIntersections, segmentFirstX, segmentSecondX, pointFirst, pointSecond, y)
def addSegmentOutline(isThick, outlines, pointBegin, pointEnd, width): "Add a diamond or hexagonal outline for a line segment." width = abs(width) exclusionWidth = 0.6 * width slope = 0.2 if isThick: slope = 3.0 exclusionWidth = 0.8 * width segment = pointEnd - pointBegin segmentLength = abs(segment) if segmentLength == 0.0: return normalizedSegment = segment / segmentLength outline = [] segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd along = 0.05 alongLength = along * segmentLength if alongLength > 0.1 * exclusionWidth: along *= 0.1 * exclusionWidth / alongLength alongEnd = 1.0 - along remainingToHalf = 0.5 - along alongToWidth = exclusionWidth / slope / segmentLength pointBeginIntermediate = euclidean.getIntermediateLocation( along, pointBeginRotated, pointEndRotated) pointEndIntermediate = euclidean.getIntermediateLocation( alongEnd, pointBeginRotated, pointEndRotated) outline.append(pointBeginIntermediate) verticalWidth = complex(0.0, exclusionWidth) if alongToWidth > 0.9 * remainingToHalf: verticalWidth = complex(0.0, slope * remainingToHalf * segmentLength) middle = (pointBeginIntermediate + pointEndIntermediate) * 0.5 middleDown = middle - verticalWidth middleUp = middle + verticalWidth outline.append(middleUp) outline.append(pointEndIntermediate) outline.append(middleDown) else: alongOutsideBegin = along + alongToWidth alongOutsideEnd = alongEnd - alongToWidth outsideBeginCenter = euclidean.getIntermediateLocation( alongOutsideBegin, pointBeginRotated, pointEndRotated) outsideBeginCenterDown = outsideBeginCenter - verticalWidth outsideBeginCenterUp = outsideBeginCenter + verticalWidth outsideEndCenter = euclidean.getIntermediateLocation( alongOutsideEnd, pointBeginRotated, pointEndRotated) outsideEndCenterDown = outsideEndCenter - verticalWidth outsideEndCenterUp = outsideEndCenter + verticalWidth outline.append(outsideBeginCenterUp) outline.append(outsideEndCenterUp) outline.append(pointEndIntermediate) outline.append(outsideEndCenterDown) outline.append(outsideBeginCenterDown) outlines.append(euclidean.getRotatedComplexes(normalizedSegment, outline))
def getPathsBetween(self, begin, end): "Insert paths between the perimeter and the fill." aroundBetweenPath = [] points = [begin] lineX = [] switchX = [] segment = euclidean.getNormalized(end - begin) segmentYMirror = complex(segment.real, -segment.imag) beginRotated = segmentYMirror * begin endRotated = segmentYMirror * end y = beginRotated.imag boundaries = self.getBoundaries() for boundaryIndex in xrange(len(boundaries)): boundary = boundaries[boundaryIndex] boundaryRotated = euclidean.getRotatedComplexes(segmentYMirror, boundary) euclidean.addXIntersectionIndexesFromLoopY(boundaryRotated, boundaryIndex, switchX, y) switchX.sort() maximumX = max(beginRotated.real, endRotated.real) minimumX = min(beginRotated.real, endRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: point = segment * complex(xIntersection.x, y) points.append(point) lineX.append(xIntersection) points.append(end) lineXIndex = 0 # pathBetweenAdded = False while lineXIndex < len(lineX) - 1: lineXFirst = lineX[lineXIndex] lineXSecond = lineX[lineXIndex + 1] loopFirst = boundaries[lineXFirst.index] if lineXSecond.index == lineXFirst.index: pathBetween = self.getPathBetween(loopFirst, points[lineXIndex : lineXIndex + 4]) pathBetween = self.getSimplifiedAroundPath( points[lineXIndex], points[lineXIndex + 3], loopFirst, pathBetween ) aroundBetweenPath += pathBetween lineXIndex += 2 else: lineXIndex += 1 # isLeavingPerimeter = False # if lineXSecond.index != lineXFirst.index: # isLeavingPerimeter = True # pathBetween = self.getPathBetween( points[ lineXIndex + 1 ], points[ lineXIndex + 2 ], isLeavingPerimeter, loopFirst ) # if isLeavingPerimeter: # pathBetweenAdded = True # else: # pathBetween = self.getSimplifiedAroundPath( points[ lineXIndex ], points[ lineXIndex + 3 ], loopFirst, pathBetween ) # pathBetweenAdded = True # aroundBetweenPath += pathBetween # lineXIndex += 2 return aroundBetweenPath
def addSegmentOutline( isThick, outlines, pointBegin, pointEnd, width ): "Add a diamond or hexagonal outline for a line segment." width = abs( width ) exclusionWidth = 0.6 * width slope = 0.2 if isThick: slope = 3.0 exclusionWidth = 0.8 * width segment = pointEnd - pointBegin segmentLength = abs(segment) if segmentLength == 0.0: return normalizedSegment = segment / segmentLength outline = [] segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd along = 0.05 alongLength = along * segmentLength if alongLength > 0.1 * exclusionWidth: along *= 0.1 * exclusionWidth / alongLength alongEnd = 1.0 - along remainingToHalf = 0.5 - along alongToWidth = exclusionWidth / slope / segmentLength pointBeginIntermediate = euclidean.getIntermediateLocation( along, pointBeginRotated, pointEndRotated ) pointEndIntermediate = euclidean.getIntermediateLocation( alongEnd, pointBeginRotated, pointEndRotated ) outline.append( pointBeginIntermediate ) verticalWidth = complex( 0.0, exclusionWidth ) if alongToWidth > 0.9 * remainingToHalf: verticalWidth = complex( 0.0, slope * remainingToHalf * segmentLength ) middle = ( pointBeginIntermediate + pointEndIntermediate ) * 0.5 middleDown = middle - verticalWidth middleUp = middle + verticalWidth outline.append( middleUp ) outline.append( pointEndIntermediate ) outline.append( middleDown ) else: alongOutsideBegin = along + alongToWidth alongOutsideEnd = alongEnd - alongToWidth outsideBeginCenter = euclidean.getIntermediateLocation( alongOutsideBegin, pointBeginRotated, pointEndRotated ) outsideBeginCenterDown = outsideBeginCenter - verticalWidth outsideBeginCenterUp = outsideBeginCenter + verticalWidth outsideEndCenter = euclidean.getIntermediateLocation( alongOutsideEnd, pointBeginRotated, pointEndRotated ) outsideEndCenterDown = outsideEndCenter - verticalWidth outsideEndCenterUp = outsideEndCenter + verticalWidth outline.append( outsideBeginCenterUp ) outline.append( outsideEndCenterUp ) outline.append( pointEndIntermediate ) outline.append( outsideEndCenterDown ) outline.append( outsideBeginCenterDown ) outlines.append( euclidean.getRotatedComplexes( normalizedSegment, outline ) )
def getVoronoiLoopByPoint(inside, loop, outside): 'Get voronoi loop enclosing the inside.' insideMinusOutside = inside - outside insideMinusOutside /= abs(insideMinusOutside) rotation = complex(insideMinusOutside.real, -insideMinusOutside.imag) rotatedInside = inside * rotation rotatedLoop = euclidean.getRotatedComplexes(rotation, loop) rotatedOutside = outside * rotation midX = 0.5 * (rotatedInside.real + rotatedOutside.real) voronoiLoop = [] for pointIndex, point in enumerate(loop): nextIndex = (pointIndex + 1) % len(loop) addVoronoiPoint(point, loop[nextIndex], midX, voronoiLoop, rotatedLoop[pointIndex], rotatedLoop[nextIndex]) return voronoiLoop
def getOverhangDirection( belowOutsetLoops, segmentBegin, segmentEnd ): 'Add to span direction from the endpoint segments which overhang the layer below.' segment = segmentEnd - segmentBegin normalizedSegment = euclidean.getNormalized( complex( segment.real, segment.imag ) ) segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) segmentBegin = segmentYMirror * segmentBegin segmentEnd = segmentYMirror * segmentEnd solidXIntersectionList = [] y = segmentBegin.imag solidXIntersectionList.append( euclidean.XIntersectionIndex( - 1.0, segmentBegin.real ) ) solidXIntersectionList.append( euclidean.XIntersectionIndex( - 1.0, segmentEnd.real ) ) for belowLoopIndex in xrange( len( belowOutsetLoops ) ): belowLoop = belowOutsetLoops[ belowLoopIndex ] rotatedOutset = euclidean.getRotatedComplexes( segmentYMirror, belowLoop ) euclidean.addXIntersectionIndexesFromLoopY( rotatedOutset, belowLoopIndex, solidXIntersectionList, y ) overhangingSegments = euclidean.getSegmentsFromXIntersectionIndexes( solidXIntersectionList, y ) overhangDirection = complex() for overhangingSegment in overhangingSegments: overhangDirection += getDoubledRoundZ( overhangingSegment, normalizedSegment ) return overhangDirection
def getBoundaryIndexes(self, begin, boundaries, end, points): "Get boundary indexes and set the points in the way of the original line segment." boundaryIndexes = [] points.append(begin) switchX = [] segment = euclidean.getNormalized(end - begin) segmentYMirror = complex(segment.real, -segment.imag) beginRotated = segmentYMirror * begin endRotated = segmentYMirror * end y = beginRotated.imag for boundaryIndex in xrange(len(boundaries)): boundary = boundaries[boundaryIndex] boundaryRotated = euclidean.getRotatedComplexes(segmentYMirror, boundary) euclidean.addXIntersectionIndexesFromLoopY(boundaryRotated, boundaryIndex, switchX, y) switchX.sort() maximumX = max(beginRotated.real, endRotated.real) minimumX = min(beginRotated.real, endRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: point = segment * complex(xIntersection.x, y) points.append(point) boundaryIndexes.append(xIntersection.index) points.append(end) return boundaryIndexes