GteMassSpringVolume.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 template <int N, typename Real>
16 class MassSpringVolume : public ParticleSystem<N, Real>
17 {
18 public:
19  // Construction and destruction. This class represents an SxRxC array of
20  // masses lying on in a volume and connected by an array of springs. The
21  // masses are indexed by mass[s][r][c] for 0 <= s < S, 0 <= r < R, and
22  // 0 <= c < C. The mass at interior position X[s][r][c] is connected by
23  // springs to the masses at positions X[s][r-1][c], X[s][r+1][c],
24  // X[s][r][c-1], X[s][r][c+1], X[s-1][r][c], and X[s+1][r][c]. Boundary
25  // masses have springs connecting them to the obvious neighbors ("face"
26  // mass has 5 neighbors, "edge" mass has 4 neighbors, "corner" mass has 3
27  // neighbors). The masses are arranged in lexicographical order:
28  // position[c+C*(r+R*s)] = X[s][r][c] for 0 <= s < S, 0 <= r < R, and
29  // 0 <= c < C. The other arrays are stored similarly.
30  virtual ~MassSpringVolume();
31  MassSpringVolume(int numSlices, int numRows, int numCols, Real step);
32 
33  // Member access.
34  inline int GetNumSlices() const;
35  inline int GetNumRows() const;
36  inline int GetNumCols() const;
37  inline void SetMass(int s, int r, int c, Real mass);
38  inline void SetPosition(int s, int r, int c,
39  Vector<N, Real> const& position);
40  inline void SetVelocity(int s, int r, int c,
41  Vector<N, Real> const& velocity);
42  Real const& GetMass(int s, int r, int c) const;
43  inline Vector<N, Real> const& GetPosition(int s, int r, int c) const;
44  inline Vector<N, Real> const& GetVelocity(int s, int r, int c) const;
45 
46  // Each interior mass at (s,r,c) has 6 adjacent springs. Face masses
47  // have only 5 neighbors, edge masses have only 4 neighbors, and corner
48  // masses have only 3 neighbors. Each mass provides access to 3 adjacent
49  // springs at (s,r,c+1), (s,r+1,c), and (s+1,r,c). The face, edge, and
50  // corner masses provide access to only an appropriate subset of these.
51  // The caller is responsible for ensuring the validity of the (s,r,c)
52  // inputs.
53  inline void SetConstantS(int s, int r, int c,
54  Real constant); // to (s+1,r,c)
55  inline void SetLengthS(int s, int r, int c,
56  Real length); // to (s+1,r,c)
57  inline void SetConstantR(int s, int r, int c,
58  Real constant); // to (s,r+1,c)
59  inline void SetLengthR(int s, int r, int c,
60  Real length); // to (s,r+1,c)
61  inline void SetConstantC(int s, int r, int c,
62  Real constant); // to (s,r,c+1)
63  inline void SetLengthC(int s, int r, int c,
64  Real length); // spring to (s,r,c+1)
65  inline Real const& GetConstantS(int s, int r, int c) const;
66  inline Real const& GetLengthS(int s, int r, int c) const;
67  inline Real const& GetConstantR(int s, int r, int c) const;
68  inline Real const& GetLengthR(int s, int r, int c) const;
69  inline Real const& GetConstantC(int s, int r, int c) const;
70  inline Real const& GetLengthC(int s, int r, int c) const;
71 
72  // The default external force is zero. Derive a class from this one to
73  // provide nonzero external forces such as gravity, wind, friction,
74  // and so on. This function is called by Acceleration(...) to compute
75  // the impulse F/m generated by the external force F.
76  virtual Vector<N, Real> ExternalAcceleration(int i, Real time,
77  std::vector<Vector<N, Real>> const& position,
78  std::vector<Vector<N, Real>> const& velocity);
79 
80 protected:
81  // Callback for acceleration (ODE solver uses x" = F/m) applied to
82  // particle i. The positions and velocities are not necessarily
83  // mPosition and mVelocity, because the ODE solver evaluates the
84  // impulse function at intermediate positions.
85  virtual Vector<N, Real> Acceleration(int i, Real time,
86  std::vector<Vector<N, Real>> const& position,
87  std::vector<Vector<N, Real>> const& velocity);
88 
89  inline int GetIndex(int s, int r, int c) const;
90  void GetCoordinates(int i, int& s, int& r, int& c) const;
91 
93  std::vector<Real> mConstantS, mLengthS;
94  std::vector<Real> mConstantR, mLengthR;
95  std::vector<Real> mConstantC, mLengthC;
96 };
97 
98 
99 template <int N, typename Real>
101 {
102 }
103 
104 template <int N, typename Real>
106  int numCols, Real step)
107  :
108  ParticleSystem<N, Real>(numSlices * numRows * numCols, step),
109  mNumSlices(numSlices),
110  mNumRows(numRows),
111  mNumCols(numCols),
112  mConstantS(numSlices * numRows * numCols),
113  mLengthS(numSlices * numRows * numCols),
114  mConstantR(numSlices * numRows * numCols),
115  mLengthR(numSlices * numRows * numCols),
116  mConstantC(numSlices * numRows * numCols),
117  mLengthC(numSlices * numRows * numCols)
118 {
119  std::fill(mConstantS.begin(), mConstantS.end(), (Real)0);
120  std::fill(mLengthS.begin(), mLengthS.end(), (Real)0);
121  std::fill(mConstantR.begin(), mConstantR.end(), (Real)0);
122  std::fill(mLengthR.begin(), mLengthR.end(), (Real)0);
123  std::fill(mConstantC.begin(), mConstantC.end(), (Real)0);
124  std::fill(mLengthC.begin(), mLengthC.end(), (Real)0);
125 }
126 
127 template <int N, typename Real> inline
129 {
130  return mNumSlices;
131 }
132 
133 template <int N, typename Real> inline
135 {
136  return mNumRows;
137 }
138 
139 template <int N, typename Real> inline
141 {
142  return mNumCols;
143 }
144 
145 template <int N, typename Real> inline
146 void MassSpringVolume<N, Real>::SetMass(int s, int r, int c, Real mass)
147 {
149 }
150 
151 template <int N, typename Real> inline
153 Vector<N, Real> const& position)
154 {
156 }
157 
158 template <int N, typename Real> inline
160 Vector<N, Real> const& velocity)
161 {
163 }
164 
165 template <int N, typename Real> inline
166 Real const& MassSpringVolume<N, Real>::GetMass(int s, int r, int c) const
167 {
169 }
170 
171 template <int N, typename Real> inline
173 int c) const
174 {
176 }
177 
178 template <int N, typename Real> inline
180 int c) const
181 {
183 }
184 
185 template <int N, typename Real> inline
187 Real constant)
188 {
189  mConstantS[GetIndex(s, r, c)] = constant;
190 }
191 
192 template <int N, typename Real> inline
194 {
195  mLengthS[GetIndex(s, r, c)] = length;
196 }
197 
198 template <int N, typename Real> inline
200 Real constant)
201 {
202  mConstantR[GetIndex(s, r, c)] = constant;
203 }
204 
205 template <int N, typename Real> inline
207 {
208  mLengthR[GetIndex(s, r, c)] = length;
209 }
210 
211 template <int N, typename Real> inline
213 Real constant)
214 {
215  mConstantC[GetIndex(s, r, c)] = constant;
216 }
217 
218 template <int N, typename Real> inline
220 {
221  mLengthC[GetIndex(s, r, c)] = length;
222 }
223 
224 template <int N, typename Real> inline
225 Real const& MassSpringVolume<N, Real>::GetConstantS(int s, int r, int c) const
226 {
227  return mConstantS[GetIndex(s, r, c)];
228 }
229 
230 template <int N, typename Real> inline
231 Real const& MassSpringVolume<N, Real>::GetLengthS(int s, int r, int c) const
232 {
233  return mLengthS[GetIndex(s, r, c)];
234 }
235 
236 template <int N, typename Real> inline
237 Real const& MassSpringVolume<N, Real>::GetConstantR(int s, int r, int c) const
238 {
239  return mConstantR[GetIndex(s, r, c)];
240 }
241 
242 template <int N, typename Real> inline
243 Real const& MassSpringVolume<N, Real>::GetLengthR(int s, int r, int c) const
244 {
245  return mLengthR[GetIndex(s, r, c)];
246 }
247 
248 template <int N, typename Real> inline
249 Real const& MassSpringVolume<N, Real>::GetConstantC(int s, int r, int c) const
250 {
251  return mConstantC[GetIndex(s, r, c)];
252 }
253 
254 template <int N, typename Real> inline
255 Real const& MassSpringVolume<N, Real>::GetLengthC(int s, int r, int c) const
256 {
257  return mLengthC[GetIndex(s, r, c)];
258 }
259 
260 template <int N, typename Real>
262  std::vector<Vector<N, Real>> const&, std::vector<Vector<N, Real>> const&)
263 {
264  return Vector<N, Real>::Zero();
265 }
266 
267 template <int N, typename Real>
269  std::vector<Vector<N, Real>> const& position,
270  std::vector<Vector<N, Real>> const& velocity)
271 {
272  // Compute spring forces on position X[i]. The positions are not
273  // necessarily mPosition, because the RK4 solver in ParticleSystem
274  // evaluates the acceleration function at intermediate positions. The
275  // face, edge, and corner points of the volume of masses must be handled
276  // separately, because each has fewer than eight springs attached to it.
277 
278  Vector<N, Real> acceleration = ExternalAcceleration(i, time, position,
279  velocity);
280 
281  Vector<N, Real> diff, force;
282  Real ratio;
283 
284  int s, r, c, prev, next;
285  GetCoordinates(i, s, r, c);
286 
287  if (s > 0)
288  {
289  prev = i - mNumRows * mNumCols; // index to previous s-neighbor
290  diff = position[prev] - position[i];
291  ratio = GetLengthS(s - 1, r, c) / Length(diff);
292  force = GetConstantS(s - 1, r, c) * ((Real)1 - ratio) * diff;
293  acceleration += this->mInvMass[i] * force;
294  }
295 
296  if (s < mNumSlices - 1)
297  {
298  next = i + mNumRows * mNumCols; // index to next s-neighbor
299  diff = position[next] - position[i];
300  ratio = GetLengthS(s, r, c) / Length(diff);
301  force = GetConstantS(s, r, c) * ((Real)1 - ratio) * diff;
302  acceleration += this->mInvMass[i] * force;
303  }
304 
305  if (r > 0)
306  {
307  prev = i - mNumCols; // index to previous r-neighbor
308  diff = position[prev] - position[i];
309  ratio = GetLengthR(s, r - 1, c) / Length(diff);
310  force = GetConstantR(s, r - 1, c) * ((Real)1 - ratio) * diff;
311  acceleration += this->mInvMass[i] * force;
312  }
313 
314  if (r < mNumRows - 1)
315  {
316  next = i + mNumCols; // index to next r-neighbor
317  diff = position[next] - position[i];
318  ratio = GetLengthR(s, r, c) / Length(diff);
319  force = GetConstantR(s, r, c) * ((Real)1 - ratio) * diff;
320  acceleration += this->mInvMass[i] * force;
321  }
322 
323  if (c > 0)
324  {
325  prev = i - 1; // index to previous c-neighbor
326  diff = position[prev] - position[i];
327  ratio = GetLengthC(s, r, c - 1) / Length(diff);
328  force = GetConstantC(s, r, c - 1) * ((Real)1 - ratio) * diff;
329  acceleration += this->mInvMass[i] * force;
330  }
331 
332  if (c < mNumCols - 1)
333  {
334  next = i + 1; // index to next c-neighbor
335  diff = position[next] - position[i];
336  ratio = GetLengthC(s, r, c) / Length(diff);
337  force = GetConstantC(s, r, c) * ((Real)1 - ratio) * diff;
338  acceleration += this->mInvMass[i] * force;
339  }
340 
341  return acceleration;
342 }
343 
344 template <int N, typename Real> inline
345 int MassSpringVolume<N, Real>::GetIndex(int s, int r, int c) const
346 {
347  return c + mNumCols * (r + mNumRows * s);
348 }
349 
350 template <int N, typename Real>
351 void MassSpringVolume<N, Real>::GetCoordinates(int i, int& s, int& r, int& c)
352 const
353 {
354  c = i % mNumCols;
355  i = (i - c) / mNumCols;
356  r = i % mNumRows;
357  s = i / mNumRows;
358 }
359 
360 
361 }
Real const & GetConstantR(int s, int r, int c) const
Real const & GetConstantS(int s, int r, int c) const
Vector< N, Real > const & GetPosition(int s, int r, int c) const
std::vector< Real > mLengthC
void SetVelocity(int s, int r, int c, Vector< N, Real > const &velocity)
std::vector< Real > mConstantS
Real const & GetMass(int i) const
virtual Vector< N, Real > ExternalAcceleration(int i, Real time, std::vector< Vector< N, Real >> const &position, std::vector< Vector< N, Real >> const &velocity)
virtual Vector< N, Real > Acceleration(int i, Real time, std::vector< Vector< N, Real >> const &position, std::vector< Vector< N, Real >> const &velocity)
Real const & GetMass(int s, int r, int c) const
Real const & GetLengthR(int s, int r, int c) const
void SetConstantC(int s, int r, int c, Real constant)
const GLubyte * c
Definition: glext.h:11671
void SetLengthR(int s, int r, int c, Real length)
Vector< N, Real > const & GetVelocity(int s, int r, int c) const
void SetMass(int i, Real mass)
void SetLengthS(int s, int r, int c, Real length)
void SetLengthC(int s, int r, int c, Real length)
Real const & GetLengthS(int s, int r, int c) const
void GetCoordinates(int i, int &s, int &r, int &c) const
static Vector Zero()
Definition: GteVector.h:295
void SetConstantS(int s, int r, int c, Real constant)
void SetVelocity(int i, Vector< N, Real > const &velocity)
std::vector< Real > mConstantC
void SetPosition(int s, int r, int c, Vector< N, Real > const &position)
Real const & GetConstantC(int s, int r, int c) const
std::vector< Real > mLengthS
MassSpringVolume(int numSlices, int numRows, int numCols, Real step)
int GetIndex(int s, int r, int c) const
std::vector< Real > mConstantR
Vector< N, Real > const & GetVelocity(int i) const
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:790
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
void SetPosition(int i, Vector< N, Real > const &position)
GLboolean r
Definition: glcorearb.h:1217
GLdouble s
Definition: glext.h:231
std::vector< Real > mLengthR
std::vector< Real > mInvMass
Real const & GetLengthC(int s, int r, int c) const
void SetMass(int s, int r, int c, Real mass)
Vector< N, Real > const & GetPosition(int i) const
void SetConstantR(int s, int r, int c, Real constant)


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