Пример #1
0
def getRadialPath(begin, center, end, path):
    "Get radial path."
    beginComplex = begin.dropAxis()
    endComplex = end.dropAxis()
    centerComplex = center.dropAxis()
    beginMinusCenterComplex = beginComplex - centerComplex
    endMinusCenterComplex = endComplex - centerComplex
    beginMinusCenterComplexRadius = abs(beginMinusCenterComplex)
    endMinusCenterComplexRadius = abs(endMinusCenterComplex)
    if beginMinusCenterComplexRadius == 0.0 or endMinusCenterComplexRadius == 0.0:
        return [begin]
    beginMinusCenterComplex /= beginMinusCenterComplexRadius
    endMinusCenterComplex /= endMinusCenterComplexRadius
    angleDifference = euclidean.getAngleDifferenceByComplex(
        endMinusCenterComplex, beginMinusCenterComplex)
    radialPath = []
    for point in path:
        weightEnd = point.x
        weightBegin = 1.0 - weightEnd
        weightedRadius = beginMinusCenterComplexRadius * weightBegin + endMinusCenterComplexRadius * weightEnd * (
            1.0 + point.y)
        radialComplex = weightedRadius * euclidean.getWiddershinsUnitPolar(
            angleDifference * point.x) * beginMinusCenterComplex
        polygonPoint = center + Vector3(radialComplex.real, radialComplex.imag,
                                        point.z)
        radialPath.append(polygonPoint)
    return radialPath
Пример #2
0
def getRadialPath(begin, end, path, segmentCenter):
    "Get radial path."
    beginComplex = begin.dropAxis()
    endComplex = end.dropAxis()
    segmentCenterComplex = segmentCenter.dropAxis()
    beginMinusCenterComplex = beginComplex - segmentCenterComplex
    endMinusCenterComplex = endComplex - segmentCenterComplex
    beginMinusCenterComplexRadius = abs(beginMinusCenterComplex)
    endMinusCenterComplexRadius = abs(endMinusCenterComplex)
    if beginMinusCenterComplexRadius == 0.0 or endMinusCenterComplexRadius == 0.0:
        return [begin]
    beginMinusCenterComplex /= beginMinusCenterComplexRadius
    endMinusCenterComplex /= endMinusCenterComplexRadius
    angleDifference = euclidean.getAngleDifferenceByComplex(endMinusCenterComplex, beginMinusCenterComplex)
    radialPath = []
    for point in path:
        weightEnd = point.x
        weightBegin = 1.0 - weightEnd
        weightedRadius = beginMinusCenterComplexRadius * weightBegin + endMinusCenterComplexRadius * weightEnd * (
            1.0 + point.y
        )
        radialComplex = (
            weightedRadius * euclidean.getWiddershinsUnitPolar(angleDifference * point.x) * beginMinusCenterComplex
        )
        polygonPoint = segmentCenter + Vector3(radialComplex.real, radialComplex.imag, point.z)
        radialPath.append(polygonPoint)
    return radialPath
Пример #3
0
 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, afterSegmentComplex, beforeSegment,
         beforeSegmentComplex, 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)
     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
     beforeCenter = beforePoint - center
     angleDifference = euclidean.getAngleDifferenceByComplex(
         afterCenterComplex, beforeCenter.dropAxis())
     self.addArc(angleDifference, afterPoint, beforeCenter, beforePoint,
                 center)
     return afterPoint
Пример #4
0
 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, afterSegmentComplex, beforeSegment, beforeSegmentComplex, 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
     )
     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
     beforeCenter = beforePoint - center
     angleDifference = euclidean.getAngleDifferenceByComplex(afterCenterComplex, beforeCenter.dropAxis())
     self.addArc(angleDifference, afterPoint, beforeCenter, beforePoint, center)
     return afterPoint
