Esempio n. 1
0
def getWedgePath(begin, centerBegin, centerEnd, centerEndMinusBegin, end,
                 path):
    "Get segment path."
    beginComplex = begin.dropAxis()
    centerBeginComplex = centerBegin.dropAxis()
    centerEndComplex = centerEnd.dropAxis()
    endComplex = end.dropAxis()
    wedgePath = []
    centerBeginMinusBeginComplex = euclidean.getNormalized(centerBeginComplex -
                                                           beginComplex)
    centerEndMinusCenterBeginComplexOriginal = centerEndComplex - centerBeginComplex
    centerEndMinusCenterBeginComplexLength = abs(
        centerEndMinusCenterBeginComplexOriginal)
    if centerEndMinusCenterBeginComplexLength <= 0.0:
        return [centerBegin]
    centerEndMinusCenterBeginComplex = centerEndMinusCenterBeginComplexOriginal / centerEndMinusCenterBeginComplexLength
    endMinusCenterEndComplex = euclidean.getNormalized(endComplex -
                                                       centerEndComplex)
    widdershinsBegin = getWiddershinsAverageByVector3(
        centerBeginMinusBeginComplex, centerEndMinusCenterBeginComplex)
    widdershinsEnd = getWiddershinsAverageByVector3(
        centerEndMinusCenterBeginComplex, endMinusCenterEndComplex)
    for point in path:
        weightEnd = point.x
        weightBegin = 1.0 - weightEnd
        polygonPoint = centerBegin + centerEndMinusBegin * point.x
        weightedWiddershins = widdershinsBegin * weightBegin + widdershinsEnd * weightEnd
        polygonPoint += weightedWiddershins * point.y * centerEndMinusCenterBeginComplexLength
        polygonPoint.z += point.z
        wedgePath.append(polygonPoint)
    return wedgePath
Esempio n. 2
0
def getWedgePath( begin, centerBegin, centerEnd, centerEndMinusBegin, end, path ):
	"Get segment path."
	beginComplex = begin.dropAxis()
	centerBeginComplex = centerBegin.dropAxis()
	centerEndComplex = centerEnd.dropAxis()
	endComplex = end.dropAxis()
	wedgePath = []
	centerBeginMinusBeginComplex = euclidean.getNormalized( centerBeginComplex - beginComplex )
	centerEndMinusCenterBeginComplexOriginal = centerEndComplex - centerBeginComplex
	centerEndMinusCenterBeginComplexLength = abs( centerEndMinusCenterBeginComplexOriginal )
	if centerEndMinusCenterBeginComplexLength <= 0.0:
		return [ centerBegin ]
	centerEndMinusCenterBeginComplex = centerEndMinusCenterBeginComplexOriginal / centerEndMinusCenterBeginComplexLength
	endMinusCenterEndComplex = euclidean.getNormalized( endComplex - centerEndComplex )
	widdershinsBegin = getWiddershinsAverageByVector3( centerBeginMinusBeginComplex, centerEndMinusCenterBeginComplex )
	widdershinsEnd = getWiddershinsAverageByVector3( centerEndMinusCenterBeginComplex, endMinusCenterEndComplex )
	for point in path:
		weightEnd = point.x
		weightBegin = 1.0 - weightEnd
		polygonPoint = centerBegin + centerEndMinusBegin * point.x
		weightedWiddershins = widdershinsBegin * weightBegin + widdershinsEnd * weightEnd
		polygonPoint += weightedWiddershins * point.y * centerEndMinusCenterBeginComplexLength
		polygonPoint.z += point.z
		wedgePath.append( polygonPoint )
	return wedgePath
Esempio n. 3
0
def getIsInsetPointInsideLoops( inside, loops, pointBegin, pointCenter, pointEnd, radius ):
	"Determine if the inset point is inside the loops."
	centerMinusBegin = euclidean.getNormalized( pointCenter - pointBegin )
	centerMinusBeginWiddershins = complex( - centerMinusBegin.imag, centerMinusBegin.real )
	endMinusCenter = euclidean.getNormalized( pointEnd - pointCenter )
	endMinusCenterWiddershins = complex( - endMinusCenter.imag, endMinusCenter.real )
	widdershinsNormalized = euclidean.getNormalized( centerMinusBeginWiddershins + endMinusCenterWiddershins ) * radius
	return euclidean.getIsInFilledRegion( loops,  pointCenter + widdershinsNormalized ) == inside
Esempio n. 4
0
def getIsInsetPointInsideLoops( inside, loops, pointBegin, pointCenter, pointEnd, radius ):
	'Determine if the inset point is inside the loops.'
	centerMinusBegin = euclidean.getNormalized( pointCenter - pointBegin )
	centerMinusBeginWiddershins = complex( - centerMinusBegin.imag, centerMinusBegin.real )
	endMinusCenter = euclidean.getNormalized( pointEnd - pointCenter )
	endMinusCenterWiddershins = complex( - endMinusCenter.imag, endMinusCenter.real )
	widdershinsNormalized = euclidean.getNormalized( centerMinusBeginWiddershins + endMinusCenterWiddershins ) * radius
	return euclidean.getIsInFilledRegion( loops,  pointCenter + widdershinsNormalized ) == inside
