@@ -177,7 +177,7 @@ def get_patch_transform(self):
177177 """
178178 Return the :class:`~matplotlib.transforms.Transform` instance which
179179 takes patch coordinates to data coordinates.
180-
180+
181181 For example, one may define a patch of a circle which represents a
182182 radius of 5 by providing coordinates for a unit circle, and a
183183 transform which scales the coordinates (the patch coordinate) by 5.
@@ -2783,6 +2783,17 @@ def connect(self, posA, posB):
27832783 {"AvailableConnectorstyles" : _pprint_styles (_style_list )}
27842784
27852785
2786+ def _point_along_a_line (x0 , y0 , x1 , y1 , d ):
2787+ """
2788+ find a point along a line connecting (x0, y0) -- (x1, y1) whose
2789+ distance from (x0, y0) is d.
2790+ """
2791+ dx , dy = x0 - x1 , y0 - y1
2792+ ff = d / (dx * dx + dy * dy )** .5
2793+ x2 , y2 = x0 - ff * dx , y0 - ff * dy
2794+
2795+ return x2 , y2
2796+
27862797
27872798class ArrowStyle (_Style ):
27882799 """
@@ -3419,37 +3430,57 @@ def transmute(self, path, mutation_size, linewidth):
34193430 head_length = self .head_length * mutation_size
34203431 in_f = inside_circle (x2 , y2 , head_length )
34213432 arrow_path = [(x0 , y0 ), (x1 , y1 ), (x2 , y2 )]
3422- arrow_out , arrow_in = \
3423- split_bezier_intersecting_with_closedpath (arrow_path ,
3424- in_f ,
3425- tolerence = 0.01 )
3433+
3434+ from bezier import NonIntersectingPathException
3435+
3436+ try :
3437+ arrow_out , arrow_in = \
3438+ split_bezier_intersecting_with_closedpath (arrow_path ,
3439+ in_f ,
3440+ tolerence = 0.01 )
3441+ except NonIntersectingPathException :
3442+ # if this happens, make a straight line of the head_length long.
3443+ x0 , y0 = _point_along_a_line (x2 , y2 , x1 , y1 , head_length )
3444+ x1n , y1n = 0.5 * (x0 + x2 ), 0.5 * (y0 + y2 )
3445+ arrow_in = [(x0 , y0 ), (x1n , y1n ), (x2 , y2 )]
3446+ arrow_out = None
34263447
34273448 # head
34283449 head_width = self .head_width * mutation_size
3429- head_l , head_r = make_wedged_bezier2 ( arrow_in , head_width / 2. ,
3430- wm = .5 )
3431-
3450+ head_left , head_right = \
3451+ make_wedged_bezier2 ( arrow_in , head_width / 2. ,
3452+ wm = .5 )
34323453
34333454
34343455 # tail
3435- tail_width = self .tail_width * mutation_size
3436- tail_left , tail_right = get_parallels (arrow_out , tail_width / 2. )
3456+ if arrow_out is not None :
3457+ tail_width = self .tail_width * mutation_size
3458+ tail_left , tail_right = get_parallels (arrow_out , tail_width / 2. )
3459+
3460+ #head_right, head_left = head_r, head_l
3461+ patch_path = [(Path .MOVETO , tail_right [0 ]),
3462+ (Path .CURVE3 , tail_right [1 ]),
3463+ (Path .CURVE3 , tail_right [2 ]),
3464+ (Path .LINETO , head_right [0 ]),
3465+ (Path .CURVE3 , head_right [1 ]),
3466+ (Path .CURVE3 , head_right [2 ]),
3467+ (Path .CURVE3 , head_left [1 ]),
3468+ (Path .CURVE3 , head_left [0 ]),
3469+ (Path .LINETO , tail_left [2 ]),
3470+ (Path .CURVE3 , tail_left [1 ]),
3471+ (Path .CURVE3 , tail_left [0 ]),
3472+ (Path .LINETO , tail_right [0 ]),
3473+ (Path .CLOSEPOLY , tail_right [0 ]),
3474+ ]
3475+ else :
3476+ patch_path = [(Path .MOVETO , head_right [0 ]),
3477+ (Path .CURVE3 , head_right [1 ]),
3478+ (Path .CURVE3 , head_right [2 ]),
3479+ (Path .CURVE3 , head_left [1 ]),
3480+ (Path .CURVE3 , head_left [0 ]),
3481+ (Path .CLOSEPOLY , head_left [0 ]),
3482+ ]
34373483
3438- head_right , head_left = head_r , head_l
3439- patch_path = [(Path .MOVETO , tail_right [0 ]),
3440- (Path .CURVE3 , tail_right [1 ]),
3441- (Path .CURVE3 , tail_right [2 ]),
3442- (Path .LINETO , head_right [0 ]),
3443- (Path .CURVE3 , head_right [1 ]),
3444- (Path .CURVE3 , head_right [2 ]),
3445- (Path .CURVE3 , head_left [1 ]),
3446- (Path .CURVE3 , head_left [0 ]),
3447- (Path .LINETO , tail_left [2 ]),
3448- (Path .CURVE3 , tail_left [1 ]),
3449- (Path .CURVE3 , tail_left [0 ]),
3450- (Path .LINETO , tail_right [0 ]),
3451- (Path .CLOSEPOLY , tail_right [0 ]),
3452- ]
34533484 path = Path ([p for c , p in patch_path ], [c for c , p in patch_path ])
34543485
34553486 return path , True
@@ -3498,10 +3529,9 @@ def transmute(self, path, mutation_size, linewidth):
34983529 tolerence = 0.01 )
34993530 except NonIntersectingPathException :
35003531 # if this happens, make a straight line of the head_length long.
3501- dx , dy = x2 - x1 , y2 - y1
3502- ff = head_length / (dx * dx + dy * dy )** .5
3503- x0 , y0 = x2 - ff * dx , y2 - ff * dy
3504- arrow_path = [(x0 , y0 ), (x1 , y1 ), (x2 , y2 )]
3532+ x0 , y0 = _point_along_a_line (x2 , y2 , x1 , y1 , head_length )
3533+ x1n , y1n = 0.5 * (x0 + x2 ), 0.5 * (y0 + y2 )
3534+ arrow_path = [(x0 , y0 ), (x1n , y1n ), (x2 , y2 )]
35053535 path_head = arrow_path
35063536 else :
35073537 path_head = path_in
0 commit comments