def linesPointAtEachother(linepair1, linepair2):
    ep1 = linepair1[1]
    ep2 = linepair2[1]
    pointsToRadius = max(15, 0.26 * GeomUtils.pointDistance(ep1.X, ep1.Y, ep2.X, ep2.Y) ) #Span out the valid radius at about 30 degrees
    l1_to_l2 = GeomUtils.linePointsTowards(linepair1[0], linepair1[1], linepair2[1], pointsToRadius)
    l2_to_l1 = GeomUtils.linePointsTowards(linepair2[0], linepair2[1], linepair1[1], pointsToRadius)
    ss_logger.debug("l1 points to l2: %s" % (l1_to_l2))
    ss_logger.debug("l2 points to l1: %s" % (l2_to_l1))
    return (l1_to_l2 and l2_to_l1)
    def _matchHeadtoTail(self, head = None, tail = None, point = None):
        """Input head stroke or tail stroke. If head is specified, match it to a tail. If tail is specified, match it to a head.
           Parameter 'point' should be the tip if head is specified, the end-point if tail is specified.
           Returns a list of tuples: (tip, head_stroke) if tail is specified, (endpoint, tail_stroke) if head is specified."""
        retlist = []
        if point is None:
            return retlist

            
        if head is not None and tail is None: #Head is specified, find the tail
            tip = point
            ep1, ep2 = head.Points[0], head.Points[-1]
            headBreadth = GeomUtils.pointDistance(ep1.X, ep1.Y, ep2.X, ep2.Y)
            for endpoint, tailStroke in self._endpoints:
                if GeomUtils.strokeLength(head) < GeomUtils.strokeLength(tailStroke) \
                and _isPointWithHead(endpoint, head, tip): #Make sure the proportions aren't totally off
                    logger.debug("Head stroke has a tail close and within cone")
                    pointingLength = len(tailStroke.Points) / 5
                    #headToTail
                    if endpoint == tailStroke.Points[0]:
                        linept1, linept2 = tailStroke.Points[pointingLength], endpoint
                    elif endpoint== tailStroke.Points[-1]:
                        linept1, linept2 = tailStroke.Points[-pointingLength], endpoint
                    pointsTo = GeomUtils.linePointsTowards(linept1, linept2, tip, headBreadth)
                    if pointsTo:
                        retlist.append( (endpoint, tailStroke) )

        elif tail is not None and head is None: #Find the head
            endpoint = point
            pointingLength = len(tail.Points) / 5
            #headToTail
            if endpoint == tail.Points[0]:
                linept1, linept2 = tail.Points[pointingLength], endpoint
            elif endpoint== tail.Points[-1]:
                linept1, linept2 = tail.Points[-pointingLength], endpoint

            for tip, headStroke in self._arrowHeads:
                ep1, ep2 = headStroke.Points[0], headStroke.Points[-1]
                headBreadth = GeomUtils.pointDistance(ep1.X, ep1.Y, ep2.X, ep2.Y)
                if GeomUtils.strokeLength(headStroke) < GeomUtils.strokeLength(tail) \
                and _isPointWithHead(endpoint, headStroke, tip):
                    logger.debug("Tail stroke is close and within cone of an arrowhead")
                    pointsTo = GeomUtils.linePointsTowards(linept1, linept2, tip, headBreadth)
                    if pointsTo:
                        retlist.append( (tip, headStroke) )
        return retlist
示例#3
0
 def tipToNode( self, arrow_anno, circle_anno ):
     "return true if the tip of the arrow points to the circle"
     lineDist = min(10, max(len(arrow_anno.tailstroke.Points) / 10, 1)) #Check the last 10th of the stroke points the right way
     #lineseg: two points from arrow "neck" to arrowhead tip 
     #lineseg2: two points from arrow "neck" to last point in tail stroke
     if arrow_anno.direction == "tail2head":
         lineSeg = ( arrow_anno.tailstroke.Points[-lineDist], arrow_anno.tip )
         lineSeg2 = ( arrow_anno.tailstroke.Points[-lineDist], arrow_anno.tailstroke.Points[-1] )
     else: #direction == 'head2tail'
         lineSeg = ( arrow_anno.tailstroke.Points[lineDist], arrow_anno.tip )
         lineSeg2 = ( arrow_anno.tailstroke.Points[lineDist], arrow_anno.tailstroke.Points[0] )
         
     if GeomUtils.pointDist( arrow_anno.tip,  circle_anno.center ) < circle_anno.radius* DiGraphAnnotation.MATCHING_DISTANCE:
         if GeomUtils.linePointsTowards( lineSeg[0], lineSeg[1], circle_anno.center, circle_anno.radius * DiGraphAnnotation.POINTSTO_DISTANCE):
             return True
         if GeomUtils.linePointsTowards( lineSeg2[0], lineSeg2[1], circle_anno.center, circle_anno.radius * DiGraphAnnotation.POINTSTO_DISTANCE):
             return True
     return False