Esempio n. 5
0
 def addSmoothedInfill(self):
     "Add smoothed infill."
     if len(self.infill) < 4:
         self.distanceFeedRate.addGcodeFromFeedRateThreadZ(
             self.feedRateMinute, self.infill, self.travelFeedRateMinute, self.oldLocation.z
         )
         return
     self.distanceFeedRate.addGcodeMovementZWithFeedRate(
         self.travelFeedRateMinute, self.infill[0], self.oldLocation.z
     )
     self.distanceFeedRate.addLine("M101")
     lengthMinusOne = len(self.infill) - 1
     lengthMinusTwo = lengthMinusOne - 1
     wasOriginalPoint = True
     pointIndex = 0
     while pointIndex < lengthMinusOne:
         nextPoint = self.infill[pointIndex + 1]
         afterNextIndex = pointIndex + 2
         if afterNextIndex < lengthMinusTwo:
             point = self.infill[pointIndex]
             midpoint = 0.5 * (point + nextPoint)
             afterNextPoint = self.infill[afterNextIndex]
             afterNextNextPoint = self.infill[afterNextIndex + 1]
             afterNextMidpoint = 0.5 * (afterNextPoint + afterNextNextPoint)
             shortcutDistance = abs(afterNextMidpoint - midpoint)
             originalDistance = (
                 abs(midpoint - point) + abs(afterNextPoint - nextPoint) + abs(afterNextMidpoint - afterNextPoint)
             )
             segment = euclidean.getNormalized(nextPoint - point)
             afterNextSegment = euclidean.getNormalized(afterNextNextPoint - afterNextPoint)
             sameDirection = self.getIsParallelToRotation(segment) and self.getIsParallelToRotation(afterNextSegment)
             if (
                 originalDistance - shortcutDistance < self.maximumShortening
                 and shortcutDistance < self.maximumDistance
                 and sameDirection
             ):
                 if wasOriginalPoint:
                     self.distanceFeedRate.addGcodeMovementZWithFeedRate(
                         self.feedRateMinute, midpoint, self.oldLocation.z
                     )
                 feedrate = self.feedRateMinute
                 if originalDistance != 0.0:
                     feedrate *= shortcutDistance / originalDistance
                 self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedrate, afterNextMidpoint, self.oldLocation.z)
                 wasOriginalPoint = False
                 pointIndex += 1
             else:
                 self.distanceFeedRate.addGcodeMovementZWithFeedRate(
                     self.feedRateMinute, nextPoint, self.oldLocation.z
                 )
                 wasOriginalPoint = True
         else:
             self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, nextPoint, self.oldLocation.z)
             wasOriginalPoint = True
         pointIndex += 1
     self.distanceFeedRate.addLine("M103")
Esempio n. 6
0
 def addSmoothedInfill(self):
     'Add smoothed infill.'
     if len(self.infill) < 4:
         self.distanceFeedRate.addGcodeFromFeedRateThreadZ(
             self.feedRateMinute, self.infill, self.travelFeedRateMinute,
             self.oldLocation.z)
         return
     self.distanceFeedRate.addGcodeMovementZWithFeedRate(
         self.travelFeedRateMinute, self.infill[0], self.oldLocation.z)
     self.distanceFeedRate.addLine('M101')
     lengthMinusOne = len(self.infill) - 1
     lengthMinusTwo = lengthMinusOne - 1
     wasOriginalPoint = True
     pointIndex = 0
     while pointIndex < lengthMinusOne:
         nextPoint = self.infill[pointIndex + 1]
         afterNextIndex = pointIndex + 2
         if afterNextIndex < lengthMinusTwo:
             point = self.infill[pointIndex]
             midpoint = 0.5 * (point + nextPoint)
             afterNextPoint = self.infill[afterNextIndex]
             afterNextNextPoint = self.infill[afterNextIndex + 1]
             afterNextMidpoint = 0.5 * (afterNextPoint + afterNextNextPoint)
             shortcutDistance = abs(afterNextMidpoint - midpoint)
             originalDistance = abs(midpoint - point) + abs(
                 afterNextPoint - nextPoint) + abs(afterNextMidpoint -
                                                   afterNextPoint)
             segment = euclidean.getNormalized(nextPoint - point)
             afterNextSegment = euclidean.getNormalized(afterNextNextPoint -
                                                        afterNextPoint)
             sameDirection = self.getIsParallelToRotation(
                 segment) and self.getIsParallelToRotation(afterNextSegment)
             if originalDistance - shortcutDistance < self.maximumShortening and shortcutDistance < self.maximumDistance and sameDirection:
                 if wasOriginalPoint:
                     self.distanceFeedRate.addGcodeMovementZWithFeedRate(
                         self.feedRateMinute, midpoint, self.oldLocation.z)
                 feedrate = self.feedRateMinute
                 if originalDistance != 0.0:
                     feedrate *= shortcutDistance / originalDistance
                 self.distanceFeedRate.addGcodeMovementZWithFeedRate(
                     feedrate, afterNextMidpoint, self.oldLocation.z)
                 wasOriginalPoint = False
                 pointIndex += 1
             else:
                 self.distanceFeedRate.addGcodeMovementZWithFeedRate(
                     self.feedRateMinute, nextPoint, self.oldLocation.z)
                 wasOriginalPoint = True
         else:
             self.distanceFeedRate.addGcodeMovementZWithFeedRate(
                 self.feedRateMinute, nextPoint, self.oldLocation.z)
             wasOriginalPoint = True
         pointIndex += 1
     self.distanceFeedRate.addLine('M103')
Esempio n. 7
0
def getInsetPoint( loop, tinyRadius ):
	'Get the inset vertex.'
	pointIndex = getWideAnglePointIndex(loop)
	point = loop[ pointIndex % len(loop) ]
	afterPoint = loop[(pointIndex + 1) % len(loop)]
	beforePoint = loop[ ( pointIndex - 1 ) % len(loop) ]
	afterSegmentNormalized = euclidean.getNormalized( afterPoint - point )
	beforeSegmentNormalized = euclidean.getNormalized( beforePoint - point )
	afterClockwise = complex( afterSegmentNormalized.imag, - afterSegmentNormalized.real )
	beforeWiddershins = complex( - beforeSegmentNormalized.imag, beforeSegmentNormalized.real )
	midpoint = afterClockwise + beforeWiddershins
	midpointNormalized = midpoint / abs( midpoint )
	return point + midpointNormalized * tinyRadius
