def findIntersection_naive(self, other_segment, debugMode=False):
        point = TFSIntersection.calculateIntersectPoint(self.startPoint(),
                                                         self.endPoint(),
                                                         other_segment.startPoint(),
                                                         other_segment.endPoint(),
                                                         debugMode=debugMode)
#        print 'findIntersection_naive', '', self.startPoint(), self.endPoint(), other_segment.startPoint(), other_segment.endPoint()
#        print 'findIntersection_naive', 'point', point
        if debugMode:
            print 'findIntersection_naive', 'point', point
        if not point:
            if debugMode:
                print 'findIntersection_naive.0'
            return None

        def findT(p0, p1, p):
            if p0.x == p1.x:
                return inferTValue(p0.y, p1.y, p.y)
            else:
                return inferTValue(p0.x, p1.x, p.x)

        def interpolateT(startT, endT, t):
            result = startT + (endT - startT) * t
#            print 'interpolateT', startT, endT, 't', t, '->', result
            return result
        selfT = findT(self.startPoint(), self.endPoint(), point)
        selfT = interpolateT(self.startT, self.endT, selfT)
        otherT = findT(other_segment.startPoint(), other_segment.endPoint(), point)
        otherT = interpolateT(other_segment.startT, other_segment.endT, otherT)

        if debugMode:
            print 'findIntersection_naive.3'
        return selfT, otherT, point
Example #2
0
    def validate(self):
        try:
            if not onJython:
                import types
                if type(self.points) not in (types.ListType, types.TupleType):
                    raise TFSValidationException('Unexpected points type: ' +
                                                 str(type(self.points)))
                for point in self.points:
                    if not isinstance(point, TFSPoint):
                        raise TFSValidationException(
                            'Unexpected points type: ' + str(type(point)))

            if not (2 <= len(self.points) <= 4):
                raise TFSValidationException('Invalid segment')
            for point in self.points:
                point.validate()
            if self.startPoint() == self.endPoint():
                print 'self.startPoint()', self.startPoint(
                ), 'self.endPoint()', self.endPoint()
                raise TFSValidationException('Empty segment')
            startVector = self.startVector()
            endVector = self.endVector()
            if startVector is None:
                raise TFSValidationException('Empty start vector')
            if endVector is None:
                raise TFSValidationException('Empty end vector')
#            if startVector.length() == 0:
#                print 'startVector', startVector
#                raise TFSValidationException('Empty start vector')
#            if endVector.length() == 0:
#                print 'endVector', endVector
#                raise TFSValidationException('Empty end vector')

            if len(self) == 4:
                cpIntersection = TFSIntersection.calculateIntersectPoint(
                    *self.points)
                if cpIntersection is not None:
                    startVectorLength = startVector.length()
                    endVectorLength = endVector.length()
                    startIntersectionLength = cpIntersection.distanceTo(
                        self.startPoint())
                    endIntersectionLength = cpIntersection.distanceTo(
                        self.endPoint())
                    if ((startIntersectionLength <= startVectorLength * 0.5)
                            and
                        (endIntersectionLength <= endVectorLength * 0.5)):
                        # this curve will cross itself.

                        #                        print 'cpIntersection', cpIntersection.description()
                        #                        print 'startVectorLength', startVectorLength
                        #                        print 'endVectorLength', endVectorLength
                        #                        print 'startIntersectionLength', startIntersectionLength
                        #                        print 'endIntersectionLength', endIntersectionLength
                        #                        print 'hmm', startIntersectionLength, startVectorLength * 0.5, startIntersectionLength > startVectorLength * 0.5

                        raise TFSValidationException('Crossed cubic bezier')
        except TFSValidationException, e:
            print 'TFSSegment.validate', self.description()
            raise e
Example #3
0
    def validate(self):
        try:
            if not onJython:
                import types

                if type(self.points) not in (types.ListType, types.TupleType):
                    raise TFSValidationException("Unexpected points type: " + str(type(self.points)))
                for point in self.points:
                    if not isinstance(point, TFSPoint):
                        raise TFSValidationException("Unexpected points type: " + str(type(point)))

            if not (2 <= len(self.points) <= 4):
                raise TFSValidationException("Invalid segment")
            for point in self.points:
                point.validate()
            if self.startPoint() == self.endPoint():
                print "self.startPoint()", self.startPoint(), "self.endPoint()", self.endPoint()
                raise TFSValidationException("Empty segment")
            startVector = self.startVector()
            endVector = self.endVector()
            if startVector is None:
                raise TFSValidationException("Empty start vector")
            if endVector is None:
                raise TFSValidationException("Empty end vector")
            #            if startVector.length() == 0:
            #                print 'startVector', startVector
            #                raise TFSValidationException('Empty start vector')
            #            if endVector.length() == 0:
            #                print 'endVector', endVector
            #                raise TFSValidationException('Empty end vector')

            if len(self) == 4:
                cpIntersection = TFSIntersection.calculateIntersectPoint(*self.points)
                if cpIntersection is not None:
                    startVectorLength = startVector.length()
                    endVectorLength = endVector.length()
                    startIntersectionLength = cpIntersection.distanceTo(self.startPoint())
                    endIntersectionLength = cpIntersection.distanceTo(self.endPoint())
                    if (startIntersectionLength <= startVectorLength * 0.5) and (
                        endIntersectionLength <= endVectorLength * 0.5
                    ):
                        # this curve will cross itself.

                        #                        print 'cpIntersection', cpIntersection.description()
                        #                        print 'startVectorLength', startVectorLength
                        #                        print 'endVectorLength', endVectorLength
                        #                        print 'startIntersectionLength', startIntersectionLength
                        #                        print 'endIntersectionLength', endIntersectionLength
                        #                        print 'hmm', startIntersectionLength, startVectorLength * 0.5, startIntersectionLength > startVectorLength * 0.5

                        raise TFSValidationException("Crossed cubic bezier")
        except TFSValidationException, e:
            print "TFSSegment.validate", self.description()
            raise e
Example #4
0
def splitLineWithLine(l0, l1):
    if not l0.isStraightLine():
        raise Exception('Not a straight line')
    if not l1.isStraightLine():
        raise Exception('Not a straight line')
    p00 = l0.startPoint()
    p01 = l0.endPoint()
    p10 = l1.startPoint()
    p11 = l1.endPoint()

    intersect = TFSIntersection.calculateIntersectPoint(p00, p01, p10, p11)
    if intersect is None:
        raise Exception('lines do not intersect')
    return openPathWithPoints(p00, intersect), openPathWithPoints(intersect, p01)
Example #5
0
def inflateSegmentLeft(segment, hDistance, vDistance):
    p0 = segment.startPoint()
    p1 = segment.endPoint()
    startTangent = segment.startTangent()

    if len(segment) == 2:
        offset = scaleVectorHV(startTangent.rotate(math.pi * 0.5), hDistance,
                               vDistance)
        p0 = p0.plus(offset)
        p1 = p1.plus(offset)
        newPoints = (p0, p1)
    elif len(segment) == 3:
        endTangent = segment.endTangent()
        startOffset = scaleVectorHV(startTangent.rotate(math.pi * 0.5),
                                    hDistance, vDistance)
        endOffset = scaleVectorHV(endTangent.rotate(math.pi * 0.5), hDistance,
                                  vDistance)
        p0 = p0.plus(startOffset)
        p1 = p1.plus(endOffset)
        cp0 = TFSntersection.intersectionWithTangents(p0, startTangent, p1,
                                                      endTangent.invert())
        newPoints = (p0, cp0, p1)
    elif len(segment) == 4:
        endTangent = segment.endTangent()
        startOffset = scaleVectorHV(startTangent.rotate(math.pi * 0.5),
                                    hDistance, vDistance)
        endOffset = scaleVectorHV(endTangent.rotate(math.pi * 0.5), hDistance,
                                  vDistance)
        oldScale = p0.distanceTo(p1)
        p0 = p0.plus(startOffset)
        p1 = p1.plus(endOffset)
        newScale = p0.distanceTo(p1)
        cp0 = p0.plus(segment.startVector().scale(newScale / oldScale))
        cp1 = p1.minus(segment.endVector().scale(newScale / oldScale))
        newPoints = (p0, cp0, cp1, p1)
    else:
        raise Exception('Invalid segment')

    try:
        return TFSSegment(*newPoints).roundWithDefaultPrecision()
    except TFSValidationException, e:
        '''
        Inflating a segment can result in an empty or otherwise invalid segment.
        In fact, this will happen often since we'll be deflating previously
        inflated rounding curves.
        That's fine; ignore them.
        '''
        return None
