Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 93cf388

Browse files
committed
Revert "Don't divide by zero in Line2D.segment_hits."
This reverts commit fdf07f5.
1 parent 54a61cc commit 93cf388

File tree

1 file changed

+23
-18
lines changed

1 file changed

+23
-18
lines changed

lib/matplotlib/lines.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def segment_hits(cx, cy, x, y, radius):
8080
"""
8181
# Process single points specially
8282
if len(x) <= 1:
83-
res, = np.nonzero(np.hypot(cx - x, cy - y) <= radius)
83+
res, = np.nonzero((cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2)
8484
return res
8585

8686
# We need to lop the last element off a lot.
@@ -89,24 +89,24 @@ def segment_hits(cx, cy, x, y, radius):
8989
# Only look at line segments whose nearest point to C on the line
9090
# lies within the segment.
9191
dx, dy = x[1:] - xr, y[1:] - yr
92-
u = (cx - xr) * dx + (cy - yr) * dy
93-
candidates = (0 <= u) & (u <= dx ** 2 + dy ** 2)
92+
Lnorm_sq = dx ** 2 + dy ** 2 # Possibly want to eliminate Lnorm==0
93+
u = ((cx - xr) * dx + (cy - yr) * dy) / Lnorm_sq
94+
candidates = (u >= 0) & (u <= 1)
9495

9596
# Note that there is a little area near one side of each point
9697
# which will be near neither segment, and another which will
9798
# be near both, depending on the angle of the lines. The
9899
# following radius test eliminates these ambiguities.
99-
point_hits = np.hypot(cx - x, cy - y) <= radius
100+
point_hits = (cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2
100101
candidates = candidates & ~(point_hits[:-1] | point_hits[1:])
101102

102103
# For those candidates which remain, determine how far they lie away
103104
# from the line.
104105
px, py = xr + u * dx, yr + u * dy
105-
line_hits = np.hypot(cx - px, cy - py) <= radius
106+
line_hits = (cx - px) ** 2 + (cy - py) ** 2 <= radius ** 2
106107
line_hits = line_hits & candidates
107-
108-
points, = point_hits.nonzero()
109-
lines, = line_hits.nonzero()
108+
points, = point_hits.ravel().nonzero()
109+
lines, = line_hits.ravel().nonzero()
110110
return np.concatenate((points, lines))
111111

112112

@@ -454,16 +454,21 @@ def contains(self, mouseevent):
454454
else:
455455
pixels = self.figure.dpi / 72. * self.pickradius
456456

457-
# Check for collision
458-
if self._linestyle in ['None', None]:
459-
# If no line, return the nearby point(s)
460-
ind, = np.nonzero(
461-
np.hypot(xt - mouseevent.x, yt - mouseevent.y) <= pixels)
462-
else:
463-
# If line, return the nearby segment(s)
464-
ind = segment_hits(mouseevent.x, mouseevent.y, xt, yt, pixels)
465-
if self._drawstyle.startswith("steps"):
466-
ind //= 2
457+
# The math involved in checking for containment (here and inside of
458+
# segment_hits) assumes that it is OK to overflow, so temporarily set
459+
# the error flags accordingly.
460+
with np.errstate(all='ignore'):
461+
# Check for collision
462+
if self._linestyle in ['None', None]:
463+
# If no line, return the nearby point(s)
464+
ind, = np.nonzero(
465+
(xt - mouseevent.x) ** 2 + (yt - mouseevent.y) ** 2
466+
<= pixels ** 2)
467+
else:
468+
# If line, return the nearby segment(s)
469+
ind = segment_hits(mouseevent.x, mouseevent.y, xt, yt, pixels)
470+
if self._drawstyle.startswith("steps"):
471+
ind //= 2
467472

468473
ind += self.ind_offset
469474

0 commit comments

Comments
 (0)