Esempio n. 8
0
def getInsetPoint( loop, tinyRadius ):
	"Get the inset vertex."
	pointIndex = getWideAnglePointIndex( loop )
	point = loop[ pointIndex % len( loop ) ]
	afterPoint = loop[ ( pointIndex + 1 ) % len( loop ) ]
	beforePoint = loop[ ( pointIndex - 1 ) % len( loop ) ]
	afterSegmentNormalized = euclidean.getNormalized( afterPoint - point )
	beforeSegmentNormalized = euclidean.getNormalized( beforePoint - point )
	afterClockwise = complex( afterSegmentNormalized.imag, - afterSegmentNormalized.real )
	beforeWiddershins = complex( - beforeSegmentNormalized.imag, beforeSegmentNormalized.real )
	midpoint = afterClockwise + beforeWiddershins
	midpointNormalized = midpoint / abs( midpoint )
	return point + midpointNormalized * tinyRadius
Esempio n. 9
0
def getManipulatedPaths(close, loop, prefix, sideLength, xmlElement):
    "Get path with overhangs removed or filled in."
    if len(loop) < 3:
        return [loop]
    if not evaluate.getEvaluatedBooleanDefault(True, prefix + 'activate',
                                               xmlElement):
        return [loop]
    overhangAngle = evaluate.getOverhangSupportAngle(xmlElement)
    overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(0.5 * math.pi -
                                                           overhangAngle)
    overhangVerticalAngle = math.radians(
        evaluate.getEvaluatedFloatDefault(0.0, prefix + 'inclination',
                                          xmlElement))
    if overhangVerticalAngle != 0.0:
        overhangVerticalCosine = abs(math.cos(overhangVerticalAngle))
        if overhangVerticalCosine == 0.0:
            return [loop]
        imaginaryTimesCosine = overhangPlaneAngle.imag * overhangVerticalCosine
        overhangPlaneAngle = euclidean.getNormalized(
            complex(overhangPlaneAngle.real, imaginaryTimesCosine))
    alongAway = AlongAway(loop, overhangPlaneAngle)
    if euclidean.getIsWiddershinsByVector3(loop):
        alterWiddershinsSupportedPath(alongAway, close)
    else:
        alterClockwiseSupportedPath(alongAway, xmlElement)
    return [
        euclidean.getLoopWithoutCloseSequentialPoints(close, alongAway.loop)
    ]
Esempio n. 10
0
def getManipulatedPaths(close, loop, prefix, xmlElement):
    "Get path with overhangs removed or filled in."
    if len(loop) < 3:
        return [loop]
    overhangAngle = math.radians(
        xmlElement.getCascadeFloat(45.0, 'overhangangle'))
    overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(0.5 * math.pi -
                                                           overhangAngle)
    overhangVerticalAngle = math.radians(
        evaluate.getEvaluatedFloatZero(prefix + 'verticalangle', xmlElement))
    if overhangVerticalAngle != 0.0:
        overhangVerticalCosine = abs(math.cos(overhangVerticalAngle))
        if overhangVerticalCosine == 0.0:
            return [loop]
        imaginaryTimesCosine = overhangPlaneAngle.imag * overhangVerticalCosine
        overhangPlaneAngle = euclidean.getNormalized(
            complex(overhangPlaneAngle.real, imaginaryTimesCosine))
    alongAway = AlongAway(loop, overhangPlaneAngle)
    if euclidean.getIsWiddershinsByVector3(loop):
        alterWiddershinsSupportedPath(alongAway, close)
    else:
        alterClockwiseSupportedPath(alongAway, xmlElement)
    return [
        euclidean.getLoopWithoutCloseSequentialPoints(close, alongAway.loop)
    ]
Esempio n. 11
0
 def getCircleIntersectionAhead(self):
     "Get the first circle intersection on the circle node ahead."
     circleIntersections = self.circleNodeAhead.circleIntersections
     circleIntersectionAhead = None
     largestDot = -912345678.0
     for circleIntersection in circleIntersections:
         if not circleIntersection.steppedOn:
             circleIntersectionRelativeToMidpoint = euclidean.getNormalized(
                 circleIntersection.positionRelativeToBehind + self.aheadMinusBehind
             )
             dot = euclidean.getDotProduct(self.demichord, circleIntersectionRelativeToMidpoint)
             if dot > largestDot:
                 largestDot = dot
                 circleIntersectionAhead = circleIntersection
     if circleIntersectionAhead == None:
         print("Warning, circleIntersectionAhead in getCircleIntersectionAhead in intercircle is None for:")
         print(self.circleNodeAhead.dividedPoint)
         print("circleIntersectionsAhead")
         for circleIntersection in circleIntersections:
             print(circleIntersection.circleNodeAhead.dividedPoint)
         print("circleIntersectionsBehind")
         for circleIntersection in self.circleNodeBehind.circleIntersections:
             print(circleIntersection.circleNodeAhead.dividedPoint)
         print("This may lead to a loop not being sliced.")
         print(
             "If this is a problem, you may as well send a bug report, even though I probably can not fix this particular problem."
         )
     return circleIntersectionAhead
Esempio n. 12
0
def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
    "Get path with overhangs removed or filled in."
    if len(loop) < 3:
        print(
            'Warning, loop has less than three sides in getManipulatedPaths in overhang for:'
        )
        print(elementNode)
        return [loop]
    derivation = OverhangDerivation(elementNode, prefix)
    overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(
        0.5 * math.pi - derivation.overhangRadians)
    if derivation.overhangInclinationRadians != 0.0:
        overhangInclinationCosine = abs(
            math.cos(derivation.overhangInclinationRadians))
        if overhangInclinationCosine == 0.0:
            return [loop]
        imaginaryTimesCosine = overhangPlaneAngle.imag * overhangInclinationCosine
        overhangPlaneAngle = euclidean.getNormalized(
            complex(overhangPlaneAngle.real, imaginaryTimesCosine))
    alongAway = AlongAway(loop, overhangPlaneAngle)
    if euclidean.getIsWiddershinsByVector3(loop):
        alterWiddershinsSupportedPath(alongAway, close)
    else:
        alterClockwiseSupportedPath(alongAway, elementNode)
    return [
        euclidean.getLoopWithoutCloseSequentialPoints(close, alongAway.loop)
    ]
Esempio n. 13
0
def getGeometryOutput(derivation, xmlElement):
	"Get vector3 vertexes from attribute dictionary."
	if derivation == None:
		derivation = SquareDerivation()
		derivation.setToXMLElement(xmlElement)
	topRight = complex(derivation.topDemiwidth, derivation.demiheight)
	topLeft = complex(-derivation.topDemiwidth, derivation.demiheight)
	bottomLeft = complex(-derivation.bottomDemiwidth, -derivation.demiheight)
	bottomRight = complex(derivation.bottomDemiwidth, -derivation.demiheight)
	if derivation.interiorAngle != 90.0:
		interiorPlaneAngle = euclidean.getWiddershinsUnitPolar(math.radians(derivation.interiorAngle - 90.0))
		topRight = (topRight - bottomRight) * interiorPlaneAngle + bottomRight
		topLeft = (topLeft - bottomLeft) * interiorPlaneAngle + bottomLeft
	lineation.setClosedAttribute(derivation.revolutions, xmlElement)
	complexLoop = [topRight, topLeft, bottomLeft, bottomRight]
	originalLoop = complexLoop[:]
	for revolution in xrange(1, derivation.revolutions):
		complexLoop += originalLoop
	spiral = lineation.Spiral(derivation.spiral, 0.25)
	loop = []
	loopCentroid = euclidean.getLoopCentroid(originalLoop)
	for point in complexLoop:
		unitPolar = euclidean.getNormalized(point - loopCentroid)
		loop.append(spiral.getSpiralPoint(unitPolar, Vector3(point.real, point.imag)))
	return lineation.getGeometryOutputByLoop(lineation.SideLoop(loop, 0.5 * math.pi), xmlElement)
Esempio n. 14
0
def getManipulatedPaths(close, loop, prefix, sideLength, xmlElement):
    "Get path with overhangs removed or filled in."
    if len(loop) < 3:
        print(
            'Warning, loop has less than three sides in getManipulatedPaths in overhang for:'
        )
        print(xmlElement)
        return [loop]
    overhangRadians = setting.getOverhangRadians(xmlElement)
    overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(0.5 * math.pi -
                                                           overhangRadians)
    overhangVerticalRadians = math.radians(
        evaluate.getEvaluatedFloat(0.0, prefix + 'inclination', xmlElement))
    if overhangVerticalRadians != 0.0:
        overhangVerticalCosine = abs(math.cos(overhangVerticalRadians))
        if overhangVerticalCosine == 0.0:
            return [loop]
        imaginaryTimesCosine = overhangPlaneAngle.imag * overhangVerticalCosine
        overhangPlaneAngle = euclidean.getNormalized(
            complex(overhangPlaneAngle.real, imaginaryTimesCosine))
    alongAway = AlongAway(loop, overhangPlaneAngle)
    if euclidean.getIsWiddershinsByVector3(loop):
        alterWiddershinsSupportedPath(alongAway, close)
    else:
        alterClockwiseSupportedPath(alongAway, xmlElement)
    return [
        euclidean.getLoopWithoutCloseSequentialPoints(close, alongAway.loop)
    ]
Esempio n. 15
0
 def getCircleIntersectionAhead(self):
     'Get the first circle intersection on the circle node ahead.'
     circleIntersections = self.circleNodeAhead.circleIntersections
     circleIntersectionAhead = None
     largestDot = -912345678.0
     for circleIntersection in circleIntersections:
         if not circleIntersection.steppedOn:
             circleIntersectionRelativeToMidpoint = euclidean.getNormalized(
                 circleIntersection.positionRelativeToBehind +
                 self.aheadMinusBehind)
             dot = euclidean.getDotProduct(
                 self.demichord, circleIntersectionRelativeToMidpoint)
             if dot > largestDot:
                 largestDot = dot
                 circleIntersectionAhead = circleIntersection
     if circleIntersectionAhead == None:
         print(
             'Warning, circleIntersectionAhead in getCircleIntersectionAhead in intercircle is None for:'
         )
         print(self.circleNodeAhead.dividedPoint)
         print('circleIntersectionsAhead')
         for circleIntersection in circleIntersections:
             print(circleIntersection.circleNodeAhead.dividedPoint)
         print('circleIntersectionsBehind')
         for circleIntersection in self.circleNodeBehind.circleIntersections:
             print(circleIntersection.circleNodeAhead.dividedPoint)
         print('This may lead to a loop not being sliced.')
         print(
             'If this is a problem, you may as well send a bug report, even though I probably can not fix this particular problem.'
         )
     return circleIntersectionAhead
Esempio n. 16
0
def getGeometryOutput(derivation, elementNode):
    "Get vector3 vertexes from attribute dictionary."
    if derivation is None:
        derivation = SquareDerivation(elementNode)
    topRight = complex(derivation.topDemiwidth, derivation.demiheight)
    topLeft = complex(-derivation.topDemiwidth, derivation.demiheight)
    bottomLeft = complex(-derivation.bottomDemiwidth, -derivation.demiheight)
    bottomRight = complex(derivation.bottomDemiwidth, -derivation.demiheight)
    if derivation.interiorAngle != 90.0:
        interiorPlaneAngle = euclidean.getWiddershinsUnitPolar(
            math.radians(derivation.interiorAngle - 90.0))
        topRight = (topRight - bottomRight) * interiorPlaneAngle + bottomRight
        topLeft = (topLeft - bottomLeft) * interiorPlaneAngle + bottomLeft
    lineation.setClosedAttribute(elementNode, derivation.revolutions)
    complexLoop = [topRight, topLeft, bottomLeft, bottomRight]
    originalLoop = complexLoop[:]
    for revolution in xrange(1, derivation.revolutions):
        complexLoop += originalLoop
    spiral = lineation.Spiral(derivation.spiral, 0.25)
    loop = []
    loopCentroid = euclidean.getLoopCentroid(originalLoop)
    for point in complexLoop:
        unitPolar = euclidean.getNormalized(point - loopCentroid)
        loop.append(
            spiral.getSpiralPoint(unitPolar, Vector3(point.real, point.imag)))
    return lineation.getGeometryOutputByLoop(
        elementNode, lineation.SideLoop(loop, 0.5 * math.pi))
