Skip to content

Commit

Permalink
[Feature] Add rectangle and triangle sdf_func (PaddlePaddle#387)
Browse files Browse the repository at this point in the history
* add rectangle and triangle sdf_func

* fix naming
  • Loading branch information
AndPuQing authored Jun 17, 2023
1 parent 13dbdb3 commit d12920e
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions ppsci/geometry/geometry_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,35 @@ def is_valid(vertices):
and np.isclose(np.prod(vertices[0] - vertices[3]), 0)
)

def sdf_func(self, points: np.ndarray) -> np.ndarray:
"""Compute signed distance field.
Args:
points (np.ndarray): The coordinate points used to calculate the SDF value,
the shape of the array is [N, 2].
Returns:
np.ndarray: Unsquared SDF values of input points, the shape is [N, 1].
NOTE: This function usually returns ndarray with negative values, because
according to the definition of SDF, the SDF value of the coordinate point inside
the object(interior points) is negative, the outside is positive, and the edge
is 0. Therefore, when used for weighting, a negative sign is often added before
the result of this function.
"""
if points.shape[1] != 2:
raise ValueError(
f"Shape of given points should be [*, 2], but got {points.shape}"
)
center = (self.xmin + self.xmax) / 2
dist_from_center = (
np.abs(points - center) - np.array([self.xmax - self.xmin]) / 2
)
return -(
np.linalg.norm(np.maximum(dist_from_center, 0), axis=1)
+ np.minimum(np.max(dist_from_center, axis=1), 0)
).reshape(-1, 1)


class Triangle(geometry.Geometry):
"""Class for Triangle
Expand Down Expand Up @@ -369,6 +398,53 @@ def random_boundary_points(self, n, random="pseudo"):
x.append((l - self.l12 - self.l23) * self.n31 + self.x3)
return np.vstack(x)

def sdf_func(self, points: np.ndarray) -> np.ndarray:
"""Compute signed distance field.
Args:
points (np.ndarray): The coordinate points used to calculate the SDF value,
the shape of the array is [N, 2].
Returns:
np.ndarray: Unsquared SDF values of input points, the shape is [N, 1].
NOTE: This function usually returns ndarray with negative values, because
according to the definition of SDF, the SDF value of the coordinate point inside
the object(interior points) is negative, the outside is positive, and the edge
is 0. Therefore, when used for weighting, a negative sign is often added before
the result of this function.
"""
if points.shape[1] != 2:
raise ValueError(
f"Shape of given points should be [*, 2], but got {points.shape}"
)
v1p = points - self.x1 # v1p: vector from x1 to points
v2p = points - self.x2
v3p = points - self.x3
# vv12_p: vertical vector of points to v12(If the vertical point is in the extension of v12,
# the vector will be the vector from x1 to points)
vv12_p = (
self.v12
* np.clip(np.dot(v1p, self.v12.reshape(2, -1)) / self.l12**2, 0, 1)
- v1p
)
vv23_p = (
self.v23
* np.clip(np.dot(v2p, self.v23.reshape(2, -1)) / self.l23**2, 0, 1)
- v2p
)
vv31_p = (
self.v31
* np.clip(np.dot(v3p, self.v31.reshape(2, -1)) / self.l31**2, 0, 1)
- v3p
)
is_inside = self.is_inside(points).reshape(-1, 1) * 2 - 1
len_vv12_p = np.linalg.norm(vv12_p, axis=1, keepdims=True)
len_vv23_p = np.linalg.norm(vv23_p, axis=1, keepdims=True)
len_vv31_p = np.linalg.norm(vv31_p, axis=1, keepdims=True)
mini_dist = np.minimum(np.minimum(len_vv12_p, len_vv23_p), len_vv31_p)
return is_inside * mini_dist


class Polygon(geometry.Geometry):
"""Class for simple polygon.
Expand Down

0 comments on commit d12920e

Please sign in to comment.