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

Skip to content

Commit 480ea3f

Browse files
authored
Merge pull request #17282 from anntzer/segment_hits_overflow
Don't divide by zero in Line2D.segment_hits.
2 parents bd1e75a + fdf07f5 commit 480ea3f

File tree

1 file changed

+18
-23
lines changed

1 file changed

+18
-23
lines changed

lib/matplotlib/lines.py

Lines changed: 18 additions & 23 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((cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2)
83+
res, = np.nonzero(np.hypot(cx - x, cy - y) <= radius)
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-
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)
92+
u = (cx - xr) * dx + (cy - yr) * dy
93+
candidates = (0 <= u) & (u <= dx ** 2 + dy ** 2)
9594

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

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

112112

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

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
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
472467

473468
ind += self.ind_offset
474469

0 commit comments

Comments
 (0)