Skip to content

Arrow with "simple" style is not robust. Code fix included. #1619

Closed

Description

@dhyams

An arrow with the "simple" arrowstyle, if too short, throws a NonIntersectingPathException. The fix is below, which follows the same pattern as the "fancy" arrowstyle. I apologize for not submitting a github pull request, but I just don't have things set up properly to do it right now.

In patches.py (I'm working with MPL 1.1.1, so this is around line 3400), the transmute method for class Simple_ should be changed to (all added lines marked with ADDME).

   def transmute(self, path, mutation_size, linewidth):

        x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)

        from bezier import NonIntersectingPathException # ADDME

        # divide the path into a head and a tail
        head_length  = self.head_length * mutation_size
        in_f = inside_circle(x2, y2, head_length)
        arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
        try:  # ADDME
          arrow_out, arrow_in = \
                   split_bezier_intersecting_with_closedpath(arrow_path,
                                                             in_f,
                                                             tolerence=0.01)
        except NonIntersectingPathException: # ADDME
            # if this happens, make a straight line of the head_length long. # ADDME
            dx, dy = x2 - x1, y2 - y1 # ADDME
            ff = head_length/(dx*dx+dy*dy)**.5 # ADDME
            x0, y0 = x2 - ff*dx, y2 - ff*dy # ADDME
            arrow_in  = [(x0, y0), (x1, y1), (x2, y2)] # ADDME
            arrow_out = [(x0, y0), (x0, y0), (x0, y0)] # ADDME



        # head
        head_width = self.head_width * mutation_size
        head_l, head_r = make_wedged_bezier2(arrow_in, head_width/2.,
                                             wm=.5)



        # tail
        tail_width = self.tail_width * mutation_size
        tail_left, tail_right = get_parallels(arrow_out, tail_width/2.)

        head_right, head_left = head_r, head_l
        patch_path = [(Path.MOVETO, tail_right[0]),
                      (Path.CURVE3, tail_right[1]),
                      (Path.CURVE3, tail_right[2]),
                      (Path.LINETO, head_right[0]),
                      (Path.CURVE3, head_right[1]),
                      (Path.CURVE3, head_right[2]),
                      (Path.CURVE3, head_left[1]),
                      (Path.CURVE3, head_left[0]),
                      (Path.LINETO, tail_left[2]),
                      (Path.CURVE3, tail_left[1]),
                      (Path.CURVE3, tail_left[0]),
                      (Path.LINETO, tail_right[0]),
                      (Path.CLOSEPOLY, tail_right[0]),
                      ]
        path = Path([p for c, p in patch_path], [c for c, p in patch_path])

        return path, True

Activity

  1. dhyams commented on Feb 20, 2013

    @dhyams
    ContributorAuthor

    This issue was addressed by #566

  2. pelson commented on Feb 22, 2013

    @pelson
    Member

    Thanks for updating @dhyams .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions