GteMassSpringSurface.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 MassSpringSurface : public ParticleSystem<N, Real>
17 {
18 public:
19  // Construction and destruction. This class represents an RxC array of
20  // masses lying on a surface and connected by an array of springs. The
21  // masses are indexed by mass[r][c] for 0 <= r < R and 0 <= c < C. The
22  // mass at interior position X[r][c] is connected by springs to the
23  // masses at positions X[r-1][c], X[r+1][c], X[r][c-1], and X[r][c+1].
24  // Boundary masses have springs connecting them to the obvious neighbors
25  // ("edge" mass has 3 neighbors, "corner" mass has 2 neighbors). The
26  // masses are arranged in row-major order: position[c+C*r] = X[r][c]
27  // for 0 <= r < R and 0 <= c < C. The other arrays are stored similarly.
28  virtual ~MassSpringSurface();
29  MassSpringSurface(int numRows, int numCols, Real step);
30 
31  // Member access.
32  inline int GetNumRows() const;
33  inline int GetNumCols() const;
34  inline void SetMass(int r, int c, Real mass);
35  inline void SetPosition(int r, int c, Vector<N, Real> const& position);
36  inline void SetVelocity(int r, int c, Vector<N, Real> const& velocity);
37  inline Real const& GetMass(int r, int c) const;
38  inline Vector<N, Real> const& GetPosition(int r, int c) const;
39  inline Vector<N, Real> const& GetVelocity(int r, int c) const;
40 
41  // The interior mass at (r,c) has springs to the left, right, bottom, and
42  // top. Edge masses have only three neighbors and corner masses have only
43  // two neighbors. The mass at (r,c) provides access to the springs
44  // connecting to locations (r,c+1) and (r+1,c). Edge and corner masses
45  // provide access to only a subset of these. The caller is responsible
46  // for ensuring the validity of the (r,c) inputs.
47  inline void SetConstantR(int r, int c, Real constant); // to (r+1,c)
48  inline void SetLengthR(int r, int c, Real length); // to (r+1,c)
49  inline void SetConstantC(int r, int c, Real constant); // to (r,c+1)
50  inline void SetLengthC(int r, int c, Real length); // to (r,c+1)
51  inline Real const& GetConstantR(int r, int c) const;
52  inline Real const& GetLengthR(int r, int c) const;
53  inline Real const& GetConstantC(int r, int c) const;
54  inline Real const& GetLengthC(int r, int c) const;
55 
56  // The default external force is zero. Derive a class from this one to
57  // provide nonzero external forces such as gravity, wind, friction,
58  // and so on. This function is called by Acceleration(...) to compute
59  // the impulse F/m generated by the external force F.
60  virtual Vector<N, Real> ExternalAcceleration(int i, Real time,
61  std::vector<Vector<N, Real>> const& position,
62  std::vector<Vector<N, Real>> const& velocity);
63 
64 protected:
65  // Callback for acceleration (ODE solver uses x" = F/m) applied to
66  // particle i. The positions and velocities are not necessarily
67  // mPosition and mVelocity, because the ODE solver evaluates the
68  // impulse function at intermediate positions.
69  virtual Vector<N, Real> Acceleration(int i, Real time,
70  std::vector<Vector<N, Real>> const& position,
71  std::vector<Vector<N, Real>> const& velocity);
72 
73  inline int GetIndex(int r, int c) const;
74  void GetCoordinates(int i, int& r, int& c) const;
75 
77  std::vector<Real> mConstantR, mLengthR;
78  std::vector<Real> mConstantC, mLengthC;
79 };
80 
81 
82 template <int N, typename Real>
84 {
85 }
86 
87 template <int N, typename Real>
89  Real step)
90  :
91  ParticleSystem<N, Real>(numRows * numCols, step),
92  mNumRows(numRows),
93  mNumCols(numCols),
94  mConstantR(numRows * numCols),
95  mLengthR(numRows * numCols),
96  mConstantC(numRows * numCols),
97  mLengthC(numRows * numCols)
98 {
99  std::fill(mConstantR.begin(), mConstantR.end(), (Real)0);
100  std::fill(mLengthR.begin(), mLengthR.end(), (Real)0);
101  std::fill(mConstantC.begin(), mConstantC.end(), (Real)0);
102  std::fill(mLengthC.begin(), mLengthC.end(), (Real)0);
103 }
104 
105 template <int N, typename Real> inline
107 {
108  return mNumRows;
109 }
110 
111 template <int N, typename Real> inline
113 {
114  return mNumCols;
115 }
116 
117 template <int N, typename Real> inline
118 void MassSpringSurface<N, Real>::SetMass(int r, int c, Real mass)
119 {
121 }
122 
123 template <int N, typename Real> inline
125 Vector<N, Real> const& position)
126 {
128 }
129 
130 template <int N, typename Real> inline
132 Vector<N, Real> const& position)
133 {
135 }
136 
137 template <int N, typename Real> inline
138 Real const& MassSpringSurface<N, Real>::GetMass(int r, int c) const
139 {
141 }
142 
143 template <int N, typename Real> inline
145 const
146 {
148 }
149 
150 template <int N, typename Real> inline
152 const
153 {
155 }
156 
157 template <int N, typename Real> inline
158 void MassSpringSurface<N, Real>::SetConstantR(int r, int c, Real constant)
159 {
160  mConstantR[GetIndex(r, c)] = constant;
161 }
162 
163 template <int N, typename Real> inline
165 {
166  mLengthR[GetIndex(r, c)] = length;
167 }
168 
169 template <int N, typename Real> inline
170 void MassSpringSurface<N, Real>::SetConstantC(int r, int c, Real constant)
171 {
172  mConstantC[GetIndex(r, c)] = constant;
173 }
174 
175 template <int N, typename Real> inline
177 {
178  mLengthC[GetIndex(r, c)] = length;
179 }
180 
181 template <int N, typename Real> inline
182 Real const& MassSpringSurface<N, Real>::GetConstantR(int r, int c) const
183 {
184  return mConstantR[GetIndex(r, c)];
185 }
186 
187 template <int N, typename Real> inline
188 Real const& MassSpringSurface<N, Real>::GetLengthR(int r, int c) const
189 {
190  return mLengthR[GetIndex(r, c)];
191 }
192 
193 template <int N, typename Real> inline
194 Real const& MassSpringSurface<N, Real>::GetConstantC(int r, int c) const
195 {
196  return mConstantC[GetIndex(r, c)];
197 }
198 
199 template <int N, typename Real> inline
200 Real const& MassSpringSurface<N, Real>::GetLengthC(int r, int c) const
201 {
202  return mLengthC[GetIndex(r, c)];
203 }
204 
205 template <int N, typename Real>
207  std::vector<Vector<N, Real>> const&, std::vector<Vector<N, Real>> const&)
208 {
209  return Vector<N, Real>::Zero();
210 }
211 
212 template <int N, typename Real>
214  std::vector<Vector<N, Real>> const& position,
215  std::vector<Vector<N, Real>> const& velocity)
216 {
217  // Compute spring forces on position X[i]. The positions are not
218  // necessarily mPosition, because the RK4 solver in ParticleSystem
219  // evaluates the acceleration function at intermediate positions. The
220  // edge and corner points of the surface of masses must be handled
221  // separately, because each has fewer than four springs attached to it.
222 
223  Vector<N, Real> acceleration = ExternalAcceleration(i, time, position,
224  velocity);
225 
226  Vector<N, Real> diff, force;
227  Real ratio;
228 
229  int r, c, prev, next;
230  GetCoordinates(i, r, c);
231 
232  if (r > 0)
233  {
234  prev = i - mNumCols; // index to previous row-neighbor
235  diff = position[prev] - position[i];
236  ratio = GetLengthR(r - 1, c) / Length(diff);
237  force = GetConstantR(r - 1, c) * ((Real)1 - ratio) * diff;
238  acceleration += this->mInvMass[i] * force;
239  }
240 
241  if (r < mNumRows - 1)
242  {
243  next = i + mNumCols; // index to next row-neighbor
244  diff = position[next] - position[i];
245  ratio = GetLengthR(r, c) / Length(diff);
246  force = GetConstantR(r, c) * ((Real)1 - ratio) * diff;
247  acceleration += this->mInvMass[i] * force;
248  }
249 
250  if (c > 0)
251  {
252  prev = i - 1; // index to previous col-neighbor
253  diff = position[prev] - position[i];
254  ratio = GetLengthC(r, c - 1) / Length(diff);
255  force = GetConstantC(r, c - 1) * ((Real)1 - ratio) * diff;
256  acceleration += this->mInvMass[i] * force;
257  }
258 
259  if (c < mNumCols - 1)
260  {
261  next = i + 1; // index to next col-neighbor
262  diff = position[next] - position[i];
263  ratio = GetLengthC(r, c) / Length(diff);
264  force = GetConstantC(r, c) * ((Real)1 - ratio) * diff;
265  acceleration += this->mInvMass[i] * force;
266  }
267 
268  return acceleration;
269 }
270 
271 template <int N, typename Real> inline
273 {
274  return c + mNumCols * r;
275 }
276 
277 template <int N, typename Real> inline
278 void MassSpringSurface<N, Real>::GetCoordinates(int i, int& r, int& c) const
279 {
280  c = i % mNumCols;
281  r = i / mNumCols;
282 }
283 
284 
285 }
void SetLengthR(int r, int c, Real length)
void SetLengthC(int r, int c, Real length)
void SetMass(int r, int c, Real mass)
std::vector< Real > mConstantR
Vector< N, Real > const & GetPosition(int r, int c) const
Real const & GetMass(int i) const
void SetConstantR(int r, int c, Real constant)
Real const & GetLengthC(int r, int c) const
std::vector< Real > mLengthC
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 & GetLengthR(int r, int c) const
MassSpringSurface(int numRows, int numCols, Real step)
Real const & GetConstantC(int r, int c) const
const GLubyte * c
Definition: glext.h:11671
Real const & GetConstantR(int r, int c) const
void GetCoordinates(int i, int &r, int &c) const
void SetMass(int i, Real mass)
static Vector Zero()
Definition: GteVector.h:295
std::vector< Real > mLengthR
void SetVelocity(int i, Vector< N, Real > const &velocity)
std::vector< Real > mConstantC
void SetConstantC(int r, int c, Real constant)
Real const & GetMass(int r, int c) const
int GetIndex(int r, int c) const
Vector< N, Real > const & GetVelocity(int i) const
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:790
Vector< N, Real > const & GetVelocity(int r, int c) const
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
virtual Vector< N, Real > ExternalAcceleration(int i, Real time, std::vector< Vector< N, Real >> const &position, std::vector< Vector< N, Real >> const &velocity)
void SetPosition(int i, Vector< N, Real > const &position)
GLboolean r
Definition: glcorearb.h:1217
void SetVelocity(int r, int c, Vector< N, Real > const &velocity)
std::vector< Real > mInvMass
void SetPosition(int r, int c, Vector< N, Real > const &position)
Vector< N, Real > const & GetPosition(int i) const


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