Skip to content

Commit

Permalink
add equidistant resampling
Browse files Browse the repository at this point in the history
  • Loading branch information
m-reuter committed Dec 16, 2024
1 parent 13d28af commit 972e6c4
Showing 1 changed file with 31 additions and 3 deletions.
34 changes: 31 additions & 3 deletions lapy/tria_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,6 @@ def level_length(self, vfunc, level):
else:
raise ValueError('No lengths computed, should never get here.')


@staticmethod
def reduce_edges_to_path(edges, start_idx=None, get_edge_idx=False):
"""Static helper to reduce undirected unsorted edges to path.
Expand Down Expand Up @@ -1240,7 +1239,30 @@ def reduce_edges_to_path(edges, start_idx=None, get_edge_idx=False):
else:
return path

def level_path(self, vfunc, level, get_tria_idx=False):
@staticmethod
def resample_polygon(path3d: np.ndarray, n_points: int = 100) -> np.ndarray:
# Helper: Cumulative Euclidean distance between successive polygon points.
# This will be the "x" for interpolation
d = np.cumsum(np.r_[0, np.sqrt((np.diff(path3d, axis=0) ** 2).sum(axis=1))])
# get linearly spaced points along the cumulative Euclidean distance
d_sampled = np.linspace(0, d.max(), n_points)
# interpolate x and y coordinates
xy_interp = np.c_[
np.interp(d_sampled, d, path3d[:, 0]),
np.interp(d_sampled, d, path3d[:, 1]),
np.interp(d_sampled, d, path3d[:, 2])
]
return xy_interp

@staticmethod
def iterative_resample_polygon(path3d: np.ndarray, n_points: int = 100, n_iter: int = 3) -> np.ndarray:
# Helper: resample multiple times to numerically stabilize the result to be truly equidistant
path3d_resampled = TriaMesh.resample_polygon(path3d, n_points)
for _ in range(n_iter-1):
path3d_resampled = TriaMesh.resample_polygon(path3d_resampled, n_points)
return path3d_resampled

def level_path(self, vfunc, level, get_tria_idx=False, n_points=None):
"""Extract levelset as a path.
Note: Only works for level sets that represent a single path with
Expand All @@ -1254,12 +1276,14 @@ def level_path(self, vfunc, level, get_tria_idx=False):
Level set value.
get_tria_idx : bool, default: False
Also return a list of triangle indices for each edge, default False.
n_points: resample level set into n equidistant points. Cannot be combined
with get_tria_idx=True.
Returns
-------
path: array
Array of shape (n,3) containing coordinates of vertices on level path.
length : float
length : float
Length of level set.
tria_idx : array
Array of triangle index for each edge segment on the path (length n-1
Expand Down Expand Up @@ -1317,7 +1341,11 @@ def level_path(self, vfunc, level, get_tria_idx=False):
eps=0.000001
path3d = path3d[dd>eps,:]
if get_tria_idx:
if n_points:
raise ValueError("n_points cannot be combined wiht get_tria_idx=True.")
tria_idx = tria_idx[dd[:-1]>eps]
return path3d, llength, tria_idx
else:
if n_points:
path3d = TriaMesh.iterative_resample_polygon(path3d, n_points)
return path3d, llength

0 comments on commit 972e6c4

Please sign in to comment.