99from matplotlib .path import Path
1010
1111from operator import xor
12+ import warnings
1213
1314
1415# some functions
@@ -323,6 +324,22 @@ def get_cos_sin(x0, y0, x1, y1):
323324 d = (dx * dx + dy * dy )** .5
324325 return dx / d , dy / d
325326
327+ def check_if_parallel (dx1 , dy1 , dx2 , dy2 , tolerence = 1.e-5 ):
328+ """ returns
329+ * 1 if two lines are parralel in same direction
330+ * -1 if two lines are parralel in opposite direction
331+ * 0 otherwise
332+ """
333+ theta1 = np .arctan2 (dx1 , dy1 )
334+ theta2 = np .arctan2 (dx2 , dy2 )
335+ dtheta = np .abs (theta1 - theta2 )
336+ if dtheta < tolerence :
337+ return 1
338+ elif np .abs (dtheta - np .pi ) < tolerence :
339+ return - 1
340+ else :
341+ return False
342+
326343
327344def get_parallels (bezier2 , width ):
328345 """
@@ -338,10 +355,18 @@ def get_parallels(bezier2, width):
338355 cmx , cmy = bezier2 [1 ]
339356 c2x , c2y = bezier2 [2 ]
340357
341- # t1 and t2 is the anlge between c1 and cm, cm, c2.
342- # They are also a angle of the tangential line of the path at c1 and c2
343- cos_t1 , sin_t1 = get_cos_sin (c1x , c1y , cmx , cmy )
344- cos_t2 , sin_t2 = get_cos_sin (cmx , cmy , c2x , c2y )
358+ parallel_test = check_if_parallel (c1x - cmx , c1y - cmy , cmx - c2x , cmy - c2y )
359+
360+ if parallel_test == - 1 :
361+ warnings .warn ("Lines do not intersect. A straight line is used instead." )
362+ #cmx, cmy = 0.5*(c1x+c2x), 0.5*(c1y+c2y)
363+ cos_t1 , sin_t1 = get_cos_sin (c1x , c1y , c2x , c2y )
364+ cos_t2 , sin_t2 = cos_t1 , sin_t1
365+ else :
366+ # t1 and t2 is the anlge between c1 and cm, cm, c2. They are
367+ # also a angle of the tangential line of the path at c1 and c2
368+ cos_t1 , sin_t1 = get_cos_sin (c1x , c1y , cmx , cmy )
369+ cos_t2 , sin_t2 = get_cos_sin (cmx , cmy , c2x , c2y )
345370
346371 # find c1_left, c1_right which are located along the lines
347372 # throught c1 and perpendicular to the tangential lines of the
@@ -355,11 +380,21 @@ def get_parallels(bezier2, width):
355380 # find cm_left which is the intersectng point of a line through
356381 # c1_left with angle t1 and a line throught c2_left with angle
357382 # t2. Same with cm_right.
358- cmx_left , cmy_left = get_intersection (c1x_left , c1y_left , cos_t1 , sin_t1 ,
359- c2x_left , c2y_left , cos_t2 , sin_t2 )
383+ if parallel_test != 0 :
384+ # a special case for a straight line, i.e., angle between two
385+ # lines are smaller than some (arbitrtay) value.
386+ cmx_left , cmy_left = \
387+ 0.5 * (c1x_left + c2x_left ), 0.5 * (c1y_left + c2y_left )
388+ cmx_right , cmy_right = \
389+ 0.5 * (c1x_right + c2x_right ), 0.5 * (c1y_right + c2y_right )
390+ else :
391+ cmx_left , cmy_left = \
392+ get_intersection (c1x_left , c1y_left , cos_t1 , sin_t1 ,
393+ c2x_left , c2y_left , cos_t2 , sin_t2 )
360394
361- cmx_right , cmy_right = get_intersection (c1x_right , c1y_right , cos_t1 , sin_t1 ,
362- c2x_right , c2y_right , cos_t2 , sin_t2 )
395+ cmx_right , cmy_right = \
396+ get_intersection (c1x_right , c1y_right , cos_t1 , sin_t1 ,
397+ c2x_right , c2y_right , cos_t2 , sin_t2 )
363398
364399 # the parralel bezier lines are created with control points of
365400 # [c1_left, cm_left, c2_left] and [c1_right, cm_right, c2_right]
0 commit comments