Пример #5
0
def getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation):
	'Get the arc complexes, procedure at http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes'
	xAxisRotationComplex = euclidean.getWiddershinsUnitPolar(xAxisRotation)
	reverseXAxisRotationComplex = complex(xAxisRotationComplex.real, -xAxisRotationComplex.imag)
	beginRotated = begin * reverseXAxisRotationComplex
	beginTransformed = complex(beginRotated.real / radius.real, beginRotated.imag / radius.imag)
	endRotated = end * reverseXAxisRotationComplex
	endTransformed = complex(endRotated.real / radius.real, endRotated.imag / radius.imag)
	midpointTransformed = 0.5 * (beginTransformed + endTransformed)
	midMinusBeginTransformed = midpointTransformed - beginTransformed
	midMinusBeginTransformedLength = abs(midMinusBeginTransformed)
	midWiddershinsTransformed = complex(-midMinusBeginTransformed.imag, midMinusBeginTransformed.real)
	midWiddershinsLengthSquared = 1.0 - midMinusBeginTransformedLength * midMinusBeginTransformedLength
	if midWiddershinsLengthSquared < 0.0:
		print('Warning, the radius is too small for getArcComplexes in svgReader')
		print(begin)
		print(end)
		print(radius)
		return []
	midWiddershinsLength = midWiddershinsLengthSquared
	midWiddershinsTransformed *= midWiddershinsLength / abs(midWiddershinsTransformed)
	centerTransformed = midpointTransformed
	if largeArcFlag == sweepFlag:
		centerTransformed -= midWiddershinsTransformed
	else:
		centerTransformed += midWiddershinsTransformed
	beginMinusCenterTransformed = beginTransformed - centerTransformed
	beginMinusCenterTransformedLength = abs(beginMinusCenterTransformed)
	if beginMinusCenterTransformedLength <= 0.0:
		return end
	beginAngle = math.atan2(beginMinusCenterTransformed.imag, beginMinusCenterTransformed.real)
	endMinusCenterTransformed = endTransformed - centerTransformed
	angleDifference = euclidean.getAngleDifferenceByComplex(endMinusCenterTransformed, beginMinusCenterTransformed)
	if sweepFlag:
		if angleDifference < 0.0:
			angleDifference += 2.0 * math.pi
	else:
		if angleDifference > 0.0:
			angleDifference -= 2.0 * math.pi
	global globalSideAngle
	sides = int(math.ceil(abs(angleDifference) / globalSideAngle))
	sideAngle = angleDifference / float(sides)
	arcComplexes = []
	center = complex(centerTransformed.real * radius.real, centerTransformed.imag * radius.imag) * xAxisRotationComplex
	for side in xrange(1, sides):
		unitPolar = euclidean.getWiddershinsUnitPolar(beginAngle + float(side) * sideAngle)
		circumferential = complex(unitPolar.real * radius.real, unitPolar.imag * radius.imag) * beginMinusCenterTransformedLength
		point = center + circumferential * xAxisRotationComplex
		arcComplexes.append(point)
	arcComplexes.append(end)
	return arcComplexes
Пример #6
0
def getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation):
	'Get the arc complexes, procedure at http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes'
	xAxisRotationComplex = euclidean.getWiddershinsUnitPolar(xAxisRotation)
	reverseXAxisRotationComplex = complex(xAxisRotationComplex.real, -xAxisRotationComplex.imag)
	beginRotated = begin * reverseXAxisRotationComplex
	beginTransformed = complex(beginRotated.real / radius.real, beginRotated.imag / radius.imag)
	endRotated = end * reverseXAxisRotationComplex
	endTransformed = complex(endRotated.real / radius.real, endRotated.imag / radius.imag)
	midpointTransformed = 0.5 * (beginTransformed + endTransformed)
	midMinusBeginTransformed = midpointTransformed - beginTransformed
	midMinusBeginTransformedLength = abs(midMinusBeginTransformed)
	midWiddershinsTransformed = complex(-midMinusBeginTransformed.imag, midMinusBeginTransformed.real)
	midWiddershinsLengthSquared = 1.0 - midMinusBeginTransformedLength * midMinusBeginTransformedLength
	if midWiddershinsLengthSquared < 0.0:
		print('Warning, the radius is too small for getArcComplexes in svgReader')
		print(begin)
		print(end)
		print(radius)
		return []
	midWiddershinsLength = midWiddershinsLengthSquared
	midWiddershinsTransformed *= midWiddershinsLength / abs(midWiddershinsTransformed)
	centerTransformed = midpointTransformed
	if largeArcFlag == sweepFlag:
		centerTransformed -= midWiddershinsTransformed
	else:
		centerTransformed += midWiddershinsTransformed
	beginMinusCenterTransformed = beginTransformed - centerTransformed
	beginMinusCenterTransformedLength = abs(beginMinusCenterTransformed)
	if beginMinusCenterTransformedLength <= 0.0:
		return end
	beginAngle = math.atan2(beginMinusCenterTransformed.imag, beginMinusCenterTransformed.real)
	endMinusCenterTransformed = endTransformed - centerTransformed
	angleDifference = euclidean.getAngleDifferenceByComplex(endMinusCenterTransformed, beginMinusCenterTransformed)
	if sweepFlag:
		if angleDifference < 0.0:
			angleDifference += 2.0 * math.pi
	else:
		if angleDifference > 0.0:
			angleDifference -= 2.0 * math.pi
	global globalSideAngle
	sides = int(math.ceil(abs(angleDifference) / globalSideAngle))
	sideAngle = angleDifference / float(sides)
	arcComplexes = []
	center = complex(centerTransformed.real * radius.real, centerTransformed.imag * radius.imag) * xAxisRotationComplex
	for side in xrange(1, sides):
		unitPolar = euclidean.getWiddershinsUnitPolar(beginAngle + float(side) * sideAngle)
		circumferential = complex(unitPolar.real * radius.real, unitPolar.imag * radius.imag) * beginMinusCenterTransformedLength
		point = center + circumferential * xAxisRotationComplex
		arcComplexes.append(point)
	arcComplexes.append(end)
	return arcComplexes
