def helicalMove(self, isCounterclockwise, splitLine): "Get statistics for a helical move." if self.oldLocation == None: return location = self.getLocationSetFeedRateToSplitLine(splitLine) location += self.oldLocation center = self.oldLocation.copy() indexOfR = gcodec.indexOfStartingWithSecond("R", splitLine) if indexOfR > 0: radius = gcodec.getDoubleAfterFirstLetter(splitLine[indexOfR]) halfLocationMinusOld = location - self.oldLocation halfLocationMinusOld *= 0.5 halfLocationMinusOldLength = halfLocationMinusOld.magnitude() centerMidpointDistanceSquared = radius * radius - halfLocationMinusOldLength * halfLocationMinusOldLength centerMidpointDistance = math.sqrt( max(centerMidpointDistanceSquared, 0.0)) centerMinusMidpoint = euclidean.getRotatedWiddershinsQuarterAroundZAxis( halfLocationMinusOld) centerMinusMidpoint.normalize() centerMinusMidpoint *= centerMidpointDistance if isCounterclockwise: center.setToVector3(halfLocationMinusOld + centerMinusMidpoint) else: center.setToVector3(halfLocationMinusOld - centerMinusMidpoint) else: center.x = gcodec.getDoubleForLetter("I", splitLine) center.y = gcodec.getDoubleForLetter("J", splitLine) curveSection = 0.5 center += self.oldLocation afterCenterSegment = location - center beforeCenterSegment = self.oldLocation - center afterCenterDifferenceAngle = euclidean.getAngleAroundZAxisDifference( afterCenterSegment, beforeCenterSegment) absoluteDifferenceAngle = abs(afterCenterDifferenceAngle) steps = int( round(0.5 + max( absoluteDifferenceAngle * 2.4, absoluteDifferenceAngle * beforeCenterSegment.magnitude() / curveSection))) stepPlaneAngle = euclidean.getUnitPolar( afterCenterDifferenceAngle / steps, 1.0) zIncrement = (afterCenterSegment.z - beforeCenterSegment.z) / float(steps) for step in xrange(1, steps): beforeCenterSegment = euclidean.getRoundZAxisByPlaneAngle( stepPlaneAngle, beforeCenterSegment) beforeCenterSegment.z += zIncrement arcPoint = center + beforeCenterSegment self.addToPath(arcPoint) self.addToPath(location)
def helicalMove(self, isCounterclockwise, splitLine): "Get statistics for a helical move." if self.oldLocation == None: return location = self.getLocationSetFeedRateToSplitLine(splitLine) location += self.oldLocation center = self.oldLocation.copy() indexOfR = gcodec.indexOfStartingWithSecond("R", splitLine) if indexOfR > 0: radius = gcodec.getDoubleAfterFirstLetter(splitLine[indexOfR]) halfLocationMinusOld = location - self.oldLocation halfLocationMinusOld *= 0.5 halfLocationMinusOldLength = halfLocationMinusOld.magnitude() centerMidpointDistanceSquared = radius * radius - halfLocationMinusOldLength * halfLocationMinusOldLength centerMidpointDistance = math.sqrt(max(centerMidpointDistanceSquared, 0.0)) centerMinusMidpoint = euclidean.getRotatedWiddershinsQuarterAroundZAxis(halfLocationMinusOld) centerMinusMidpoint.normalize() centerMinusMidpoint *= centerMidpointDistance if isCounterclockwise: center.setToVector3(halfLocationMinusOld + centerMinusMidpoint) else: center.setToVector3(halfLocationMinusOld - centerMinusMidpoint) else: center.x = gcodec.getDoubleForLetter("I", splitLine) center.y = gcodec.getDoubleForLetter("J", splitLine) curveSection = 0.5 center += self.oldLocation afterCenterSegment = location - center beforeCenterSegment = self.oldLocation - center afterCenterDifferenceAngle = euclidean.getAngleAroundZAxisDifference(afterCenterSegment, beforeCenterSegment) absoluteDifferenceAngle = abs(afterCenterDifferenceAngle) steps = int( round( 0.5 + max( absoluteDifferenceAngle * 2.4, absoluteDifferenceAngle * beforeCenterSegment.magnitude() / curveSection, ) ) ) stepPlaneAngle = euclidean.getPolar(afterCenterDifferenceAngle / steps, 1.0) zIncrement = (afterCenterSegment.z - beforeCenterSegment.z) / float(steps) for step in xrange(1, steps): beforeCenterSegment = euclidean.getRoundZAxisByPlaneAngle(stepPlaneAngle, beforeCenterSegment) beforeCenterSegment.z += zIncrement arcPoint = center + beforeCenterSegment self.addToPath(arcPoint) self.addToPath(location)
def splitPointGetAfter( self, location, nextLocation ): "Fillet a point into arc segments and return the end of the last segment." afterSegment = nextLocation - location afterSegmentLength = afterSegment.magnitude() afterSegmentExtension = 0.5 * afterSegmentLength if afterSegmentExtension == 0.0: return location beforeSegment = self.oldLocation - location beforeSegmentLength = beforeSegment.magnitude() if beforeSegmentLength == 0.0: return location radius = self.filletRadius afterSegmentNormalized = afterSegment / afterSegmentLength beforeSegmentNormalized = beforeSegment / beforeSegmentLength betweenCenterDotNormalized = afterSegmentNormalized + beforeSegmentNormalized if betweenCenterDotNormalized.magnitude() < 0.01 * self.filletRadius: return location extruderOffReversalPoint = self.getExtruderOffReversalPoint( afterSegment, beforeSegment, location ) if extruderOffReversalPoint != None: return extruderOffReversalPoint betweenCenterDotNormalized.normalize() beforeSegmentNormalizedWiddershins = euclidean.getRotatedWiddershinsQuarterAroundZAxis( beforeSegmentNormalized ) betweenAfterPlaneDot = abs( euclidean.getPlaneDot( betweenCenterDotNormalized, beforeSegmentNormalizedWiddershins ) ) centerDotDistance = radius / betweenAfterPlaneDot bevelLength = math.sqrt( centerDotDistance * centerDotDistance - radius * radius ) radiusOverBevelLength = radius / bevelLength bevelLength = min( bevelLength, radius ) bevelLength = min( afterSegmentExtension, bevelLength ) beforePoint = self.oldLocation if beforeSegmentLength < bevelLength: bevelLength = beforeSegmentLength else: beforePoint = euclidean.getPointPlusSegmentWithLength( bevelLength, location, beforeSegment ) self.addLinearMovePoint( self.feedrateMinute, beforePoint ) self.shouldAddLine = False afterPoint = euclidean.getPointPlusSegmentWithLength( bevelLength, location, afterSegment ) radius = bevelLength * radiusOverBevelLength centerDotDistance = radius / betweenAfterPlaneDot center = location + betweenCenterDotNormalized * centerDotDistance afterCenterSegment = afterPoint - center beforeCenterSegment = beforePoint - center afterCenterDifferenceAngle = euclidean.getAngleAroundZAxisDifference( afterCenterSegment, beforeCenterSegment ) self.addArc( afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center ) return afterPoint
def splitPointGetAfter( self, location, nextLocation ): "Fillet a point into arc segments and return the end of the last segment." if self.filletRadius < 2.0 * self.minimumRadius: return location afterSegment = nextLocation - location afterSegmentComplex = afterSegment.dropAxis( 2 ) thirdAfterSegmentLength = 0.333 * abs( afterSegmentComplex ) if thirdAfterSegmentLength < self.minimumRadius: return location beforeSegment = self.oldLocation - location beforeSegmentComplex = beforeSegment.dropAxis( 2 ) thirdBeforeSegmentLength = 0.333 * abs( beforeSegmentComplex ) if thirdBeforeSegmentLength < self.minimumRadius: return location extruderOffReversalPoint = self.getExtruderOffReversalPoint( afterSegment, beforeSegment, location ) if extruderOffReversalPoint != None: return extruderOffReversalPoint bevelRadius = min( thirdAfterSegmentLength, self.filletRadius ) bevelRadius = min( thirdBeforeSegmentLength, bevelRadius ) self.shouldAddLine = False beforePoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( beforeSegment ) / abs( beforeSegmentComplex ), location, beforeSegment ) self.addLinearMovePoint( self.feedRateMinute, beforePoint ) afterPoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( afterSegment ) / abs( afterSegmentComplex ), location, afterSegment ) # self.addLinearMovePoint( self.feedRateMinute, afterPoint ) afterPointComplex = afterPoint.dropAxis( 2 ) beforePointComplex = beforePoint.dropAxis( 2 ) locationComplex = location.dropAxis( 2 ) midPoint = 0.5 * ( afterPoint + beforePoint ) midPointComplex = midPoint.dropAxis( 2 ) midPointMinusLocationComplex = midPointComplex - locationComplex midPointLocationLength = abs( midPointMinusLocationComplex ) if midPointLocationLength < 0.01 * self.filletRadius: self.addLinearMovePoint( self.getCornerFeedRate(), afterPoint ) return afterPoint midPointAfterPointLength = abs( midPointComplex - afterPointComplex ) midPointCenterLength = midPointAfterPointLength * midPointAfterPointLength / midPointLocationLength radius = math.sqrt( midPointCenterLength * midPointCenterLength + midPointAfterPointLength * midPointAfterPointLength ) centerComplex = midPointComplex + midPointMinusLocationComplex * midPointCenterLength / midPointLocationLength center = Vector3( centerComplex.real, centerComplex.imag, midPoint.z ) afterCenterComplex = afterPointComplex - centerComplex beforeMinusCenterCenterComplex = beforePointComplex - centerComplex beforeCenter = beforePoint - center beforeCenterComplex = beforeCenter.dropAxis( 2 ) subtractComplexMirror = complex( beforeCenterComplex.real , - beforeCenterComplex.imag ) differenceComplex = subtractComplexMirror * afterCenterComplex differenceAngle = math.atan2( differenceComplex.imag, differenceComplex.real ) self.addArc( differenceAngle, afterPoint, beforeCenter, beforePoint, center ) return afterPoint # afterSegment = nextLocation - location afterSegmentLength = afterSegment.magnitude() afterSegmentExtension = 0.5 * afterSegmentLength if afterSegmentExtension == 0.0: return location beforeSegment = self.oldLocation - location beforeSegmentLength = beforeSegment.magnitude() if beforeSegmentLength == 0.0: return location radius = self.filletRadius afterSegmentNormalized = afterSegment / afterSegmentLength beforeSegmentNormalized = beforeSegment / beforeSegmentLength betweenCenterDotNormalized = afterSegmentNormalized + beforeSegmentNormalized if betweenCenterDotNormalized.magnitude() < 0.01 * self.filletRadius: return location extruderOffReversalPoint = self.getExtruderOffReversalPoint( afterSegment, beforeSegment, location ) if extruderOffReversalPoint != None: return extruderOffReversalPoint betweenCenterDotNormalized.normalize() beforeSegmentNormalizedWiddershins = euclidean.getRotatedWiddershinsQuarterAroundZAxis( beforeSegmentNormalized ) betweenAfterPlaneDot = abs( euclidean.getPlaneDot( betweenCenterDotNormalized, beforeSegmentNormalizedWiddershins ) ) if betweenAfterPlaneDot <= 0.0: return nextLocation centerDotDistance = radius / betweenAfterPlaneDot bevelLength = math.sqrt( centerDotDistance * centerDotDistance - radius * radius ) radiusOverBevelLength = radius / bevelLength bevelLength = min( bevelLength, radius ) bevelLength = min( afterSegmentExtension, bevelLength ) beforePoint = self.oldLocation if beforeSegmentLength < bevelLength: bevelLength = beforeSegmentLength else: beforePoint = euclidean.getPointPlusSegmentWithLength( bevelLength, location, beforeSegment ) self.addLinearMovePoint( self.feedRateMinute, beforePoint ) self.shouldAddLine = False afterPoint = euclidean.getPointPlusSegmentWithLength( bevelLength, location, afterSegment ) radius = bevelLength * radiusOverBevelLength centerDotDistance = radius / betweenAfterPlaneDot center = location + betweenCenterDotNormalized * centerDotDistance afterCenterSegment = afterPoint - center beforeCenterSegment = beforePoint - center afterCenterDifferenceAngle = euclidean.getAngleAroundZAxisDifference( afterCenterSegment, beforeCenterSegment ) if afterCenterDifferenceAngle <= 0.0: self.addLinearMovePoint( self.getCornerFeedRate(), afterPoint ) return afterPoint self.addArc( afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center ) print( 'center' ) print( center ) print( afterCenterDifferenceAngle ) print( centerComplex ) print( differenceAngle ) return afterPoint