Skip to content

Commit

Permalink
[processing] Added isclose function to VoronoyPolygons.py to avoid nu…
Browse files Browse the repository at this point in the history
…merical instability

Fixes #8002 - hopefully, and adds tests

(cherry-picked from d2b71c3)
  • Loading branch information
havatv authored and nyalldawson committed Aug 9, 2018
1 parent 450f9f3 commit 7c2a998
Show file tree
Hide file tree
Showing 4 changed files with 1,570 additions and 1 deletion.
11 changes: 10 additions & 1 deletion python/plugins/processing/algs/qgis/VoronoiPolygons.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ def clip_voronoi(self, edges, c, width, height, extent, point, xyminmax):
pt_y = point.y() - extent.yMinimum()
(xmin, ymin, xmax, ymax) = xyminmax

def isclose(a, b, rel_tol=1e-9, abs_tol=0.0):
return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

def clip_line(x1, y1, x2, y2, w, h):
if x1 < 0 and x2 < 0:
# Completely to the left
Expand All @@ -210,6 +213,7 @@ def clip_line(x1, y1, x2, y2, w, h):
if y1 > h and y2 > h:
# Completely above
return [0, 0, 0, 0]
# Clip on the left envelope boundary
if x1 < 0:
# First point to the left
y1 = (y1 * x2 - y2 * x1) / (x2 - x1)
Expand All @@ -218,6 +222,7 @@ def clip_line(x1, y1, x2, y2, w, h):
# Last point to the left
y2 = (y1 * x2 - y2 * x1) / (x2 - x1)
x2 = 0
# Clip on the right envelope boundary
if x1 > w:
# First point to the right
y1 = y1 + (w - x1) * (y2 - y1) / (x2 - x1)
Expand All @@ -226,8 +231,9 @@ def clip_line(x1, y1, x2, y2, w, h):
# Last point to the right
y2 = y1 + (w - x1) * (y2 - y1) / (x2 - x1)
x2 = w
if x1 == x2 and y1 == y2:
if isclose(x1, x2) and isclose(y1, y2):
return [0, 0, 0, 0]
# Clip on the bottom envelope boundary
if y1 < 0:
# First point below
x1 = (x1 * y2 - x2 * y1) / (y2 - y1)
Expand All @@ -236,6 +242,7 @@ def clip_line(x1, y1, x2, y2, w, h):
# Second point below
x2 = (x1 * y2 - x2 * y1) / (y2 - y1)
y2 = 0
# Clip on the top envelope boundary
if y1 > h:
# First point above
x1 = x1 + (h - y1) * (x2 - x1) / (y2 - y1)
Expand All @@ -244,6 +251,8 @@ def clip_line(x1, y1, x2, y2, w, h):
# Second point above
x2 = x1 + (h - y1) * (x2 - x1) / (y2 - y1)
y2 = h
if isclose(x1, x2) and isclose(y1, y2):
return [0, 0, 0, 0]
return [x1, y1, x2, y2]

bndpoints = []
Expand Down
Loading

0 comments on commit 7c2a998

Please sign in to comment.