Skip to content

Commit

Permalink
add Polygon sdf (#406)
Browse files Browse the repository at this point in the history
* add Polygon sdf

* add Polygon sdf

* rewrite Polygon sdf

* rewrite Polygon sdf

* rewrite Polygon sdf

* rewrite Polygon sdf

* rewrite Polygon sdf

* rewrite Polygon sdf

* rewrite Polygon sdf and add some annotations

* rewrite Polygon sdf

* rewrite Polygon sdf

* rewrite Polygon sdf

* rewrite Polygon sdf
  • Loading branch information
mrcangye authored Jun 27, 2023
1 parent 507b385 commit abf9559
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions ppsci/geometry/geometry_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,51 @@ def random_boundary_points(self, n, random="pseudo"):
x.append((l - l0) * v + self.vertices[i])
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 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.
"""
sdf_value = np.empty((points.shape[0], 1), dtype=paddle.get_default_dtype())
for n in range(points.shape[0]):
distance = np.dot(
points[n] - self.vertices[0], points[n] - self.vertices[0]
)
inside_tag = 1.0
for i in range(self.vertices.shape[0]):
j = (self.vertices.shape[0] - 1) if i == 0 else (i - 1)
# Calculate the shortest distance from point P to each edge.
vector_ij = self.vertices[j] - self.vertices[i]
vector_in = points[n] - self.vertices[i]
distance_vector = vector_in - vector_ij * np.clip(
np.dot(vector_in, vector_ij) / np.dot(vector_ij, vector_ij),
0.0,
1.0,
)
distance = np.minimum(
distance, np.dot(distance_vector, distance_vector)
)
# Calculate the inside and outside using the Odd-even rule
odd_even_rule_number = np.array(
[
points[n][1] >= self.vertices[i][1],
points[n][1] < self.vertices[j][1],
vector_ij[0] * vector_in[1] > vector_ij[1] * vector_in[0],
]
)
if odd_even_rule_number.all() or np.all(~odd_even_rule_number):
inside_tag *= -1.0
sdf_value[n] = inside_tag * np.sqrt(distance)
return -sdf_value


def polygon_signed_area(vertices):
"""The (signed) area of a simple polygon.
Expand Down

0 comments on commit abf9559

Please sign in to comment.