Пример #7
0
def getRoundPath(begin, center, close, end, radius, sidesPerRadian):
    "Get round path."
    beginComplex = begin.dropAxis()
    centerComplex = center.dropAxis()
    endComplex = end.dropAxis()
    beginComplexSegmentLength = abs(centerComplex - beginComplex)
    endComplexSegmentLength = abs(centerComplex - endComplex)
    minimumRadius = lineation.getMinimumRadius(beginComplexSegmentLength,
                                               endComplexSegmentLength, radius)
    if minimumRadius <= close:
        return [center]
    beginBevel = center + minimumRadius / beginComplexSegmentLength * (begin -
                                                                       center)
    endBevel = center + minimumRadius / endComplexSegmentLength * (end -
                                                                   center)
    beginBevelComplex = beginBevel.dropAxis()
    endBevelComplex = endBevel.dropAxis()
    midpointComplex = 0.5 * (beginBevelComplex + endBevelComplex)
    if radius < 0.0:
        centerComplex = midpointComplex + midpointComplex - centerComplex
    midpointMinusCenterComplex = midpointComplex - centerComplex
    midpointCenterLength = abs(midpointMinusCenterComplex)
    midpointEndLength = abs(midpointComplex - endBevelComplex)
    midpointCircleCenterLength = midpointEndLength * midpointEndLength / midpointCenterLength
    circleRadius = math.sqrt(midpointCircleCenterLength *
                             midpointCircleCenterLength +
                             midpointEndLength * midpointEndLength)
    circleCenterComplex = midpointComplex + midpointMinusCenterComplex * midpointCircleCenterLength / midpointCenterLength
    circleCenter = Vector3(circleCenterComplex.real, circleCenterComplex.imag,
                           center.z)
    endMinusCircleCenterComplex = endBevelComplex - circleCenterComplex
    beginMinusCircleCenter = beginBevel - circleCenter
    beginMinusCircleCenterComplex = beginMinusCircleCenter.dropAxis()
    angleDifference = euclidean.getAngleDifferenceByComplex(
        endMinusCircleCenterComplex, beginMinusCircleCenterComplex)
    steps = int(math.ceil(abs(angleDifference) * sidesPerRadian))
    stepPlaneAngle = euclidean.getWiddershinsUnitPolar(angleDifference /
                                                       float(steps))
    deltaZStep = (end.z - begin.z) / float(steps)
    roundPath = [beginBevel]
    for step in xrange(1, steps):
        beginMinusCircleCenterComplex = beginMinusCircleCenterComplex * stepPlaneAngle
        arcPointComplex = circleCenterComplex + beginMinusCircleCenterComplex
        arcPoint = Vector3(arcPointComplex.real, arcPointComplex.imag,
                           begin.z + deltaZStep * step)
        roundPath.append(arcPoint)
    return roundPath + [endBevel]
Пример #8
0
def getRoundPath(begin, center, close, end, radius, sidesPerRadian):
    "Get round path."
    beginComplex = begin.dropAxis()
    centerComplex = center.dropAxis()
    endComplex = end.dropAxis()
    beginComplexSegmentLength = abs(centerComplex - beginComplex)
    endComplexSegmentLength = abs(centerComplex - endComplex)
    minimumRadius = lineation.getMinimumRadius(beginComplexSegmentLength, endComplexSegmentLength, radius)
    if minimumRadius <= close:
        return [center]
    beginBevel = center + minimumRadius / beginComplexSegmentLength * (begin - center)
    endBevel = center + minimumRadius / endComplexSegmentLength * (end - center)
    beginBevelComplex = beginBevel.dropAxis()
    endBevelComplex = endBevel.dropAxis()
    midpointComplex = 0.5 * (beginBevelComplex + endBevelComplex)
    if radius < 0.0:
        centerComplex = midpointComplex + midpointComplex - centerComplex
    midpointMinusCenterComplex = midpointComplex - centerComplex
    midpointCenterLength = abs(midpointMinusCenterComplex)
    midpointEndLength = abs(midpointComplex - endBevelComplex)
    midpointCircleCenterLength = midpointEndLength * midpointEndLength / midpointCenterLength
    circleRadius = math.sqrt(
        midpointCircleCenterLength * midpointCircleCenterLength + midpointEndLength * midpointEndLength
    )
    circleCenterComplex = (
        midpointComplex + midpointMinusCenterComplex * midpointCircleCenterLength / midpointCenterLength
    )
    circleCenter = Vector3(circleCenterComplex.real, circleCenterComplex.imag, center.z)
    endMinusCircleCenterComplex = endBevelComplex - circleCenterComplex
    beginMinusCircleCenter = beginBevel - circleCenter
    beginMinusCircleCenterComplex = beginMinusCircleCenter.dropAxis()
    angleDifference = euclidean.getAngleDifferenceByComplex(endMinusCircleCenterComplex, beginMinusCircleCenterComplex)
    steps = int(math.ceil(abs(angleDifference) * sidesPerRadian))
    stepPlaneAngle = euclidean.getWiddershinsUnitPolar(angleDifference / float(steps))
    deltaZStep = (end.z - begin.z) / float(steps)
    roundPath = [beginBevel]
    for step in xrange(1, steps):
        beginMinusCircleCenterComplex = beginMinusCircleCenterComplex * stepPlaneAngle
        arcPointComplex = circleCenterComplex + beginMinusCircleCenterComplex
        arcPoint = Vector3(arcPointComplex.real, arcPointComplex.imag, begin.z + deltaZStep * step)
        roundPath.append(arcPoint)
    return roundPath + [endBevel]
Пример #9
0
def getArcComplexes( begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation ):
	'Get the arc complexes, procedure at http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes'
	beginTransformed = complex( begin.real / radius.real, begin.imag / radius.imag )
	endTransformed = complex( end.real / radius.real, end.imag / radius.imag )
	midpointTransformed = 0.5 * ( beginTransformed + endTransformed )
	midMinusBeginTransformed = midpointTransformed - beginTransformed
	midMinusBeginTransformedLength = abs( midMinusBeginTransformed )
	midWiddershinsTransformed = complex( - midMinusBeginTransformed.imag, midMinusBeginTransformed.real )
	midWiddershinsLength = math.sqrt( 1.0 - midMinusBeginTransformedLength * midMinusBeginTransformedLength )
	midWiddershinsTransformed *= midWiddershinsLength / abs( midWiddershinsTransformed )
	centerTransformed = midpointTransformed
	if largeArcFlag == sweepFlag:
		centerTransformed -= midWiddershinsTransformed
	else:
		centerTransformed += midWiddershinsTransformed
	beginMinusCenterTransformed = beginTransformed - centerTransformed
	beginAngle = math.atan2( beginMinusCenterTransformed.imag, beginMinusCenterTransformed.real )
	endMinusCenterTransformed = endTransformed - centerTransformed
	angleDifference = euclidean.getAngleDifferenceByComplex( endMinusCenterTransformed, beginMinusCenterTransformed )
	if sweepFlag:
		if angleDifference < 0.0:
			angleDifference += 2.0 * math.pi
	else:
		if angleDifference > 0.0:
			angleDifference -= 2.0 * math.pi
	global globalSideAngle
	sides = int( math.ceil( abs( angleDifference ) / globalSideAngle ) )
	sideAngle = angleDifference / sides
	arcComplexes = []
	center = complex(centerTransformed.real * radius.real, centerTransformed.imag * radius.imag)
	for side in xrange( 1, sides ):
		unitPolar = euclidean.getWiddershinsUnitPolar( beginAngle + float(side) * sideAngle )
		point = center + complex( unitPolar.real * radius.real, unitPolar.imag * radius.imag )
		arcComplexes.append( point )
	arcComplexes.append( end )
	return arcComplexes