Esempio n. 17
0
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
Esempio n. 18
0
def getToothProfileCylinder(gearDerivation, pitchRadius, teeth):
    'Get profile for one tooth of a cylindrical gear.'
    toothProfile = getToothProfileHalfCylinder(gearDerivation, pitchRadius,
                                               teeth)
    profileFirst = toothProfile[0]
    profileSecond = toothProfile[1]
    firstMinusSecond = profileFirst - profileSecond
    remainingDedendum = abs(
        profileFirst) - pitchRadius + gearDerivation.dedendum
    firstMinusSecond *= remainingDedendum / abs(firstMinusSecond)
    extensionPoint = profileFirst + firstMinusSecond
    if gearDerivation.bevel <= 0.0:
        toothProfile.insert(0, extensionPoint)
        return getMirrorPath(toothProfile)
    unitPolar = euclidean.getWiddershinsUnitPolar(-2.0 / float(teeth) *
                                                  math.pi)
    mirrorExtensionPoint = complex(-extensionPoint.real,
                                   extensionPoint.imag) * unitPolar
    mirrorMinusExtension = euclidean.getNormalized(mirrorExtensionPoint -
                                                   extensionPoint)
    if remainingDedendum <= gearDerivation.bevel:
        toothProfile.insert(
            0,
            complex(extensionPoint.real, extensionPoint.imag) +
            remainingDedendum * mirrorMinusExtension)
        return getMirrorPath(toothProfile)
    firstMinusSecond *= (remainingDedendum -
                         gearDerivation.bevel) / abs(firstMinusSecond)
    toothProfile.insert(0, profileFirst + firstMinusSecond)
    toothProfile.insert(
        0,
        complex(extensionPoint.real, extensionPoint.imag) +
        gearDerivation.bevel * mirrorMinusExtension)
    return getMirrorPath(toothProfile)
Esempio n. 19
0
 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
Esempio n. 20
0
def getGeometryOutput(xmlElement):
	"Get vector3 vertexes from attribute dictionary."
	inradius = lineation.getComplexByPrefixes(['demisize', 'inradius'], complex(1.0, 1.0), xmlElement)
	inradius = lineation.getComplexByMultiplierPrefix(2.0, 'size', inradius, xmlElement)
	demiwidth = lineation.getFloatByPrefixBeginEnd('demiwidth', 'width', inradius.real, xmlElement)
	demiheight = lineation.getFloatByPrefixBeginEnd('demiheight', 'height', inradius.imag, xmlElement)
	bottomDemiwidth = lineation.getFloatByPrefixBeginEnd('bottomdemiwidth', 'bottomwidth', demiwidth, xmlElement)
	topDemiwidth = lineation.getFloatByPrefixBeginEnd('topdemiwidth', 'topwidth', demiwidth, xmlElement)
	interiorAngle = evaluate.getEvaluatedFloatDefault(90.0, 'interiorangle', xmlElement)
	topRight = complex(topDemiwidth, demiheight)
	topLeft = complex(-topDemiwidth, demiheight)
	bottomLeft = complex(-bottomDemiwidth, -demiheight)
	bottomRight = complex(bottomDemiwidth, -demiheight)
	if interiorAngle != 90.0:
		interiorPlaneAngle = euclidean.getWiddershinsUnitPolar(math.radians(interiorAngle - 90.0))
		topRight = (topRight - bottomRight) * interiorPlaneAngle + bottomRight
		topLeft = (topLeft - bottomLeft) * interiorPlaneAngle + bottomLeft
	revolutions = evaluate.getEvaluatedIntOne('revolutions', xmlElement)
	lineation.setClosedAttribute(revolutions, xmlElement)
	complexLoop = [topRight, topLeft, bottomLeft, bottomRight]
	originalLoop = complexLoop[:]
	for revolution in xrange(1, revolutions):
		complexLoop += originalLoop
	spiral = lineation.Spiral(0.25, xmlElement)
	loop = []
	loopCentroid = euclidean.getLoopCentroid(originalLoop)
	for point in complexLoop:
		unitPolar = euclidean.getNormalized(point - loopCentroid)
		loop.append(spiral.getSpiralPoint(unitPolar, Vector3(point.real, point.imag)))
	return lineation.getGeometryOutputByLoop(lineation.SideLoop(loop, 0.5 * math.pi), xmlElement)
Esempio n. 21
0
def getInsetFromClockwiseTriple(aheadAbsolute, behindAbsolute, center, radius):
    "Get loop inset from clockwise triple, out from widdershins loop."
    originalCenterMinusBehind = euclidean.getNormalized(center -
                                                        behindAbsolute)
    reverseRoundZAngle = complex(originalCenterMinusBehind.real,
                                 -originalCenterMinusBehind.imag)
    rotatedAheadAbsolute = aheadAbsolute * reverseRoundZAngle
    rotatedBehindAbsolute = behindAbsolute * reverseRoundZAngle
    rotatedCenter = center * reverseRoundZAngle
    aheadIntersection = getIntersectionAtInset(rotatedAheadAbsolute,
                                               rotatedCenter, radius)
    behindIntersection = getIntersectionAtInset(rotatedCenter,
                                                rotatedBehindAbsolute, radius)
    centerMinusAhead = rotatedCenter - rotatedAheadAbsolute
    if abs(centerMinusAhead.imag) < abs(0.00001 * centerMinusAhead.real):
        between = 0.5 * (aheadIntersection + behindIntersection)
        return originalCenterMinusBehind * between
    yMinusAhead = behindIntersection.imag - aheadIntersection.imag
    x = aheadIntersection.real + yMinusAhead * centerMinusAhead.real / centerMinusAhead.imag
    insetFromClockwiseTriple = originalCenterMinusBehind * complex(
        x, behindIntersection.imag)
    insetMinusOriginal = insetFromClockwiseTriple - center
    distance = abs(insetMinusOriginal)
    maximumDistance = 2.0 * radius
    if distance < maximumDistance:
        return insetFromClockwiseTriple
    return center + maximumDistance / distance * insetMinusOriginal
