@@ -2841,6 +2841,18 @@ def connect(self, posA, posB):
2841
2841
{"AvailableConnectorstyles" : _pprint_styles (_style_list )}
2842
2842
2843
2843
2844
+ def _point_along_a_line (x0 , y0 , x1 , y1 , d ):
2845
+ """
2846
+ find a point along a line connecting (x0, y0) -- (x1, y1) whose
2847
+ distance from (x0, y0) is d.
2848
+ """
2849
+ dx , dy = x0 - x1 , y0 - y1
2850
+ ff = d / (dx * dx + dy * dy )** .5
2851
+ x2 , y2 = x0 - ff * dx , y0 - ff * dy
2852
+
2853
+ return x2 , y2
2854
+
2855
+
2844
2856
class ArrowStyle (_Style ):
2845
2857
"""
2846
2858
:class:`ArrowStyle` is a container class which defines several
@@ -3460,35 +3472,57 @@ def transmute(self, path, mutation_size, linewidth):
3460
3472
head_length = self .head_length * mutation_size
3461
3473
in_f = inside_circle (x2 , y2 , head_length )
3462
3474
arrow_path = [(x0 , y0 ), (x1 , y1 ), (x2 , y2 )]
3463
- arrow_out , arrow_in = \
3464
- split_bezier_intersecting_with_closedpath (arrow_path ,
3465
- in_f ,
3466
- tolerence = 0.01 )
3475
+
3476
+ from bezier import NonIntersectingPathException
3477
+
3478
+ try :
3479
+ arrow_out , arrow_in = \
3480
+ split_bezier_intersecting_with_closedpath (arrow_path ,
3481
+ in_f ,
3482
+ tolerence = 0.01 )
3483
+ except NonIntersectingPathException :
3484
+ # if this happens, make a straight line of the head_length long.
3485
+ x0 , y0 = _point_along_a_line (x2 , y2 , x1 , y1 , head_length )
3486
+ x1n , y1n = 0.5 * (x0 + x2 ), 0.5 * (y0 + y2 )
3487
+ arrow_in = [(x0 , y0 ), (x1n , y1n ), (x2 , y2 )]
3488
+ arrow_out = None
3467
3489
3468
3490
# head
3469
3491
head_width = self .head_width * mutation_size
3470
- head_l , head_r = make_wedged_bezier2 (arrow_in , head_width / 2. ,
3471
- wm = .5 )
3492
+ head_left , head_right = \
3493
+ make_wedged_bezier2 (arrow_in , head_width / 2. ,
3494
+ wm = .5 )
3495
+
3472
3496
3473
3497
# tail
3474
- tail_width = self .tail_width * mutation_size
3475
- tail_left , tail_right = get_parallels (arrow_out , tail_width / 2. )
3498
+ if arrow_out is not None :
3499
+ tail_width = self .tail_width * mutation_size
3500
+ tail_left , tail_right = get_parallels (arrow_out , tail_width / 2. )
3501
+
3502
+ #head_right, head_left = head_r, head_l
3503
+ patch_path = [(Path .MOVETO , tail_right [0 ]),
3504
+ (Path .CURVE3 , tail_right [1 ]),
3505
+ (Path .CURVE3 , tail_right [2 ]),
3506
+ (Path .LINETO , head_right [0 ]),
3507
+ (Path .CURVE3 , head_right [1 ]),
3508
+ (Path .CURVE3 , head_right [2 ]),
3509
+ (Path .CURVE3 , head_left [1 ]),
3510
+ (Path .CURVE3 , head_left [0 ]),
3511
+ (Path .LINETO , tail_left [2 ]),
3512
+ (Path .CURVE3 , tail_left [1 ]),
3513
+ (Path .CURVE3 , tail_left [0 ]),
3514
+ (Path .LINETO , tail_right [0 ]),
3515
+ (Path .CLOSEPOLY , tail_right [0 ]),
3516
+ ]
3517
+ else :
3518
+ patch_path = [(Path .MOVETO , head_right [0 ]),
3519
+ (Path .CURVE3 , head_right [1 ]),
3520
+ (Path .CURVE3 , head_right [2 ]),
3521
+ (Path .CURVE3 , head_left [1 ]),
3522
+ (Path .CURVE3 , head_left [0 ]),
3523
+ (Path .CLOSEPOLY , head_left [0 ]),
3524
+ ]
3476
3525
3477
- head_right , head_left = head_r , head_l
3478
- patch_path = [(Path .MOVETO , tail_right [0 ]),
3479
- (Path .CURVE3 , tail_right [1 ]),
3480
- (Path .CURVE3 , tail_right [2 ]),
3481
- (Path .LINETO , head_right [0 ]),
3482
- (Path .CURVE3 , head_right [1 ]),
3483
- (Path .CURVE3 , head_right [2 ]),
3484
- (Path .CURVE3 , head_left [1 ]),
3485
- (Path .CURVE3 , head_left [0 ]),
3486
- (Path .LINETO , tail_left [2 ]),
3487
- (Path .CURVE3 , tail_left [1 ]),
3488
- (Path .CURVE3 , tail_left [0 ]),
3489
- (Path .LINETO , tail_right [0 ]),
3490
- (Path .CLOSEPOLY , tail_right [0 ]),
3491
- ]
3492
3526
path = Path ([p for c , p in patch_path ], [c for c , p in patch_path ])
3493
3527
3494
3528
return path , True
@@ -3536,12 +3570,10 @@ def transmute(self, path, mutation_size, linewidth):
3536
3570
in_f ,
3537
3571
tolerence = 0.01 )
3538
3572
except NonIntersectingPathException :
3539
- # if this happens, make a straight line of the head_length
3540
- # long.
3541
- dx , dy = x2 - x1 , y2 - y1
3542
- ff = head_length / (dx * dx + dy * dy ) ** .5
3543
- x0 , y0 = x2 - ff * dx , y2 - ff * dy
3544
- arrow_path = [(x0 , y0 ), (x1 , y1 ), (x2 , y2 )]
3573
+ # if this happens, make a straight line of the head_length long.
3574
+ x0 , y0 = _point_along_a_line (x2 , y2 , x1 , y1 , head_length )
3575
+ x1n , y1n = 0.5 * (x0 + x2 ), 0.5 * (y0 + y2 )
3576
+ arrow_path = [(x0 , y0 ), (x1n , y1n ), (x2 , y2 )]
3545
3577
path_head = arrow_path
3546
3578
else :
3547
3579
path_head = path_in
0 commit comments