-
Notifications
You must be signed in to change notification settings - Fork 12
/
utilities.py
118 lines (93 loc) · 4.34 KB
/
utilities.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
from mayavi import mlab
import numpy as np
import plyfile
def showSuperquadrics(x, threshold = 1e-2, num_limit = 10000, arclength = 0.02):
# avoid numerical instability in sampling
if x.shape[0] < 0.007:
x.shape[0] = 0.007
if x.shape[1] < 0.007:
x.shape[1] = 0.007
# sampling points in superellipse
point_eta = uniformSampledSuperellipse(x.shape[0], [1, x.scale[2]], threshold, num_limit, arclength)
point_omega = uniformSampledSuperellipse(x.shape[1], [x.scale[0], x.scale[1]], threshold, num_limit, arclength)
# preallocate meshgrid
x_mesh = np.ones((np.shape(point_omega)[1], np.shape(point_eta)[1]))
y_mesh = np.ones((np.shape(point_omega)[1], np.shape(point_eta)[1]))
z_mesh = np.ones((np.shape(point_omega)[1], np.shape(point_eta)[1]))
for m in range(np.shape(point_omega)[1]):
for n in range(np.shape(point_eta)[1]):
point_temp = np.zeros(3)
point_temp[0 : 2] = point_omega[:, m] * point_eta[0, n]
point_temp[2] = point_eta[1, n]
point_temp = x.RotM @ point_temp + x.translation
x_mesh[m, n] = point_temp[0]
y_mesh[m, n] = point_temp[1]
z_mesh[m, n] = point_temp[2]
mlab.view(azimuth=0.0, elevation=0.0, distance=2)
mlab.mesh(x_mesh, y_mesh, z_mesh, color=(0, 0, 1), opacity=0.8)
def uniformSampledSuperellipse(epsilon, scale, threshold = 1e-2, num_limit = 10000, arclength = 0.02):
# initialize array storing sampled theta
theta = np.zeros(num_limit)
theta[0] = 0
for i in range(num_limit):
dt = dtheta(theta[i], arclength, threshold, scale, epsilon)
theta_temp = theta[i] + dt
if theta_temp > np.pi / 4:
theta[i + 1] = np.pi / 4
break
else:
if i + 1 < num_limit:
theta[i + 1] = theta_temp
else:
raise Exception(
'Number of the sampled points exceed the preset limit', \
num_limit,
'Please decrease the sampling arclength.'
)
critical = i + 1
for j in range(critical + 1, num_limit):
dt = dtheta(theta[j], arclength, threshold, np.flip(scale), epsilon)
theta_temp = theta[j] + dt
if theta_temp > np.pi / 4:
break
else:
if j + 1 < num_limit:
theta[j + 1] = theta_temp
else:
raise Exception(
'Number of the sampled points exceed the preset limit', \
num_limit,
'Please decrease the sampling arclength.'
)
num_pt = j
theta = theta[0 : num_pt + 1]
point_fw = angle2points(theta[0 : critical + 1], scale, epsilon)
point_bw = np.flip(angle2points(theta[critical + 1: num_pt + 1], np.flip(scale), epsilon), (0, 1))
point = np.concatenate((point_fw, point_bw), 1)
point = np.concatenate((point, np.flip(point[:, 0 : num_pt], 1) * np.array([[-1], [1]]),
point[:, 1 : num_pt + 1] * np.array([[-1], [-1]]),
np.flip(point[:, 0 : num_pt], 1) * np.array([[1], [-1]])), 1)
return point
def dtheta(theta, arclength, threshold, scale, epsilon):
# calculation the sampling step size
if theta < threshold:
dt = np.abs(np.power(arclength / scale[1] +np.power(theta, epsilon), \
(1 / epsilon)) - theta)
else:
dt = arclength / epsilon * ((np.cos(theta) ** 2 * np.sin(theta) ** 2) /
(scale[0] ** 2 * np.cos(theta) ** (2 * epsilon) * np.sin(theta) ** 4 +
scale[1] ** 2 * np.sin(theta) ** (2 * epsilon) * np.cos(theta) ** 4)) ** (1 / 2)
return dt
def angle2points(theta, scale, epsilon):
point = np.zeros((2, np.shape(theta)[0]))
point[0] = scale[0] * np.sign(np.cos(theta)) * np.abs(np.cos(theta)) ** epsilon
point[1] = scale[1] * np.sign(np.sin(theta)) * np.abs(np.sin(theta)) ** epsilon
return point
def read_ply(path_to_file):
# read points from a .ply file and store in an nparray
plydata = plyfile.PlyData.read(path_to_file)
pc = plydata['vertex'].data
return np.array([[x, y, z] for x, y, z in pc])
def showPoints(point, scale_factor=0.1):
mlab.view(azimuth=0.0, elevation=0.0, distance=2)
mlab.points3d(point[:, 0], point[:, 1], point[:, 2], scale_factor=scale_factor, color=(1, 0, 0))