Esempio n. 22
0
def getWideAnglePointIndex( loop ):
	"Get a point index which has a wide enough angle, most point indexes have a wide enough angle, this is just to make sure."
	dotProductMinimum = 9999999.9
	widestPointIndex = 0
	for pointIndex in xrange( len( loop ) ):
		point = loop[ pointIndex % len( loop ) ]
		afterPoint = loop[ ( pointIndex + 1 ) % len( loop ) ]
		beforePoint = loop[ ( pointIndex - 1 ) % len( loop ) ]
		afterSegmentNormalized = euclidean.getNormalized( afterPoint - point )
		beforeSegmentNormalized = euclidean.getNormalized( beforePoint - point )
		dotProduct = euclidean.getDotProduct( afterSegmentNormalized, beforeSegmentNormalized )
		if dotProduct < .99:
			return pointIndex
		if dotProduct < dotProductMinimum:
			dotProductMinimum = dotProduct
			widestPointIndex = pointIndex
	return widestPointIndex
Esempio n. 23
0
def getWideAnglePointIndex(loop):
	'Get a point index which has a wide enough angle, most point indexes have a wide enough angle, this is just to make sure.'
	dotProductMinimum = 9999999.9
	widestPointIndex = 0
	for pointIndex in xrange(len(loop)):
		point = loop[ pointIndex % len(loop) ]
		afterPoint = loop[(pointIndex + 1) % len(loop)]
		beforePoint = loop[ ( pointIndex - 1 ) % len(loop) ]
		afterSegmentNormalized = euclidean.getNormalized( afterPoint - point )
		beforeSegmentNormalized = euclidean.getNormalized( beforePoint - point )
		dotProduct = euclidean.getDotProduct( afterSegmentNormalized, beforeSegmentNormalized )
		if dotProduct < .99:
			return pointIndex
		if dotProduct < dotProductMinimum:
			dotProductMinimum = dotProduct
			widestPointIndex = pointIndex
	return widestPointIndex
Esempio n. 24
0
    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]
            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
Esempio n. 25
0
 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
Esempio n. 26
0
def isLoopIntersectingLoop( anotherLoop, loop ):
	'Determine if the a loop is intersecting another loop.'
	for pointIndex in xrange(len(loop)):
		pointFirst = loop[pointIndex]
		pointSecond = loop[(pointIndex + 1) % len(loop)]
		segment = pointFirst - pointSecond
		normalizedSegment = euclidean.getNormalized(segment)
		segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag)
		segmentFirstPoint = segmentYMirror * pointFirst
		segmentSecondPoint = segmentYMirror * pointSecond
		if euclidean.isLoopIntersectingInsideXSegment( anotherLoop, segmentFirstPoint.real, segmentSecondPoint.real, segmentYMirror, segmentFirstPoint.imag ):
			return True
	return False
Esempio n. 27
0
	def getPathBetween( self, loop, points ):
		"Add a path between the perimeter and the fill."
		paths = getPathsByIntersectedLoop( points[ 1 ], points[ 2 ], loop )
		shortestPath = paths[ int( euclidean.getPathLength( paths[ 1 ] ) < euclidean.getPathLength( paths[ 0 ] ) ) ]
		if not euclidean.isWiddershins( shortestPath ):
			shortestPath.reverse()
		loopAround = intercircle.getLargestInsetLoopFromLoopNoMatterWhat( shortestPath, - self.combInset )
		endMinusBegin = points[ 3 ] - points[ 0 ]
		endMinusBegin = 1.3 * self.combInset * euclidean.getNormalized( endMinusBegin )
		aroundPaths = getPathsByIntersectedLoop( points[ 0 ] - endMinusBegin, points[ 3 ] + endMinusBegin, loopAround )
		insidePath = aroundPaths[ int( getInsideness( aroundPaths[ 1 ], loop ) > getInsideness( aroundPaths[ 0 ], loop ) ) ]
		pathBetween = []
		for point in insidePath:
			if euclidean.isPointInsideLoop( loop, point ):
				pathBetween.append(point )
		return pathBetween
Esempio n. 28
0
	def getCircleIntersectionAhead( self ):
		"Get the first circle intersection on the circle node ahead."
		circleIntersections = self.circleNodeAhead.circleIntersections
		circleIntersectionAhead = None
		largestDot = - 999999999.0
		for circleIntersection in circleIntersections:
			if not circleIntersection.steppedOn:
				circleIntersectionRelativeToMidpoint = euclidean.getNormalized( circleIntersection.positionRelativeToBehind + self.aheadMinusBehind )
				dot = euclidean.getDotProduct( self.demichord, circleIntersectionRelativeToMidpoint )
				if dot > largestDot:
					largestDot = dot
					circleIntersectionAhead = circleIntersection
		if circleIntersectionAhead == None:
			print( 'this should never happen, circleIntersectionAhead in intercircle is None' )
			print( self.circleNodeAhead.circle )
			for circleIntersection in circleIntersections:
				print( circleIntersection.circleNodeAhead.circle )
		return circleIntersectionAhead
Esempio n. 29
0
def getManipulatedPaths(close, loop, prefix, xmlElement):
    "Get path with overhangs removed or filled in."
    if len(loop) < 3:
        return [loop]
    overhangAngle = math.radians(xmlElement.getCascadeFloat(45.0, "overhangangle"))
    overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(0.5 * math.pi - overhangAngle)
    overhangVerticalAngle = math.radians(evaluate.getEvaluatedFloatZero(prefix + "verticalangle", xmlElement))
    if overhangVerticalAngle != 0.0:
        overhangVerticalCosine = abs(math.cos(overhangVerticalAngle))
        if overhangVerticalCosine == 0.0:
            return [loop]
        imaginaryTimesCosine = overhangPlaneAngle.imag * overhangVerticalCosine
        overhangPlaneAngle = euclidean.getNormalized(complex(overhangPlaneAngle.real, imaginaryTimesCosine))
    alongAway = AlongAway(loop, overhangPlaneAngle)
    if euclidean.getIsWiddershinsByVector3(loop):
        alterWiddershinsSupportedPath(alongAway, close)
    else:
        alterClockwiseSupportedPath(alongAway, xmlElement)
    return [euclidean.getLoopWithoutCloseSequentialPoints(close, alongAway.loop)]
