Newer
Older
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
import numpy as np
class TriangulatedSurface(object):
"""
center: center of mass [m^3]
m: total mass [kg]
im: 3, 3 | inertia matrix relative to center of mass [kg m^2]
"""
def __init__(self, rho, vertices=None, triangles=None):
"""
:param rho: constant density of the solid object [kg/m^3]
:param vertices: n, 3 | vertices of 3d object [m]
:param triangles: m, 3 | triangles composing the object's surface
Assume that these are vertices are consistently ordered
For a closed body, all surface normals pointing outward is sufficient
"""
self.rho = rho
self.vertices = vertices
self.triangles = triangles
self.m = None
self.center = None
self.im = None
def calculate_mass_properties(vertices, triangles, rho):
"""
Calculate mass properties of solid object via surface integrals
following supplemental material for:
M. Bacher, et al., ”Spin-It: Optimizing Moment of
Inertia for Spinnable Objects", ACM Trans. Graphics, 2014.
:param vertices: n, 3 | vertices of 3d object [m]
:param triangles: m, 3 | triangles composing the object's surface
Assume that these are vertices are consistently ordered
:param rho: constant density of the solid object [kg/m^3]
:return:
"""
s = np.zeros((10,))
for ijk in triangles:
a, b, c = vertices[ijk]
bars = vertices[ijk, :].copy()
bars = bars[:, [1, 2, 0]]
u = b - a
v = c - a
n = np.cross(u, v)
h1 = a + b + c
h2 = a**2 + b * (a + b)
h3 = h2 + c * h1
h4 = a**3 + b * h2 + c * h3
h5 = h3 + a * (h1 + a)
h6 = h3 + b * (h1 + b)
h7 = h3 + c * (h1 + c)
h8 = bars[0] * h5 + bars[1] * h6 + bars[2] * h7
s[0] += (n * h1)[0]
s[1:4] += n * h3
s[4:7] += n * h8
s[7:] += n * h4
s[0] /= 6
s[1:4] /= 24
s[4:7] /= 120
s[7:] /= 60
s *= rho
m = s[0]
center = s[1:4] / m
im = np.array([
[s[8] + s[9], -s[4], -s[6]],
[-s[4], s[7] + s[9], -s[5]],
[-s[6], -s[5], s[7] + s[8]],
])
return m, center, im