示例#4
0
 def tailToNode( self, arrow_anno, circle_anno ):
     "return true if the tail of the arrow comes from the circle"
     lineDist = max(len(arrow_anno.tailstroke.Points) / 10, 1) #Check the last 10th of the stroke points the right way
     if arrow_anno.direction == "tail2head":
         lineSeg = ( arrow_anno.tailstroke.Points[lineDist], arrow_anno.tailstroke.Points[0] )
     else: #direction == 'head2tail'
         lineSeg = ( arrow_anno.tailstroke.Points[-lineDist], arrow_anno.tailstroke.Points[-1] )
         
     if GeomUtils.pointDist( arrow_anno.tail,  circle_anno.center ) < circle_anno.radius* DiGraphAnnotation.MATCHING_DISTANCE:
         if GeomUtils.linePointsTowards( lineSeg[0], lineSeg[1], circle_anno.center, circle_anno.radius * DiGraphAnnotation.POINTSTO_DISTANCE):
             return True
     return False
示例#5
0
    def _matchHeadtoTail(self, head = None, tail = None, point = None):
        """Input head stroke or tail stroke. If head is specified, match it to a tail. If tail is specified, match it to a head.
           Parameter 'point' should be the tip if head is specified, the end-point if tail is specified.
           Returns a list of tuples: (tip, head_stroke) if tail is specified, (endpoint, tail_stroke) if head is specified."""
        retlist = []
        if point is None:
            return retlist

            
        headStroke = head
        tailStroke = tail

        if headStroke is not None and tail is None: #Head is specified, find the tail
            tip = point
            ep1, ep2 = headStroke.Points[0], headStroke.Points[-1]
            headBreadth = GeomUtils.pointDistance(ep1.X, ep1.Y, ep2.X, ep2.Y)
            for endpoint, origStk, tailStroke in self._endpoints:
                pointingLength = len(tailStroke.Points) / 10
                if endpoint == tailStroke.Points[0]: #Treat as drawn head2tail
                    tailpoints = tailStroke.Points
                    linept1, linept2 = tailStroke.Points[pointingLength], endpoint
                elif endpoint== tailStroke.Points[-1]: #Treat as drawn tail2head
                    tailpoints = list(reversed(tailStroke.Points))
                    linept1, linept2 = tailStroke.Points[-(pointingLength+1)], endpoint

                headLen = GeomUtils.strokeLength(headStroke) 
                tailLen = GeomUtils.strokeLength(tailStroke)
                pointWithHead = _isPointWithHead(tailpoints, headStroke, tip)
                if headLen < tailLen * 2 \
                and pointWithHead:
                    logger.debug("Head stroke has a tail close and within cone")
                    #headToTail
                    pointsTo = GeomUtils.linePointsTowards(linept1, linept2, tip, headBreadth)
                    if pointsTo:
                        logger.debug("  Tail points to head")
                        retlist.append( (endpoint, origStk) )
                    else:
                        logger.debug("  Tail does NOT point to head")
                else:
                    if headLen < tailLen * 2:
                        logger.debug("  Head stroke scale is okay for this arrowhead")
                    else:
                        logger.debug("  Head stroke scale is BAD for this arrowhead")
                        logger.debug("  Head Len: %s, tail Len: %s" % (headLen, tailLen))
                    if not pointWithHead:
                        logger.debug("  Head stroke is NOT close or within cone of an arrowhead\n")
                    else:
                        logger.debug("  Head stroke is close and within cone of an arrowhead\n")

        elif tailStroke is not None and headStroke is None: #Find the head
            endpoint = point
            pointingLength = len(tailStroke.Points) / 10

            if endpoint == tailStroke.Points[0]: #Treat as drawn head2tail
                tailpoints = tailStroke.Points
                linept1, linept2 = tailStroke.Points[pointingLength], endpoint
            elif endpoint== tailStroke.Points[-1]: #Treat as drawn tail2head
                tailpoints = list(reversed(tailStroke.Points))
                linept1, linept2 = tailStroke.Points[-pointingLength], endpoint

            for tip, origStk, headStroke in self._arrowHeads:
                ep1, ep2 = headStroke.Points[0], headStroke.Points[-1]
                headBreadth = GeomUtils.pointDistance(ep1.X, ep1.Y, ep2.X, ep2.Y)
                headLen = GeomUtils.strokeLength(headStroke) 
                tailLen = GeomUtils.strokeLength(tailStroke)
                pointWithHead = _isPointWithHead(tailpoints, headStroke, tip)
                if headLen < tailLen * 2\
                and pointWithHead:
                    logger.debug("Tail stroke is close and within cone of an arrowhead")
                    pointsTo = GeomUtils.linePointsTowards(linept1, linept2, tip, headBreadth)
                    if pointsTo:
                        logger.debug("  Tail points to head")
                        retlist.append( (tip, origStk) )
                    else:
                        logger.debug("  Tail does NOT point to head")
                else:
                    if headLen < tailLen * 2:
                        logger.debug("  Tail stroke scale is okay for this arrowhead")
                    else:
                        logger.debug("  Tail stroke scale is BAD for this arrowhead")
                        logger.debug("  Head Len: %s, tail Len: %s" % (headLen, tailLen))

                    if not pointWithHead:
                        logger.debug("  Tail stroke is NOT close or within cone of an arrowhead\n")
                    else:
                        logger.debug("  Tail stroke is close and within cone of an arrowhead\n")
                        
        return retlist