Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #1182 from NelleV/bezier_pep8

Bezier pep8
  • Loading branch information...
commit 9eab454b4b9e631aff6fa40c3bc3bb182cdb3240 2 parents dffbad1 + 182cd74
@mdboom mdboom authored
Showing with 82 additions and 135 deletions.
  1. +82 −135 lib/matplotlib/bezier.py
View
217 lib/matplotlib/bezier.py
@@ -4,8 +4,6 @@
from __future__ import print_function
import numpy as np
-from math import sqrt
-
from matplotlib.path import Path
from operator import xor
@@ -17,6 +15,7 @@ class NonIntersectingPathException(ValueError):
# some functions
+
def get_intersection(cx1, cy1, cos_t1, sin_t1,
cx2, cy2, cos_t2, sin_t2):
""" return a intersecting point between a line through (cx1, cy1)
@@ -33,7 +32,7 @@ def get_intersection(cx1, cy1, cos_t1, sin_t1,
a, b = sin_t1, -cos_t1
c, d = sin_t2, -cos_t2
- ad_bc = a*d-b*c
+ ad_bc = a * d - b * c
if ad_bc == 0.:
raise ValueError("Given lines do not intersect")
@@ -42,17 +41,17 @@ def get_intersection(cx1, cy1, cos_t1, sin_t1,
c_, d_ = -c, a
a_, b_, c_, d_ = [k / ad_bc for k in [a_, b_, c_, d_]]
- x = a_* line1_rhs + b_ * line2_rhs
- y = c_* line1_rhs + d_ * line2_rhs
+ x = a_ * line1_rhs + b_ * line2_rhs
+ y = c_ * line1_rhs + d_ * line2_rhs
return x, y
-
def get_normal_points(cx, cy, cos_t, sin_t, length):
"""
- For a line passing through (*cx*, *cy*) and having a angle *t*,
- return locations of the two points located along its perpendicular line at the distance of *length*.
+ For a line passing through (*cx*, *cy*) and having a angle *t*, return
+ locations of the two points located along its perpendicular line at the
+ distance of *length*.
"""
if length == 0.:
@@ -61,27 +60,23 @@ def get_normal_points(cx, cy, cos_t, sin_t, length):
cos_t1, sin_t1 = sin_t, -cos_t
cos_t2, sin_t2 = -sin_t, cos_t
- x1, y1 = length*cos_t1 + cx, length*sin_t1 + cy
- x2, y2 = length*cos_t2 + cx, length*sin_t2 + cy
+ x1, y1 = length * cos_t1 + cx, length * sin_t1 + cy
+ x2, y2 = length * cos_t2 + cx, length * sin_t2 + cy
return x1, y1, x2, y2
-
-
## BEZIER routines
-
-
-
-
# subdividing bezier curve
# http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-sub.html
+
def _de_casteljau1(beta, t):
- next_beta = beta[:-1] * (1-t) + beta[1:] * t
+ next_beta = beta[:-1] * (1 - t) + beta[1:] * t
return next_beta
+
def split_de_casteljau(beta, t):
"""split a bezier segment defined by its controlpoints *beta*
into two separate segment divided at *t* and return their control points.
@@ -100,12 +95,9 @@ def split_de_casteljau(beta, t):
return left_beta, right_beta
-
-
-
-
-
-def find_bezier_t_intersecting_with_closedpath(bezier_point_at_t, inside_closedpath,
+# FIXME spelling mistake in the name of the parameter ``tolerence``
+def find_bezier_t_intersecting_with_closedpath(bezier_point_at_t,
+ inside_closedpath,
t0=0., t1=1., tolerence=0.01):
""" Find a parameter t0 and t1 of the given bezier path which
bounds the intersecting points with a provided closed
@@ -129,16 +121,18 @@ def find_bezier_t_intersecting_with_closedpath(bezier_point_at_t, inside_closedp
end_inside = inside_closedpath(end)
if not xor(start_inside, end_inside):
- raise NonIntersectingPathException("the segment does not seemed to intersect with the path")
+ raise NonIntersectingPathException(
+ "the segment does not seem to intersect with the path")
while 1:
# return if the distance is smaller than the tolerence
- if (start[0]-end[0])**2 + (start[1]-end[1])**2 < tolerence**2:
+ if (start[0] - end[0]) ** 2 + \
+ (start[1] - end[1]) ** 2 < tolerence ** 2:
return t0, t1
# calculate the middle point
- middle_t = 0.5*(t0+t1)
+ middle_t = 0.5 * (t0 + t1)
middle = bezier_point_at_t(middle_t)
middle_inside = inside_closedpath(middle)
@@ -152,19 +146,16 @@ def find_bezier_t_intersecting_with_closedpath(bezier_point_at_t, inside_closedp
start_inside = middle_inside
-
-
-
-class BezierSegment:
+class BezierSegment(object):
"""
A simple class of a 2-dimensional bezier segment
"""
- # Highrt order bezier lines can be supported by simplying adding
- # correcponding values.
- _binom_coeff = {1:np.array([1., 1.]),
- 2:np.array([1., 2., 1.]),
- 3:np.array([1., 3., 3., 1.])}
+ # Higher order bezier lines can be supported by simplying adding
+ # corresponding values.
+ _binom_coeff = {1: np.array([1., 1.]),
+ 2: np.array([1., 2., 1.]),
+ 3: np.array([1., 3., 3., 1.])}
def __init__(self, control_points):
"""
@@ -177,15 +168,15 @@ def __init__(self, control_points):
_coeff = BezierSegment._binom_coeff[_o - 1]
_control_points = np.asarray(control_points)
- xx = _control_points[:,0]
- yy = _control_points[:,1]
+ xx = _control_points[:, 0]
+ yy = _control_points[:, 1]
self._px = xx * _coeff
self._py = yy * _coeff
def point_at_t(self, t):
"evaluate a point at t"
- one_minus_t_powers = np.power(1.-t, self._orders)[::-1]
+ one_minus_t_powers = np.power(1. - t, self._orders)[::-1]
t_powers = np.power(t, self._orders)
tt = one_minus_t_powers * t_powers
@@ -201,7 +192,8 @@ def split_bezier_intersecting_with_closedpath(bezier,
"""
bezier : control points of the bezier segment
- inside_closedpath : a function which returns true if the point is inside the path
+ inside_closedpath : a function which returns true if the point is inside
+ the path
"""
bz = BezierSegment(bezier)
@@ -211,11 +203,10 @@ def split_bezier_intersecting_with_closedpath(bezier,
inside_closedpath,
tolerence=tolerence)
- _left, _right = split_de_casteljau(bezier, (t0+t1)/2.)
+ _left, _right = split_de_casteljau(bezier, (t0 + t1) / 2.)
return _left, _right
-
def find_r_to_boundary_of_closedpath(inside_closedpath, xy,
cos_t, sin_t,
rmin=0., rmax=1., tolerence=0.01):
@@ -230,16 +221,17 @@ def find_r_to_boundary_of_closedpath(inside_closedpath, xy,
"""
cx, cy = xy
+
def _f(r):
- return cos_t*r + cx, sin_t*r + cy
+ return cos_t * r + cx, sin_t * r + cy
find_bezier_t_intersecting_with_closedpath(_f, inside_closedpath,
- t0=rmin, t1=rmax, tolerence=tolerence)
-
-
+ t0=rmin, t1=rmax,
+ tolerence=tolerence)
## matplotlib specific
+
def split_path_inout(path, inside, tolerence=0.01, reorder_inout=False):
""" divide a path into two segment at the point where inside(x, y)
becomes False.
@@ -248,19 +240,19 @@ def split_path_inout(path, inside, tolerence=0.01, reorder_inout=False):
path_iter = path.iter_segments()
ctl_points, command = next(path_iter)
- begin_inside = inside(ctl_points[-2:]) # true if begin point is inside
+ begin_inside = inside(ctl_points[-2:]) # true if begin point is inside
bezier_path = None
ctl_points_old = ctl_points
concat = np.concatenate
- iold=0
+ iold = 0
i = 1
for ctl_points, command in path_iter:
- iold=i
- i += len(ctl_points)/2
+ iold = i
+ i += len(ctl_points) / 2
if inside(ctl_points[-2:]) != begin_inside:
bezier_path = concat([ctl_points_old[-2:], ctl_points])
break
@@ -308,24 +300,22 @@ def split_path_inout(path, inside, tolerence=0.01, reorder_inout=False):
return path_in, path_out
-
-
-
def inside_circle(cx, cy, r):
- r2 = r**2
+ r2 = r ** 2
+
def _f(xy):
x, y = xy
- return (x-cx)**2 + (y-cy)**2 < r2
+ return (x - cx) ** 2 + (y - cy) ** 2 < r2
return _f
-
# quadratic bezier lines
def get_cos_sin(x0, y0, x1, y1):
- dx, dy = x1-x0, y1-y0
- d = (dx*dx + dy*dy)**.5
- return dx/d, dy/d
+ dx, dy = x1 - x0, y1 - y0
+ d = (dx * dx + dy * dy) ** .5
+ return dx / d, dy / d
+
def check_if_parallel(dx1, dy1, dx2, dy2, tolerence=1.e-5):
""" returns
@@ -346,27 +336,31 @@ def check_if_parallel(dx1, dy1, dx2, dy2, tolerence=1.e-5):
def get_parallels(bezier2, width):
"""
- Given the quadraitc bezier control points *bezier2*, returns
- control points of quadrativ bezier lines roughly parralel to given
+ Given the quadratic bezier control points *bezier2*, returns
+ control points of quadratic bezier lines roughly parallel to given
one separated by *width*.
"""
- # The parallel bezier lines constructed by following ways.
- # c1 and c2 are contol points representing the begin and end of the bezier line.
+ # The parallel bezier lines are constructed by following ways.
+ # c1 and c2 are contol points representing the begin and end of the
+ # bezier line.
# cm is the middle point
+
c1x, c1y = bezier2[0]
cmx, cmy = bezier2[1]
c2x, c2y = bezier2[2]
- parallel_test = check_if_parallel(c1x-cmx, c1y-cmy, cmx-c2x, cmy-c2y)
+ parallel_test = check_if_parallel(c1x - cmx, c1y - cmy,
+ cmx - c2x, cmy - c2y)
if parallel_test == -1:
- warnings.warn("Lines do not intersect. A straight line is used instead.")
+ warnings.warn(
+ "Lines do not intersect. A straight line is used instead.")
#cmx, cmy = 0.5*(c1x+c2x), 0.5*(c1y+c2y)
cos_t1, sin_t1 = get_cos_sin(c1x, c1y, c2x, c2y)
cos_t2, sin_t2 = cos_t1, sin_t1
else:
- # t1 and t2 is the anlge between c1 and cm, cm, c2. They are
+ # t1 and t2 is the angle between c1 and cm, cm, c2. They are
# also a angle of the tangential line of the path at c1 and c2
cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy)
cos_t2, sin_t2 = get_cos_sin(cmx, cmy, c2x, c2y)
@@ -387,9 +381,9 @@ def get_parallels(bezier2, width):
# a special case for a straight line, i.e., angle between two
# lines are smaller than some (arbitrtay) value.
cmx_left, cmy_left = \
- 0.5*(c1x_left+c2x_left), 0.5*(c1y_left+c2y_left)
+ 0.5 * (c1x_left + c2x_left), 0.5 * (c1y_left + c2y_left)
cmx_right, cmy_right = \
- 0.5*(c1x_right+c2x_right), 0.5*(c1y_right+c2y_right)
+ 0.5 * (c1x_right + c2x_right), 0.5 * (c1y_right + c2y_right)
else:
cmx_left, cmy_left = \
get_intersection(c1x_left, c1y_left, cos_t1, sin_t1,
@@ -401,62 +395,32 @@ def get_parallels(bezier2, width):
# the parralel bezier lines are created with control points of
# [c1_left, cm_left, c2_left] and [c1_right, cm_right, c2_right]
- path_left = [(c1x_left, c1y_left), (cmx_left, cmy_left), (c2x_left, c2y_left)]
- path_right = [(c1x_right, c1y_right), (cmx_right, cmy_right), (c2x_right, c2y_right)]
+ path_left = [(c1x_left, c1y_left),
+ (cmx_left, cmy_left),
+ (c2x_left, c2y_left)]
+ path_right = [(c1x_right, c1y_right),
+ (cmx_right, cmy_right),
+ (c2x_right, c2y_right)]
return path_left, path_right
-
-def make_wedged_bezier2(bezier2, length, shrink_factor=0.5):
- """
- Being similar to get_parallels, returns
- control points of two quadrativ bezier lines having a width roughly parralel to given
- one separated by *width*.
- """
-
- xx1, yy1 = bezier2[2]
- xx2, yy2 = bezier2[1]
- xx3, yy3 = bezier2[0]
-
- cx, cy = xx3, yy3
- x0, y0 = xx2, yy2
-
- dist = sqrt((x0-cx)**2 + (y0-cy)**2)
- cos_t, sin_t = (x0-cx)/dist, (y0-cy)/dist,
-
- x1, y1, x2, y2 = get_normal_points(cx, cy, cos_t, sin_t, length)
-
- xx12, yy12 = (xx1+xx2)/2., (yy1+yy2)/2.,
- xx23, yy23 = (xx2+xx3)/2., (yy2+yy3)/2.,
-
- dist = sqrt((xx12-xx23)**2 + (yy12-yy23)**2)
- cos_t, sin_t = (xx12-xx23)/dist, (yy12-yy23)/dist,
-
- xm1, ym1, xm2, ym2 = get_normal_points(xx2, yy2, cos_t, sin_t, length*shrink_factor)
-
- l_plus = [(x1, y1), (xm1, ym1), (xx1, yy1)]
- l_minus = [(x2, y2), (xm2, ym2), (xx1, yy1)]
-
- return l_plus, l_minus
-
-
def find_control_points(c1x, c1y, mmx, mmy, c2x, c2y):
""" Find control points of the bezier line throught c1, mm, c2. We
- simply assume that c1, mm, c2 which have parameteric value 0, 0.5, and 1.
+ simply assume that c1, mm, c2 which have parametric value 0, 0.5, and 1.
"""
- cmx = .5 * (4*mmx - (c1x + c2x))
- cmy = .5 * (4*mmy - (c1y + c2y))
+ cmx = .5 * (4 * mmx - (c1x + c2x))
+ cmy = .5 * (4 * mmy - (c1y + c2y))
return [(c1x, c1y), (cmx, cmy), (c2x, c2y)]
def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.):
"""
- Being similar to get_parallels, returns
- control points of two quadrativ bezier lines having a width roughly parralel to given
- one separated by *width*.
+ Being similar to get_parallels, returns control points of two quadrativ
+ bezier lines having a width roughly parralel to given one separated by
+ *width*.
"""
# c1, cm, c2
@@ -464,7 +428,6 @@ def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.):
cmx, cmy = bezier2[1]
c3x, c3y = bezier2[2]
-
# t1 and t2 is the anlge between c1 and cm, cm, c3.
# They are also a angle of the tangential line of the path at c1 and c3
cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy)
@@ -475,24 +438,21 @@ def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.):
# bezier path at a distance of width. Same thing for c3_left and
# c3_right with respect to c3.
c1x_left, c1y_left, c1x_right, c1y_right = \
- get_normal_points(c1x, c1y, cos_t1, sin_t1, width*w1)
+ get_normal_points(c1x, c1y, cos_t1, sin_t1, width * w1)
c3x_left, c3y_left, c3x_right, c3y_right = \
- get_normal_points(c3x, c3y, cos_t2, sin_t2, width*w2)
-
-
+ get_normal_points(c3x, c3y, cos_t2, sin_t2, width * w2)
-
- # find c12, c23 and c123 which are middle points of c1-cm, cm-c3 and c12-c23
- c12x, c12y = (c1x+cmx)*.5, (c1y+cmy)*.5
- c23x, c23y = (cmx+c3x)*.5, (cmy+c3y)*.5
- c123x, c123y = (c12x+c23x)*.5, (c12y+c23y)*.5
+ # find c12, c23 and c123 which are middle points of c1-cm, cm-c3 and
+ # c12-c23
+ c12x, c12y = (c1x + cmx) * .5, (c1y + cmy) * .5
+ c23x, c23y = (cmx + c3x) * .5, (cmy + c3y) * .5
+ c123x, c123y = (c12x + c23x) * .5, (c12y + c23y) * .5
# tangential angle of c123 (angle between c12 and c23)
cos_t123, sin_t123 = get_cos_sin(c12x, c12y, c23x, c23y)
c123x_left, c123y_left, c123x_right, c123y_right = \
- get_normal_points(c123x, c123y, cos_t123, sin_t123, width*wm)
-
+ get_normal_points(c123x, c123y, cos_t123, sin_t123, width * wm)
path_left = find_control_points(c1x_left, c1y_left,
c123x_left, c123y_left,
@@ -504,8 +464,6 @@ def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.):
return path_left, path_right
-
-
def make_path_regular(p):
"""
fill in the codes if None.
@@ -520,6 +478,7 @@ def make_path_regular(p):
else:
return p
+
def concatenate_paths(paths):
"""
concatenate list of paths into a single path.
@@ -535,15 +494,3 @@ def concatenate_paths(paths):
_path = Path(np.concatenate(vertices),
np.concatenate(codes))
return _path
-
-
-
-if 0:
- path = Path([(0, 0), (1, 0), (2, 2)],
- [Path.MOVETO, Path.CURVE3, Path.CURVE3])
- left, right = divide_path_inout(path, inside)
- clf()
- ax = gca()
-
-
-
Please sign in to comment.
Something went wrong with that request. Please try again.