Newer
Older
Hans Stephensen
committed
import logging
from polygon_triangulate import polygon_triangulate, PlotTriangulation
from tetrahedralize_triangles import tetrahedralize
Hans Stephensen
committed
logging.basicConfig(filename='warnings.log', level=logging.DEBUG)
def measure_volume(V_tet, T, origin, r):
sphere = overlap.Sphere(origin, r)
volume = 0.0
Hans Stephensen
committed
volumes = []
for tet in T:
vertices = V_tet[tet]
overlap_tet = overlap.Tetrahedron(vertices)
overlap_volume = overlap.overlap(sphere, overlap_tet)
Hans Stephensen
committed
volumes.append(overlap_volume)
if overlap_volume < 0:
print('Encountered negative volume overlap')
logging.warning('Encountered negative volume overlap')
Hans Stephensen
committed
#import matplotlib.pyplot as plt
#plt.title(f'radius {r} total {volume}')
#plt.plot(np.arange(len(volumes)), volumes)
#plt.show()
return volume
def same_point(x, y):
return np.linalg.norm(x - y) < 1e-10
def remove_duplicate_contour_points(P):
n = len(P)
for i in range(n):
j = (i + 1) % n
if same_point(P[i], P[j]):
return remove_duplicate_contour_points(np.delete(P, i, axis=0))
return P
Hans Stephensen
committed
def remove_line_triangles(P, F):
n = len(F)
for i in range(n-1, -1, -1):
PF = P[F[i]]
v1 = PF[0] - PF[1]
v2 = PF[1] - PF[2]
if np.isclose(np.abs(np.dot(v1/np.linalg.norm(v1),v2/np.linalg.norm(v2))),1):
F = np.delete(F, i, axis=0)
return F
def measure_cumulative_volume(z, P, thickness, origin, R):
'''
Integration of the intersecting volume of a thick polygon and a sphere of increasing radius.
Parameters
----------
z : float
The z depth-wise coordinate of the thick polygon.
P : (N, 2) array_like
A real array of ordered contour points of the polygon.
thickness : float
The thickness of the polygon.
origin : (3,) array_like
The center of the sphere from which to integrate from.
R : (M,) array_like
The discrete sphere radii from which to measure the polygon in.
Returns
-------
mu: (M,) array_like
The intersecting volumes of the sphere and the thick polygon at radii determined by R.
'''
P = np.array(P)
origin = np.array(origin)
P = remove_duplicate_contour_points(P)
z0 = z - thickness / 2
z1 = z + thickness / 2
_, V_tri, F = polygon_triangulate(P)
Hans Stephensen
committed
F = remove_line_triangles(V_tri, F)
#import matplotlib.pyplot as plt
#print(V_tri[:5,:])
#PlotTriangulation(V_tri, F)
#plt.show()
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
V_tet, T = tetrahedralize(V_tri, F, z0, z1)
mu = np.zeros(len(R))
for i, r in enumerate(R):
if r <= 0:
continue
mu[i] = measure_volume(V_tet, T, origin, r)
return mu
def measure_cumulative_points(z, X, thickness, origin, R):
'''
Integration of the points placed in a thick section integrated intersecting with a sphere of increasing size.
Parameters
----------
z : float
The z depth-wise coordinate of the section with the points.
X : (N, 2) array_like
A real array of points inside the section.
thickness : float
The thickness of the section of which the points are in.
origin : (3,) array_like
The center of the sphere from which to integrate from.
R : (M,) array_like
The discrete sphere radii from which to measure the points inside.
Returns
-------
mu: (M,) array_like
The integrated point masses inside the sphere of radii determined by R.
'''
oz = origin[2]
oxy = origin[:2]
dxy = np.array([np.linalg.norm(x - oxy) for x in X])
mu = np.zeros(len(R))
if z == oz:
for i, r in enumerate(R):
s = np.sqrt(np.clip(r**2 - dxy**2, 0, None))
mu[i] = np.sum(np.clip(2*s/thickness, 0, 1))
return mu
# plane is below, mirror it above to simplify calculations
if z < oz:
z = z + 2*(oz - z)
z0 = z - thickness / 2
z1 = z + thickness / 2
d0 = z0 - oz
for i, r in enumerate(R):
h = np.sqrt(np.clip(r**2 - dxy**2, 0, None))
s = h - d0
mu[i] = np.sum(np.clip(s/thickness, 0, 1))