Esempio n. 30
0
def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
	"Get path with overhangs removed or filled in."
	if len(loop) < 3:
		print('Warning, loop has less than three sides in getManipulatedPaths in overhang for:')
		print(elementNode)
		return [loop]
	derivation = OverhangDerivation(elementNode, prefix)
	overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(0.5 * math.pi - derivation.overhangRadians)
	if derivation.overhangInclinationRadians != 0.0:
		overhangInclinationCosine = abs(math.cos(derivation.overhangInclinationRadians))
		if overhangInclinationCosine == 0.0:
			return [loop]
		imaginaryTimesCosine = overhangPlaneAngle.imag * overhangInclinationCosine
		overhangPlaneAngle = euclidean.getNormalized(complex(overhangPlaneAngle.real, imaginaryTimesCosine))
	alongAway = AlongAway(loop, overhangPlaneAngle)
	if euclidean.getIsWiddershinsByVector3(loop):
		alterWiddershinsSupportedPath(alongAway, close)
	else:
		alterClockwiseSupportedPath(alongAway, elementNode)
	return [euclidean.getLoopWithoutCloseSequentialPoints(close,  alongAway.loop)]
Esempio n. 31
0
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
Esempio n. 32
0
def getGeometryOutput(xmlElement):
    "Get vector3 vertexes from attribute dictionary."
    inradius = lineation.getComplexByPrefixes(['demisize', 'inradius'],
                                              complex(1.0, 1.0), xmlElement)
    inradius = lineation.getComplexByMultiplierPrefix(2.0, 'size', inradius,
                                                      xmlElement)
    demiwidth = lineation.getFloatByPrefixBeginEnd('demiwidth', 'width',
                                                   inradius.real, xmlElement)
    demiheight = lineation.getFloatByPrefixBeginEnd('demiheight', 'height',
                                                    inradius.imag, xmlElement)
    bottomDemiwidth = lineation.getFloatByPrefixBeginEnd(
        'bottomdemiwidth', 'bottomwidth', demiwidth, xmlElement)
    topDemiwidth = lineation.getFloatByPrefixBeginEnd('topdemiwidth',
                                                      'topwidth', demiwidth,
                                                      xmlElement)
    interiorAngle = evaluate.getEvaluatedFloatDefault(90.0, 'interiorangle',
                                                      xmlElement)
    topRight = complex(topDemiwidth, demiheight)
    topLeft = complex(-topDemiwidth, demiheight)
    bottomLeft = complex(-bottomDemiwidth, -demiheight)
    bottomRight = complex(bottomDemiwidth, -demiheight)
    if interiorAngle != 90.0:
        interiorPlaneAngle = euclidean.getWiddershinsUnitPolar(
            math.radians(interiorAngle - 90.0))
        topRight = (topRight - bottomRight) * interiorPlaneAngle + bottomRight
        topLeft = (topLeft - bottomLeft) * interiorPlaneAngle + bottomLeft
    revolutions = evaluate.getEvaluatedIntOne('revolutions', xmlElement)
    lineation.setClosedAttribute(revolutions, xmlElement)
    complexLoop = [topRight, topLeft, bottomLeft, bottomRight]
    originalLoop = complexLoop[:]
    for revolution in xrange(1, revolutions):
        complexLoop += originalLoop
    spiral = lineation.Spiral(0.25, xmlElement)
    loop = []
    loopCentroid = euclidean.getLoopCentroid(originalLoop)
    for point in complexLoop:
        unitPolar = euclidean.getNormalized(point - loopCentroid)
        loop.append(
            spiral.getSpiralPoint(unitPolar, Vector3(point.real, point.imag)))
    return lineation.getGeometryOutputByLoop(
        lineation.SideLoop(loop, 0.5 * math.pi), xmlElement)
Esempio n. 33
0
def getManipulatedPaths(close, loop, prefix, sideLength, xmlElement):
	"Get path with overhangs removed or filled in."
	if len(loop) < 3:
		return [loop]
	if not evaluate.getEvaluatedBooleanDefault( True, prefix + 'activate', xmlElement ):
		return [loop]
	overhangAngle = evaluate.getOverhangSupportAngle(xmlElement)
	overhangPlaneAngle = euclidean.getWiddershinsUnitPolar( 0.5 * math.pi - overhangAngle )
	overhangVerticalAngle = math.radians( evaluate.getEvaluatedFloatDefault(0.0,  prefix + 'inclination', xmlElement ) )
	if overhangVerticalAngle != 0.0:
		overhangVerticalCosine = abs( math.cos( overhangVerticalAngle ) )
		if overhangVerticalCosine == 0.0:
			return [loop]
		imaginaryTimesCosine = overhangPlaneAngle.imag * overhangVerticalCosine
		overhangPlaneAngle = euclidean.getNormalized( complex( overhangPlaneAngle.real, imaginaryTimesCosine ) )
	alongAway = AlongAway( loop, overhangPlaneAngle )
	if euclidean.getIsWiddershinsByVector3(loop):
		alterWiddershinsSupportedPath( alongAway, close )
	else:
		alterClockwiseSupportedPath( alongAway, xmlElement )
	return [ euclidean.getLoopWithoutCloseSequentialPoints( close,  alongAway.loop ) ]
