def addLoopXSegmentIntersections( lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y ): "Add intersections of the loop with the x segment." rotatedLoop = euclidean.getPointsRoundZAxis( 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 getSegmentsFromPoints(loops, pointBegin, pointEnd): "Get endpoint segments from the beginning and end of a line segment." normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs(normalizedSegment) if normalizedSegmentLength == 0.0: return [] normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd xIntersectionIndexList = [] xIntersectionIndexList.append( euclidean.XIntersectionIndex(-1, pointBeginRotated.real)) xIntersectionIndexList.append( euclidean.XIntersectionIndex(-1, pointEndRotated.real)) for loopIndex in xrange(len(loops)): rotatedLoop = euclidean.getPointsRoundZAxis(segmentYMirror, loops[loopIndex]) euclidean.addXIntersectionIndexesFromLoopY(rotatedLoop, loopIndex, xIntersectionIndexList, pointBeginRotated.imag) segments = euclidean.getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, pointBeginRotated.imag) for segment in segments: for endpoint in segment: endpoint.point *= normalizedSegment return segments
def getSegmentsFromPoints( aroundLists, loopLists, pointBegin, pointEnd ): "Get endpoint segments from the beginning and end of a line segment." normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength == 0.0: return normalizedSegment /= normalizedSegmentLength segmentYMirror = complex( normalizedSegment.real, - normalizedSegment.imag ) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd rotatedLoopLists = [] for loopList in loopLists: rotatedLoopList = [] rotatedLoopLists.append( rotatedLoopList ) for loop in loopList: rotatedLoop = euclidean.getPointsRoundZAxis( segmentYMirror, loop ) rotatedLoopList.append( rotatedLoop ) xIntersectionIndexList = [] xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointBeginRotated.real ) ) xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointEndRotated.real ) ) euclidean.addXIntersectionIndexesFromLoopLists( rotatedLoopLists, xIntersectionIndexList, pointBeginRotated.imag ) segments = euclidean.getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, pointBeginRotated.imag ) insideSegments = [] for segment in segments: insideSegment = euclidean.getSegmentFromPoints( normalizedSegment * segment[ 0 ].point, normalizedSegment * segment[ 1 ].point ) if len( aroundLists ) < 1: insideSegments.append( insideSegment ) elif isSegmentInsideAround( aroundLists, insideSegment ): insideSegments.append( insideSegment ) return insideSegments
def insertPathsBetween(self, aroundBetweenPath, nextBeginning, pathEnd): "Insert paths between the perimeter and the fill." betweenX = [] switchX = [] segment = euclidean.getNormalized(nextBeginning - pathEnd) segmentYMirror = complex(segment.real, -segment.imag) pathEndRotated = segmentYMirror * pathEnd nextBeginningRotated = segmentYMirror * nextBeginning y = pathEndRotated.imag for betweenIndex in xrange(len(self.getBetweens())): between = self.getBetweens()[betweenIndex] betweenRotated = euclidean.getPointsRoundZAxis( segmentYMirror, between) euclidean.addXIntersectionIndexes(betweenRotated, betweenIndex, switchX, y) switchX.sort() maximumX = max(pathEndRotated.real, nextBeginningRotated.real) minimumX = min(pathEndRotated.real, nextBeginningRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: betweenX.append(xIntersection) betweenXIndex = self.getStartIndex(betweenX) while betweenXIndex < len(betweenX) - 1: betweenXFirst = betweenX[betweenXIndex] betweenXSecond = betweenX[betweenXIndex + 1] loopFirst = self.getBetweens()[betweenXFirst.index] betweenFirst = segment * complex(betweenXFirst.x, y) betweenSecond = segment * complex(betweenXSecond.x, y) isLeavingPerimeter = False if betweenXSecond.index != betweenXFirst.index: isLeavingPerimeter = True self.addPathBetween(aroundBetweenPath, betweenFirst, betweenSecond, isLeavingPerimeter, loopFirst) betweenXIndex += 2
def getSegmentsFromLoopListsPoints( loopLists, pointBegin, pointEnd ): "Get endpoint segments from the beginning and end of a line segment." normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength == 0.0: return [] normalizedSegment /= normalizedSegmentLength segmentYMirror = complex( normalizedSegment.real, - normalizedSegment.imag ) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd rotatedLoopLists = [] for loopList in loopLists: rotatedLoopList = [] rotatedLoopLists.append( rotatedLoopList ) for loop in loopList: rotatedLoop = euclidean.getPointsRoundZAxis( segmentYMirror, loop ) rotatedLoopList.append( rotatedLoop ) xIntersectionIndexList = [] xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointBeginRotated.real ) ) xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointEndRotated.real ) ) euclidean.addXIntersectionIndexesFromLoopListsY( rotatedLoopLists, xIntersectionIndexList, pointBeginRotated.imag ) segments = euclidean.getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, pointBeginRotated.imag ) for segment in segments: for endpoint in segment: endpoint.point *= normalizedSegment return segments
def insertPathsBetween( self, aroundBetweenPath, nextBeginning, pathEnd ): "Insert paths between the perimeter and the fill." betweenX = [] switchX = [] segment = euclidean.getNormalized( nextBeginning - pathEnd ) segmentYMirror = complex( segment.real, - segment.imag ) pathEndRotated = segmentYMirror * pathEnd nextBeginningRotated = segmentYMirror * nextBeginning y = pathEndRotated.imag for betweenIndex in xrange( len( self.getBetweens() ) ): between = self.getBetweens()[ betweenIndex ] betweenRotated = euclidean.getPointsRoundZAxis( segmentYMirror, between ) euclidean.addXIntersectionIndexes( betweenRotated, betweenIndex, switchX, y ) switchX.sort() maximumX = max( pathEndRotated.real, nextBeginningRotated.real ) minimumX = min( pathEndRotated.real, nextBeginningRotated.real ) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: betweenX.append( xIntersection ) betweenXIndex = self.getStartIndex( betweenX ) while betweenXIndex < len( betweenX ) - 1: betweenXFirst = betweenX[ betweenXIndex ] betweenXSecond = betweenX[ betweenXIndex + 1 ] loopFirst = self.getBetweens()[ betweenXFirst.index ] betweenFirst = segment * complex( betweenXFirst.x, y ) betweenSecond = segment * complex( betweenXSecond.x, y ) isLeavingPerimeter = False if betweenXSecond.index != betweenXFirst.index: isLeavingPerimeter = True self.addPathBetween( aroundBetweenPath, betweenFirst, betweenSecond, isLeavingPerimeter, loopFirst ) betweenXIndex += 2
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.getPointsRoundZAxis(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.getPointsRoundZAxis( 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] isLeavingPerimeter = False if lineXSecond.index != lineXFirst.index: isLeavingPerimeter = True pathBetween = self.getPathBetween(points[lineXIndex + 1], points[lineXIndex + 2], isLeavingPerimeter, loopFirst) if isLeavingPerimeter: if not pathBetweenAdded: self.addRunningJumpPath(points[lineXIndex + 3], boundaries[lineXSecond.index], pathBetween) 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.getPointsRoundZAxis( 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.getPointsRoundZAxis(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 while lineXIndex < len(lineX) - 1: lineXFirst = lineX[lineXIndex] lineXSecond = lineX[lineXIndex + 1] loopFirst = boundaries[lineXFirst.index] isLeavingPerimeter = False if lineXSecond.index != lineXFirst.index: isLeavingPerimeter = True pathBetween = self.getPathBetween( points[lineXIndex + 1], points[lineXIndex + 2], isLeavingPerimeter, loopFirst ) if isLeavingPerimeter: pathBetween = self.getRunningJumpPath( points[lineXIndex + 3], boundaries[lineXSecond.index], pathBetween ) else: pathBetween = self.getSimplifiedAroundPath( points[lineXIndex], points[lineXIndex + 3], loopFirst, pathBetween ) aroundBetweenPath += pathBetween lineXIndex += 2 return aroundBetweenPath
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.getPointsRoundZAxis( segmentYMirror, belowLoop ) euclidean.addXIntersectionIndexes( rotatedOutset, belowLoopIndex, solidXIntersectionList, y ) overhangingSegments = euclidean.getSegmentsFromXIntersectionIndexes( solidXIntersectionList, y ) overhangDirection = complex() for overhangingSegment in overhangingSegments: overhangDirection += getDoubledRoundZ( overhangingSegment, normalizedSegment ) return overhangDirection
def getTruncatedJumpSpace(self, begin, segment): "Get the jump space truncated to an intersection." truncatedJumpSpace = begin + segment * self.runningJumpSpace switchX = [] segment = euclidean.getNormalized(truncatedJumpSpace - begin) segmentYMirror = complex(segment.real, -segment.imag) beginRotated = segmentYMirror * begin truncatedJumpSpaceRotated = segmentYMirror * truncatedJumpSpace y = beginRotated.imag betweens = self.getBetweens() for betweenIndex in xrange(len(betweens)): between = betweens[betweenIndex] betweenRotated = euclidean.getPointsRoundZAxis(segmentYMirror, between) euclidean.addXIntersectionIndexesFromLoopY(betweenRotated, betweenIndex, switchX, y) switchX.sort() maximumX = max(beginRotated.real, truncatedJumpSpaceRotated.real) minimumX = min(beginRotated.real, truncatedJumpSpaceRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: return segment * complex(xIntersection.x, y) return truncatedJumpSpace
def getSegmentsFromPoints(aroundLists, loopLists, pointBegin, pointEnd): "Get endpoint segments from the beginning and end of a line segment." normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs(normalizedSegment) if normalizedSegmentLength == 0.0: return normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd rotatedLoopLists = [] for loopList in loopLists: rotatedLoopList = [] rotatedLoopLists.append(rotatedLoopList) for loop in loopList: rotatedLoop = euclidean.getPointsRoundZAxis(segmentYMirror, loop) rotatedLoopList.append(rotatedLoop) xIntersectionIndexList = [] xIntersectionIndexList.append( euclidean.XIntersectionIndex(-1, pointBeginRotated.real)) xIntersectionIndexList.append( euclidean.XIntersectionIndex(-1, pointEndRotated.real)) euclidean.addXIntersectionIndexesFromLoopLists(rotatedLoopLists, xIntersectionIndexList, pointBeginRotated.imag) segments = euclidean.getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, pointBeginRotated.imag) insideSegments = [] for segment in segments: insideSegment = euclidean.getSegmentFromPoints( normalizedSegment * segment[0].point, normalizedSegment * segment[1].point) if len(aroundLists) < 1: insideSegments.append(insideSegment) elif isSegmentInsideAround(aroundLists, insideSegment): insideSegments.append(insideSegment) return insideSegments