def inflateSegmentLeft(segment, hDistance, vDistance):
    p0 = segment.startPoint()
    p1 = segment.endPoint()
    startTangent = segment.startTangent()


    if len(segment) == 2:
        offset = scaleVectorHV(startTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        p0 = p0.plus(offset)
        p1 = p1.plus(offset)
        newPoints = (p0, p1)
    elif len(segment) == 3:
        endTangent = segment.endTangent()
        startOffset = scaleVectorHV(startTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        endOffset = scaleVectorHV(endTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        p0 = p0.plus(startOffset)
        p1 = p1.plus(endOffset)
        cp0 = TFSntersection.intersectionWithTangents(p0, startTangent, p1, endTangent.invert())
        newPoints = (p0, cp0, p1)
    elif len(segment) == 4:
        endTangent = segment.endTangent()
        startOffset = scaleVectorHV(startTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        endOffset = scaleVectorHV(endTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        oldScale = p0.distanceTo(p1)
        p0 = p0.plus(startOffset)
        p1 = p1.plus(endOffset)
        newScale = p0.distanceTo(p1)
        cp0 = p0.plus(segment.startVector().scale(newScale / oldScale))
        cp1 = p1.minus(segment.endVector().scale(newScale / oldScale))
        newPoints = (p0, cp0, cp1, p1)
    else:
        raise Exception('Invalid segment')

    try:
        return TFSSegment(*newPoints).roundWithDefaultPrecision()
    except TFSValidationException, e:
        '''
        Inflating a segment can result in an empty or otherwise invalid segment.
        In fact, this will happen often since we'll be deflating previously
        inflated rounding curves.
        That's fine; ignore them.
        '''
        return None
Example #7
0
    def findIntersection_naive(self, other_segment, debugMode=False):
        point = TFSIntersection.calculateIntersectPoint(
            self.startPoint(),
            self.endPoint(),
            other_segment.startPoint(),
            other_segment.endPoint(),
            debugMode=debugMode)
        #        print 'findIntersection_naive', '', self.startPoint(), self.endPoint(), other_segment.startPoint(), other_segment.endPoint()
        #        print 'findIntersection_naive', 'point', point
        if debugMode:
            print 'findIntersection_naive', 'point', point
        if not point:
            if debugMode:
                print 'findIntersection_naive.0'
            return None

        def findT(p0, p1, p):
            if p0.x == p1.x:
                return inferTValue(p0.y, p1.y, p.y)
            elif p0.y == p1.y:
                return inferTValue(p0.x, p1.x, p.x)
            else:
                tx = inferTValue(p0.x, p1.x, p.x)
                ty = inferTValue(p0.y, p1.y, p.y)
                return (tx + ty) * 0.5

        def interpolateT(startT, endT, t):
            result = startT + (endT - startT) * t
            #            print 'interpolateT', startT, endT, 't', t, '->', result
            return result

        selfT = findT(self.startPoint(), self.endPoint(), point)
        selfT = interpolateT(self.startT, self.endT, selfT)
        otherT = findT(other_segment.startPoint(), other_segment.endPoint(),
                       point)
        otherT = interpolateT(other_segment.startT, other_segment.endT, otherT)

        if debugMode:
            print 'findIntersection_naive.3'
        return selfT, otherT, point
Example #8
0
def _flateSegmentLeft(segment, hDistance, vDistance=None):
    """
    """
    if vDistance is None:
        vDistance = hDistance

    if segment.startVector().length() == 0 or segment.endVector().length() == 0:
        raise Exception("Cannot flate a segment without valid tangents: " + segment.description())

    p0 = segment.startPoint()
    p1 = segment.endPoint()
    startTangent = segment.startTangent()

    if len(segment) == 2:
        offset = scaleVectorHV(startTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        p0 = p0.plus(offset)
        p1 = p1.plus(offset)
        newPoints = (p0, p1)
    elif len(segment) == 3:
        endTangent = segment.endTangent()
        startOffset = scaleVectorHV(startTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        endOffset = scaleVectorHV(endTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        p0 = p0.plus(startOffset)
        p1 = p1.plus(endOffset)
        cp0 = TFSntersection.intersectionWithTangents(p0, startTangent, p1, endTangent.invert())
        newPoints = (p0, cp0, p1)
    elif len(segment) == 4:
        endTangent = segment.endTangent()
        startOffset = scaleVectorHV(startTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        endOffset = scaleVectorHV(endTangent.rotate(math.pi * 0.5), hDistance, vDistance)
        oldScale = p0.distanceTo(p1)
        p0 = p0.plus(startOffset)
        p1 = p1.plus(endOffset)
        newScale = p0.distanceTo(p1)
        cp0 = p0.plus(segment.startVector().scale(newScale / oldScale))
        cp1 = p1.minus(segment.endVector().scale(newScale / oldScale))
        newPoints = (p0, cp0, cp1, p1)
    else:
        raise Exception("Invalid segment")

    try:
        result = TFSSegment(*newPoints).roundWithDefaultPrecision()

        """
        Segments can be turned "inside out" when deflating.
        For example, deflating an arc by more than its "radius".
        We want to discard these segments.
        We can detect them by checking whether the naive endpoint tangent has reversed.
        """
        affinity = result.naiveEndpointTangent().dotProduct(segment.naiveEndpointTangent())
        if affinity < 0:
            return None

        return result
    except TFSValidationException, e:
        """
        flating a segment can result in an empty or otherwise invalid segment.
        In fact, this will happen often since we'll be deflating previously
        inflated rounding curves.
        That's fine; ignore them.
        """
        return None
Example #9
0
def _flateSegmentLeft(segment, hDistance, vDistance=None):
    '''
    '''
    if vDistance is None:
        vDistance = hDistance

    if (segment.startVector().length() == 0
            or segment.endVector().length() == 0):
        raise Exception('Cannot flate a segment without valid tangents: ' +
                        segment.description())

    p0 = segment.startPoint()
    p1 = segment.endPoint()
    startTangent = segment.startTangent()

    if len(segment) == 2:
        offset = scaleVectorHV(startTangent.rotate(math.pi * 0.5), hDistance,
                               vDistance)
        p0 = p0.plus(offset)
        p1 = p1.plus(offset)
        newPoints = (p0, p1)
    elif len(segment) == 3:
        endTangent = segment.endTangent()
        startOffset = scaleVectorHV(startTangent.rotate(math.pi * 0.5),
                                    hDistance, vDistance)
        endOffset = scaleVectorHV(endTangent.rotate(math.pi * 0.5), hDistance,
                                  vDistance)
        p0 = p0.plus(startOffset)
        p1 = p1.plus(endOffset)
        cp0 = TFSntersection.intersectionWithTangents(p0, startTangent, p1,
                                                      endTangent.invert())
        newPoints = (p0, cp0, p1)
    elif len(segment) == 4:
        endTangent = segment.endTangent()
        startOffset = scaleVectorHV(startTangent.rotate(math.pi * 0.5),
                                    hDistance, vDistance)
        endOffset = scaleVectorHV(endTangent.rotate(math.pi * 0.5), hDistance,
                                  vDistance)
        oldScale = p0.distanceTo(p1)
        p0 = p0.plus(startOffset)
        p1 = p1.plus(endOffset)
        newScale = p0.distanceTo(p1)
        cp0 = p0.plus(segment.startVector().scale(newScale / oldScale))
        cp1 = p1.minus(segment.endVector().scale(newScale / oldScale))
        newPoints = (p0, cp0, cp1, p1)
    else:
        raise Exception('Invalid segment')

    try:
        result = TFSSegment(*newPoints).roundWithDefaultPrecision()
        '''
        Segments can be turned "inside out" when deflating.
        For example, deflating an arc by more than its "radius".
        We want to discard these segments.
        We can detect them by checking whether the naive endpoint tangent has reversed.
        '''
        affinity = result.naiveEndpointTangent().dotProduct(
            segment.naiveEndpointTangent())
        if affinity < 0:
            return None

        return result
    except TFSValidationException as e:
        '''
        flating a segment can result in an empty or otherwise invalid segment.
        In fact, this will happen often since we'll be deflating previously
        inflated rounding curves.
        That's fine; ignore them.
        '''
        return None