Пример #10
0
def getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation):
	'Get the arc complexes, procedure at http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes'
	if begin == end:
		print('Warning, begin equals end in getArcComplexes in svgReader')
		print(begin)
		print(end)
		return []
	if radius.imag < 0.0:
		print('Warning, radius.imag is less than zero in getArcComplexes in svgReader')
		print(radius)
		radius = complex(radius.real, abs(radius.imag))
	if radius.real < 0.0:
		print('Warning, radius.real is less than zero in getArcComplexes in svgReader')
		print(radius)
		radius = complex(abs(radius.real), radius.imag)
	if radius.imag <= 0.0:
		print('Warning, radius.imag is too small for getArcComplexes in svgReader')
		print(radius)
		return [end]
	if radius.real <= 0.0:
		print('Warning, radius.real is too small for getArcComplexes in svgReader')
		print(radius)
		return [end]
	xAxisRotationComplex = euclidean.getWiddershinsUnitPolar(xAxisRotation)
	reverseXAxisRotationComplex = complex(xAxisRotationComplex.real, -xAxisRotationComplex.imag)
	beginRotated = begin * reverseXAxisRotationComplex
	endRotated = end * reverseXAxisRotationComplex
	beginTransformed = complex(beginRotated.real / radius.real, beginRotated.imag / radius.imag)
	endTransformed = complex(endRotated.real / radius.real, endRotated.imag / radius.imag)
	midpointTransformed = 0.5 * (beginTransformed + endTransformed)
	midMinusBeginTransformed = midpointTransformed - beginTransformed
	midMinusBeginTransformedLength = abs(midMinusBeginTransformed)
	if midMinusBeginTransformedLength > 1.0:
		print('The ellipse radius is too small for getArcComplexes in svgReader.')
		print('So the ellipse will be scaled to fit, according to the formulas in "Step 3: Ensure radii are large enough" of:')
		print('http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii')
		print('')
		radius *= midMinusBeginTransformedLength
		beginTransformed /= midMinusBeginTransformedLength
		endTransformed /= midMinusBeginTransformedLength
		midpointTransformed /= midMinusBeginTransformedLength
		midMinusBeginTransformed /= midMinusBeginTransformedLength
		midMinusBeginTransformedLength = 1.0
	midWiddershinsTransformed = complex(-midMinusBeginTransformed.imag, midMinusBeginTransformed.real)
	midWiddershinsLengthSquared = 1.0 - midMinusBeginTransformedLength * midMinusBeginTransformedLength
	if midWiddershinsLengthSquared < 0.0:
		midWiddershinsLengthSquared = 0.0
	midWiddershinsLength = math.sqrt(midWiddershinsLengthSquared)
	midWiddershinsTransformed *= midWiddershinsLength / abs(midWiddershinsTransformed)
	centerTransformed = midpointTransformed
	if largeArcFlag == sweepFlag:
		centerTransformed -= midWiddershinsTransformed
	else:
		centerTransformed += midWiddershinsTransformed
	beginMinusCenterTransformed = beginTransformed - centerTransformed
	beginMinusCenterTransformedLength = abs(beginMinusCenterTransformed)
	if beginMinusCenterTransformedLength <= 0.0:
		return end
	beginAngle = math.atan2(beginMinusCenterTransformed.imag, beginMinusCenterTransformed.real)
	endMinusCenterTransformed = endTransformed - centerTransformed
	angleDifference = euclidean.getAngleDifferenceByComplex(endMinusCenterTransformed, beginMinusCenterTransformed)
	if sweepFlag:
		if angleDifference < 0.0:
			angleDifference += 2.0 * math.pi
	else:
		if angleDifference > 0.0:
			angleDifference -= 2.0 * math.pi
	global globalSideAngle
	sides = int(math.ceil(abs(angleDifference) / globalSideAngle))
	sideAngle = angleDifference / float(sides)
	arcComplexes = []
	center = complex(centerTransformed.real * radius.real, centerTransformed.imag * radius.imag) * xAxisRotationComplex
	for side in xrange(1, sides):
		unitPolar = euclidean.getWiddershinsUnitPolar(beginAngle + float(side) * sideAngle)
		circumferential = complex(unitPolar.real * radius.real, unitPolar.imag * radius.imag) * beginMinusCenterTransformedLength
		point = center + circumferential * xAxisRotationComplex
		arcComplexes.append(point)
	arcComplexes.append(end)
	return arcComplexes