Esempio n. 34
0
def getManipulatedPaths(close, loop, prefix, sideLength, xmlElement):
	"""Get path with overhangs removed or filled in."""
	if len(loop) < 3:
		print('Warning, loop has less than three sides in getManipulatedPaths in overhang for:')
		print(xmlElement)
		return [loop]
	overhangRadians = setting.getOverhangRadians(xmlElement)
	overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(0.5 * math.pi - overhangRadians)
	overhangVerticalRadians = math.radians(evaluate.getEvaluatedFloat(0.0,  prefix + 'inclination', xmlElement))
	if overhangVerticalRadians != 0.0:
		overhangVerticalCosine = abs(math.cos(overhangVerticalRadians))
		if overhangVerticalCosine == 0.0:
			return [loop]
		imaginaryTimesCosine = overhangPlaneAngle.imag * overhangVerticalCosine
		overhangPlaneAngle = euclidean.getNormalized(complex(overhangPlaneAngle.real, imaginaryTimesCosine))
	alongAway = AlongAway(loop, overhangPlaneAngle)
	if euclidean.getIsWiddershinsByVector3(loop):
		alterWiddershinsSupportedPath(alongAway, close)
	else:
		alterClockwiseSupportedPath(alongAway, xmlElement)
	return [euclidean.getLoopWithoutCloseSequentialPoints(close,  alongAway.loop)]
Esempio n. 35
0
def getToothProfileCylinder(gearDerivation, pitchRadius, teeth):
	'Get profile for one tooth of a cylindrical gear.'
	toothProfile = getToothProfileHalfCylinder(gearDerivation, pitchRadius, teeth)
	profileFirst = toothProfile[0]
	profileSecond = toothProfile[1]
	firstMinusSecond = profileFirst - profileSecond
	remainingDedendum = abs(profileFirst) - pitchRadius + gearDerivation.dedendum
	firstMinusSecond *= remainingDedendum / abs(firstMinusSecond)
	extensionPoint = profileFirst + firstMinusSecond
	if gearDerivation.bevel <= 0.0:
		toothProfile.insert(0, extensionPoint)
		return getMirrorPath(toothProfile)
	unitPolar = euclidean.getWiddershinsUnitPolar(-2.0 / float(teeth) * math.pi)
	mirrorExtensionPoint = complex(-extensionPoint.real, extensionPoint.imag) * unitPolar
	mirrorMinusExtension = euclidean.getNormalized(mirrorExtensionPoint - extensionPoint)
	if remainingDedendum <= gearDerivation.bevel:
		toothProfile.insert(0, complex(extensionPoint.real, extensionPoint.imag) + remainingDedendum * mirrorMinusExtension)
		return getMirrorPath(toothProfile)
	firstMinusSecond *= (remainingDedendum - gearDerivation.bevel) / abs(firstMinusSecond)
	toothProfile.insert(0, profileFirst + firstMinusSecond)
	toothProfile.insert(0, complex(extensionPoint.real, extensionPoint.imag) + gearDerivation.bevel * mirrorMinusExtension)
	return getMirrorPath(toothProfile)
Esempio n. 36
0
def getInsetFromClockwiseTriple( aheadAbsolute, behindAbsolute, center, radius ):
	"Get loop inset from clockwise triple, out from widdershins loop."
	originalCenterMinusBehind = euclidean.getNormalized( center - behindAbsolute )
	reverseRoundZAngle = complex( originalCenterMinusBehind.real, - originalCenterMinusBehind.imag )
	rotatedAheadAbsolute = aheadAbsolute * reverseRoundZAngle
	rotatedBehindAbsolute = behindAbsolute * reverseRoundZAngle
	rotatedCenter = center * reverseRoundZAngle
	aheadIntersection = getIntersectionAtInset( rotatedAheadAbsolute, rotatedCenter, radius )
	behindIntersection = getIntersectionAtInset( rotatedCenter, rotatedBehindAbsolute, radius )
	centerMinusAhead = rotatedCenter - rotatedAheadAbsolute
	if abs( centerMinusAhead.imag ) < abs( 0.00001 * centerMinusAhead.real ):
		between = 0.5 * ( aheadIntersection + behindIntersection )
		return originalCenterMinusBehind * between
	yMinusAhead = behindIntersection.imag - aheadIntersection.imag
	x = aheadIntersection.real + yMinusAhead * centerMinusAhead.real / centerMinusAhead.imag
	insetFromClockwiseTriple = originalCenterMinusBehind * complex( x, behindIntersection.imag )
	insetMinusOriginal = insetFromClockwiseTriple - center
	distance = abs( insetMinusOriginal )
	maximumDistance = 2.0 * radius
	if distance < maximumDistance:
		return insetFromClockwiseTriple
	return center + maximumDistance / distance * insetMinusOriginal
Esempio n. 37
0
 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
Esempio n. 38
0
 def getPathBetween(self, loop, points):
     "Add a path between the perimeter and the fill."
     paths = getPathsByIntersectedLoop(points[1], points[2], loop)
     shortestPath = paths[int(
         euclidean.getPathLength(paths[1]) < euclidean.getPathLength(
             paths[0]))]
     if not euclidean.isWiddershins(shortestPath):
         shortestPath.reverse()
     loopAround = intercircle.getLargestInsetLoopFromLoopNoMatterWhat(
         shortestPath, -self.combInset)
     endMinusBegin = points[3] - points[0]
     endMinusBegin = 1.3 * self.combInset * euclidean.getNormalized(
         endMinusBegin)
     aroundPaths = getPathsByIntersectedLoop(points[0] - endMinusBegin,
                                             points[3] + endMinusBegin,
                                             loopAround)
     insidePath = aroundPaths[int(
         getInsideness(aroundPaths[1], loop) > getInsideness(
             aroundPaths[0], loop))]
     pathBetween = []
     for point in insidePath:
         if euclidean.isPointInsideLoop(loop, point):
             pathBetween.append(point)
     return pathBetween
Esempio n. 39
0
 def getIsPointSupportedBySegment(self, endIndex):
     "Determine if the point on the widdershins loop is supported."
     endComplex = self.loop[(endIndex % len(self.loop))].dropAxis()
     endMinusPointComplex = euclidean.getNormalized(endComplex -
                                                    self.point.dropAxis())
     return endMinusPointComplex.imag < self.ySupport
Esempio n. 40
0
	def getIsPointSupportedBySegment( self, endIndex ):
		"Determine if the point on the widdershins loop is supported."
		endComplex = self.loop[ ( endIndex % len( self.loop ) ) ].dropAxis()
		endMinusPointComplex = euclidean.getNormalized( endComplex - self.point.dropAxis() )
		return endMinusPointComplex.imag < self.ySupport