Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
90dce86
fix tightbbox to account for markeredgewidth
brunobeltran Feb 29, 2020
5ed49fd
cleanup definition of "point" marker
brunobeltran Mar 1, 2020
9088cf4
document unit_regular_polygon
brunobeltran Mar 1, 2020
fd6df9b
untested version of new code to get marker bbox
brunobeltran Mar 3, 2020
ef2fefd
fix for marker bbox now works except for on miter
brunobeltran Mar 3, 2020
db033e4
fixed mis-ordered PathEndAngles for ticks
brunobeltran Mar 3, 2020
7e41bf5
flake8 for new markers code
brunobeltran Mar 3, 2020
f1014b5
factor marker bbox code to be within MarkerStyles
brunobeltran Mar 3, 2020
42cc5db
bugfix, forgot self in MarkerStyle.get_centered_bbox
brunobeltran Mar 3, 2020
8fcb223
misc bugfixes after factoring get_centered_bbox
brunobeltran Mar 3, 2020
d95e4d8
markers bbox code visually tested, now works
brunobeltran Mar 3, 2020
4592cda
flake8 for new markers bbox code
brunobeltran Mar 3, 2020
c08826e
fixed formula for miter marker bbox, bevel broke
brunobeltran Mar 4, 2020
7f9db16
bugfix caret bbox calculation, incorrect angles
brunobeltran Mar 4, 2020
1805dc7
fixed star tip angle in marker bbox calculation
brunobeltran Mar 4, 2020
a13598d
test marker bbox. failing here, pass in jupyter
brunobeltran Mar 4, 2020
0f7300a
bugfix so markers bbox api stays in pts units
brunobeltran Mar 4, 2020
d6f1571
forgot to push new test references images up
brunobeltran Mar 4, 2020
2bee048
cleanup variable name consistency
brunobeltran Mar 6, 2020
66694a0
use conversion not magic nums for line get_extents
brunobeltran Mar 9, 2020
c4a45de
iter_curves: iterate over path more conveniently
brunobeltran Mar 9, 2020
c5bdd8d
helper functions for bezier curve zeros/tangents
brunobeltran Mar 10, 2020
41f268e
CornerInfo in bezier.py, should be path.py
brunobeltran Mar 10, 2020
637a7f2
update marker bbox to work for arbitrary paths
brunobeltran Mar 10, 2020
5ac9114
bugfix, new marker bbox code now runs, untested
brunobeltran Mar 10, 2020
ef36ec2
pyflake fixes for marker bbox code
brunobeltran Mar 10, 2020
82e3c12
cleanup path/bezier to prevent import triangle
brunobeltran Mar 12, 2020
8585eca
fix prev commit, make split_in_out method of Path
brunobeltran Mar 12, 2020
54e3a3e
generalized path bbox code tested on some markers
brunobeltran Mar 12, 2020
b390653
path bbox now works for all markers but "pixel"
brunobeltran Mar 12, 2020
85a3050
reorg'd path/bezier code now builds docs no errors
brunobeltran Mar 12, 2020
79aa3b7
cleanup docstrings of stroked path bbox code
brunobeltran Mar 12, 2020
1ea37be
fixed sphinx warnings in path.py's docstrings
brunobeltran Mar 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
helper functions for bezier curve zeros/tangents
  • Loading branch information
brunobeltran committed Mar 10, 2020
commit c5bdd8d592f0795403ee7776b86e84a5de3d46d3
67 changes: 61 additions & 6 deletions lib/matplotlib/bezier.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,73 @@ class BezierSegment:
"""

def __init__(self, control_points):
n = len(control_points)
self._orders = np.arange(n)
coeff = [math.factorial(n - 1)
// (math.factorial(i) * math.factorial(n - 1 - i))
for i in range(n)]
self._px = np.asarray(control_points).T * coeff
self.cpoints = np.asarray(control_points)
self.n, self.d = self.cpoints.shape
self._orders = np.arange(self.n)
coeff = [math.factorial(self.n - 1)
// (math.factorial(i) * math.factorial(self.n - 1 - i))
for i in range(self.n)]
self._px = self.cpoints.T * coeff

def point_at_t(self, t):
"""Return the point on the Bezier curve for parameter *t*."""
return tuple(
self._px @ (((1 - t) ** self._orders)[::-1] * t ** self._orders))

@property
def tan_in(self):
if self.n < 2:
raise ValueError("Need at least two control points to get tangent "
"vector!")
return self.cpoints[1] - self.cpoints[0]

@property
def tan_out(self):
if self.n < 2:
raise ValueError("Need at least two control points to get tangent "
"vector!")
return self.cpoints[-1] - self.cpoints[-2]

@property
def interior_extrema(self):
if self.n <= 2: # a line's extrema are always its tips
return np.array([]), np.array([])
elif self.n == 3: # quadratic curve
# the bezier curve in standard form is
# cp[0] * (1 - t)^2 + cp[1] * 2t(1-t) + cp[2] * t^2
# can be re-written as
# cp[0] + 2 (cp[1] - cp[0]) t + (cp[2] - 2 cp[1] + cp[0]) t^2
# which has simple derivative
# 2*(cp[2] - 2*cp[1] + cp[0]) t + 2*(cp[1] - cp[0])
num = 2*(self.cpoints[2] - 2*self.cpoints[1] + self.cpoints[0])
denom = self.cpoints[1] - self.cpoints[0]
mask = ~np.isclose(denom, 0)
zeros = num[mask]/denom[mask]
dims = np.arange(self.d)[mask]
in_range = (0 <= zeros) & (zeros <= 1)
return dims[in_range], zeros[in_range]
elif self.n == 4: # cubic curve
# derivative of cubic bezier curve has coefficients
a = 3*(points[3] - 3*points[2] + 3*points[1] - points[0])
b = 6*(points[2] - 2*points[1] + points[0])
c = 3*(points[1] - points[0])
under_sqrt = b**2 - 4*a*c
dims = []
zeros = []
for i in range(d):
if under_sqrt[i] < 0:
continue
roots = [(-b + np.sqrt(under_sqrt))/2/a,
(-b - np.sqrt(under_sqrt))/2/a]
for root in roots:
if 0 <= root <= 1:
dims.append(i)
zeros.append(root)
return np.asarray(dims), np.asarray(zeros)
else: # self.n > 4:
raise NotImplementedError("Zero finding only implemented up to "
"cubic curves.")


def split_bezier_intersecting_with_closedpath(
bezier, inside_closedpath, tolerance=0.01):
Expand Down