[utils] remove_duplicate_vertices now takes a tolerance (default exact)
This commit is contained in:
parent
4d57936da8
commit
f4df8e0553
2 changed files with 40 additions and 3 deletions
|
|
@ -5,7 +5,15 @@ from numpy.testing import assert_equal, assert_allclose
|
|||
from numpy import pi
|
||||
import pytest
|
||||
|
||||
from ..utils import remove_duplicate_vertices, remove_colinear_vertices, poly_contains_points, rotation_matrix_2d, apply_transforms, normalize_mirror, DeferredDict
|
||||
from ..utils import (
|
||||
DeferredDict,
|
||||
apply_transforms,
|
||||
normalize_mirror,
|
||||
poly_contains_points,
|
||||
remove_colinear_vertices,
|
||||
remove_duplicate_vertices,
|
||||
rotation_matrix_2d,
|
||||
)
|
||||
from ..file.utils import tmpfile
|
||||
from ..utils.curves import bezier
|
||||
from ..error import PatternError
|
||||
|
|
@ -23,6 +31,23 @@ def test_remove_duplicate_vertices() -> None:
|
|||
assert_equal(v_clean_open, [[0, 0], [1, 1], [2, 2], [0, 0]])
|
||||
|
||||
|
||||
def test_remove_duplicate_vertices_tolerance_defaults_to_exact_match() -> None:
|
||||
v = [[0, 0], [1, 1], [1 + 1e-13, 1], [2, 2], [1e-13, 0]]
|
||||
|
||||
assert_allclose(remove_duplicate_vertices(v, closed_path=True), v, atol=0, rtol=0)
|
||||
assert_allclose(
|
||||
remove_duplicate_vertices(v, closed_path=True, tolerance=1e-12),
|
||||
[[0, 0], [1 + 1e-13, 1], [2, 2]],
|
||||
atol=0,
|
||||
rtol=0,
|
||||
)
|
||||
|
||||
|
||||
def test_remove_duplicate_vertices_rejects_negative_tolerance() -> None:
|
||||
with pytest.raises(ValueError, match='non-negative'):
|
||||
remove_duplicate_vertices([[0, 0]], tolerance=-1)
|
||||
|
||||
|
||||
def test_remove_colinear_vertices() -> None:
|
||||
v = [[0, 0], [1, 0], [2, 0], [2, 1], [2, 2], [1, 1], [0, 0]]
|
||||
v_clean = remove_colinear_vertices(v, closed_path=True)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ import numpy
|
|||
from numpy.typing import NDArray, ArrayLike
|
||||
|
||||
|
||||
def remove_duplicate_vertices(vertices: ArrayLike, closed_path: bool = True) -> NDArray[numpy.float64]:
|
||||
def remove_duplicate_vertices(
|
||||
vertices: ArrayLike,
|
||||
closed_path: bool = True,
|
||||
tolerance: float = 0.0,
|
||||
) -> NDArray[numpy.float64]:
|
||||
"""
|
||||
Given a list of vertices, remove any consecutive duplicates.
|
||||
|
||||
|
|
@ -13,14 +17,22 @@ def remove_duplicate_vertices(vertices: ArrayLike, closed_path: bool = True) ->
|
|||
vertices: `[[x0, y0], [x1, y1], ...]`
|
||||
closed_path: If True, `vertices` is interpreted as an implicity-closed path
|
||||
(i.e. the last vertex will be removed if it is the same as the first)
|
||||
tolerance: Maximum coordinate-wise absolute difference for two vertices to
|
||||
be considered duplicates. Default `0` requires exact equality.
|
||||
|
||||
Returns:
|
||||
`vertices` with no consecutive duplicates. This may be a view into the original array.
|
||||
"""
|
||||
if tolerance < 0:
|
||||
raise ValueError(f'tolerance must be non-negative, got {tolerance}')
|
||||
|
||||
vertices = numpy.asarray(vertices)
|
||||
if vertices.shape[0] <= 1:
|
||||
return vertices
|
||||
duplicates = (vertices == numpy.roll(vertices, -1, axis=0)).all(axis=1)
|
||||
if tolerance == 0:
|
||||
duplicates = (vertices == numpy.roll(vertices, -1, axis=0)).all(axis=1)
|
||||
else:
|
||||
duplicates = (numpy.abs(vertices - numpy.roll(vertices, -1, axis=0)) <= tolerance).all(axis=1)
|
||||
if not closed_path:
|
||||
duplicates[-1] = False
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue