GtePolyhedralMassProperties.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
11 
12 namespace gte
13 {
14 
15 // The input triangle mesh must represent a polyhedron. The triangles are
16 // represented as triples of indices <V0,V1,V2> into the vertex array.
17 // The index array has numTriangles such triples. The Boolean value
18 // 'bodyCoords is' 'true' if you want the inertia tensor to be relative to
19 // body coordinates but 'false' if you want it to be relative to world
20 // coordinates.
21 //
22 // The code assumes the rigid body has a constant density of 1. If your
23 // application assigns a constant density of 'd', then you must multiply
24 // the output 'mass' by 'd' and the output 'inertia' by 'd'.
25 
26 template <typename Real>
27 void ComputeMassProperties(Vector3<Real> const* vertices, int numTriangles,
28  int const* indices, bool bodyCoords, Real& mass, Vector3<Real>& center,
29  Matrix3x3<Real>& inertia);
30 
31 
32 template <typename Real>
33 void ComputeMassProperties(Vector3<Real> const* vertices, int numTriangles,
34  int const* indices, bool bodyCoords, Real& mass, Vector3<Real>& center,
35  Matrix3x3<Real>& inertia)
36 {
37  Real const oneDiv6 = (Real)(1.0 / 6.0);
38  Real const oneDiv24 = (Real)(1.0 / 24.0);
39  Real const oneDiv60 = (Real)(1.0 / 60.0);
40  Real const oneDiv120 = (Real)(1.0 / 120.0);
41 
42  // order: 1, x, y, z, x^2, y^2, z^2, xy, yz, zx
43  Real integral[10] = { (Real)0.0, (Real)0.0, (Real)0.0, (Real)0.0,
44  (Real)0.0, (Real)0.0, (Real)0.0, (Real)0.0, (Real)0.0, (Real)0.0 };
45 
46  int const* index = indices;
47  for (int i = 0; i < numTriangles; ++i)
48  {
49  // Get vertices of triangle i.
50  Vector3<Real> v0 = vertices[*index++];
51  Vector3<Real> v1 = vertices[*index++];
52  Vector3<Real> v2 = vertices[*index++];
53 
54  // Get cross product of edges and normal vector.
55  Vector3<Real> V1mV0 = v1 - v0;
56  Vector3<Real> V2mV0 = v2 - v0;
57  Vector3<Real> N = Cross(V1mV0, V2mV0);
58 
59  // Compute integral terms.
60  Real tmp0, tmp1, tmp2;
61  Real f1x, f2x, f3x, g0x, g1x, g2x;
62  tmp0 = v0[0] + v1[0];
63  f1x = tmp0 + v2[0];
64  tmp1 = v0[0] * v0[0];
65  tmp2 = tmp1 + v1[0] * tmp0;
66  f2x = tmp2 + v2[0] * f1x;
67  f3x = v0[0] * tmp1 + v1[0] * tmp2 + v2[0] * f2x;
68  g0x = f2x + v0[0] * (f1x + v0[0]);
69  g1x = f2x + v1[0] * (f1x + v1[0]);
70  g2x = f2x + v2[0] * (f1x + v2[0]);
71 
72  Real f1y, f2y, f3y, g0y, g1y, g2y;
73  tmp0 = v0[1] + v1[1];
74  f1y = tmp0 + v2[1];
75  tmp1 = v0[1] * v0[1];
76  tmp2 = tmp1 + v1[1] * tmp0;
77  f2y = tmp2 + v2[1] * f1y;
78  f3y = v0[1] * tmp1 + v1[1] * tmp2 + v2[1] * f2y;
79  g0y = f2y + v0[1] * (f1y + v0[1]);
80  g1y = f2y + v1[1] * (f1y + v1[1]);
81  g2y = f2y + v2[1] * (f1y + v2[1]);
82 
83  Real f1z, f2z, f3z, g0z, g1z, g2z;
84  tmp0 = v0[2] + v1[2];
85  f1z = tmp0 + v2[2];
86  tmp1 = v0[2] * v0[2];
87  tmp2 = tmp1 + v1[2] * tmp0;
88  f2z = tmp2 + v2[2] * f1z;
89  f3z = v0[2] * tmp1 + v1[2] * tmp2 + v2[2] * f2z;
90  g0z = f2z + v0[2] * (f1z + v0[2]);
91  g1z = f2z + v1[2] * (f1z + v1[2]);
92  g2z = f2z + v2[2] * (f1z + v2[2]);
93 
94  // Update integrals.
95  integral[0] += N[0] * f1x;
96  integral[1] += N[0] * f2x;
97  integral[2] += N[1] * f2y;
98  integral[3] += N[2] * f2z;
99  integral[4] += N[0] * f3x;
100  integral[5] += N[1] * f3y;
101  integral[6] += N[2] * f3z;
102  integral[7] += N[0] * (v0[1] * g0x + v1[1] * g1x + v2[1] * g2x);
103  integral[8] += N[1] * (v0[2] * g0y + v1[2] * g1y + v2[2] * g2y);
104  integral[9] += N[2] * (v0[0] * g0z + v1[0] * g1z + v2[0] * g2z);
105  }
106 
107  integral[0] *= oneDiv6;
108  integral[1] *= oneDiv24;
109  integral[2] *= oneDiv24;
110  integral[3] *= oneDiv24;
111  integral[4] *= oneDiv60;
112  integral[5] *= oneDiv60;
113  integral[6] *= oneDiv60;
114  integral[7] *= oneDiv120;
115  integral[8] *= oneDiv120;
116  integral[9] *= oneDiv120;
117 
118  // mass
119  mass = integral[0];
120 
121  // center of mass
122  center = Vector3<Real>{ integral[1], integral[2], integral[3] } / mass;
123 
124  // inertia relative to world origin
125  inertia(0, 0) = integral[5] + integral[6];
126  inertia(0, 1) = -integral[7];
127  inertia(0, 2) = -integral[9];
128  inertia(1, 0) = inertia(0, 1);
129  inertia(1, 1) = integral[4] + integral[6];
130  inertia(1, 2) = -integral[8];
131  inertia(2, 0) = inertia(0, 2);
132  inertia(2, 1) = inertia(1, 2);
133  inertia(2, 2) = integral[4] + integral[5];
134 
135  // inertia relative to center of mass
136  if (bodyCoords)
137  {
138  inertia(0, 0) -= mass*(center[1] * center[1] +
139  center[2] * center[2]);
140  inertia(0, 1) += mass*center[0] * center[1];
141  inertia(0, 2) += mass*center[2] * center[0];
142  inertia(1, 0) = inertia(0, 1);
143  inertia(1, 1) -= mass*(center[2] * center[2] +
144  center[0] * center[0]);
145  inertia(1, 2) += mass*center[1] * center[2];
146  inertia(2, 0) = inertia(0, 2);
147  inertia(2, 1) = inertia(1, 2);
148  inertia(2, 2) -= mass*(center[0] * center[0] +
149  center[1] * center[1]);
150  }
151 }
152 
153 
154 }
GLfloat GLfloat v1
Definition: glcorearb.h:812
GLsizei GLenum const void * indices
Definition: glcorearb.h:401
GLfloat v0
Definition: glcorearb.h:811
DualQuaternion< Real > Cross(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
void ComputeMassProperties(Vector3< Real > const *vertices, int numTriangles, int const *indices, bool bodyCoords, Real &mass, Vector3< Real > &center, Matrix3x3< Real > &inertia)
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:813
GLuint index
Definition: glcorearb.h:781


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01