Пример #11
0
def getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag,
                    xAxisRotation):
    'Get the arc complexes, procedure at http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes'
    if begin == end:
        print('Warning, begin equals end in getArcComplexes in svgReader')
        print(begin)
        print(end)
        return []
    if radius.imag < 0.0:
        print(
            'Warning, radius.imag is less than zero in getArcComplexes in svgReader'
        )
        print(radius)
        radius = complex(radius.real, abs(radius.imag))
    if radius.real < 0.0:
        print(
            'Warning, radius.real is less than zero in getArcComplexes in svgReader'
        )
        print(radius)
        radius = complex(abs(radius.real), radius.imag)
    if radius.imag <= 0.0:
        print(
            'Warning, radius.imag is too small for getArcComplexes in svgReader'
        )
        print(radius)
        return [end]
    if radius.real <= 0.0:
        print(
            'Warning, radius.real is too small for getArcComplexes in svgReader'
        )
        print(radius)
        return [end]
    xAxisRotationComplex = euclidean.getWiddershinsUnitPolar(xAxisRotation)
    reverseXAxisRotationComplex = complex(xAxisRotationComplex.real,
                                          -xAxisRotationComplex.imag)
    beginRotated = begin * reverseXAxisRotationComplex
    endRotated = end * reverseXAxisRotationComplex
    beginTransformed = complex(beginRotated.real / radius.real,
                               beginRotated.imag / radius.imag)
    endTransformed = complex(endRotated.real / radius.real,
                             endRotated.imag / radius.imag)
    midpointTransformed = 0.5 * (beginTransformed + endTransformed)
    midMinusBeginTransformed = midpointTransformed - beginTransformed
    midMinusBeginTransformedLength = abs(midMinusBeginTransformed)
    if midMinusBeginTransformedLength > 1.0:
        print(
            'The ellipse radius is too small for getArcComplexes in svgReader.'
        )
        print(
            'So the ellipse will be scaled to fit, according to the formulas in "Step 3: Ensure radii are large enough" of:'
        )
        print(
            'http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii'
        )
        print('')
        radius *= midMinusBeginTransformedLength
        beginTransformed /= midMinusBeginTransformedLength
        endTransformed /= midMinusBeginTransformedLength
        midpointTransformed /= midMinusBeginTransformedLength
        midMinusBeginTransformed /= midMinusBeginTransformedLength
        midMinusBeginTransformedLength = 1.0
    midWiddershinsTransformed = complex(-midMinusBeginTransformed.imag,
                                        midMinusBeginTransformed.real)
    midWiddershinsLengthSquared = 1.0 - midMinusBeginTransformedLength * midMinusBeginTransformedLength
    if midWiddershinsLengthSquared < 0.0:
        midWiddershinsLengthSquared = 0.0
    midWiddershinsLength = math.sqrt(midWiddershinsLengthSquared)
    midWiddershinsTransformed *= midWiddershinsLength / abs(
        midWiddershinsTransformed)
    centerTransformed = midpointTransformed
    if largeArcFlag == sweepFlag:
        centerTransformed -= midWiddershinsTransformed
    else:
        centerTransformed += midWiddershinsTransformed
    beginMinusCenterTransformed = beginTransformed - centerTransformed
    beginMinusCenterTransformedLength = abs(beginMinusCenterTransformed)
    if beginMinusCenterTransformedLength <= 0.0:
        return end
    beginAngle = math.atan2(beginMinusCenterTransformed.imag,
                            beginMinusCenterTransformed.real)
    endMinusCenterTransformed = endTransformed - centerTransformed
    angleDifference = euclidean.getAngleDifferenceByComplex(
        endMinusCenterTransformed, beginMinusCenterTransformed)
    if sweepFlag:
        if angleDifference < 0.0:
            angleDifference += 2.0 * math.pi
    else:
        if angleDifference > 0.0:
            angleDifference -= 2.0 * math.pi
    global globalSideAngle
    sides = int(math.ceil(abs(angleDifference) / globalSideAngle))
    sideAngle = angleDifference / float(sides)
    arcComplexes = []
    center = complex(
        centerTransformed.real * radius.real,
        centerTransformed.imag * radius.imag) * xAxisRotationComplex
    for side in xrange(1, sides):
        unitPolar = euclidean.getWiddershinsUnitPolar(beginAngle +
                                                      float(side) * sideAngle)
        circumferential = complex(
            unitPolar.real * radius.real,
            unitPolar.imag * radius.imag) * beginMinusCenterTransformedLength
        point = center + circumferential * xAxisRotationComplex
        arcComplexes.append(point)
    arcComplexes.append(end)
    return arcComplexes