GteMassSpringArbitrary.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 #include <cstring>
12 #include <set>
13 
14 namespace gte
15 {
16 
17 template <int N, typename Real>
18 class MassSpringArbitrary : public ParticleSystem<N, Real>
19 {
20 public:
21  // Construction and destruction. This class represents a set of M
22  // masses that are connected by S springs with arbitrary topology. The
23  // function SetSpring(...) should be called for each spring that you
24  // want in the system.
25  virtual ~MassSpringArbitrary();
26  MassSpringArbitrary(int numParticles, int numSprings, Real step);
27 
28  struct Spring
29  {
32  };
33 
34  // Member access.
35  inline int GetNumSprings() const;
36  void SetSpring(int index, Spring const& spring);
37  inline Spring const& GetSpring(int index) const;
38 
39  // The default external force is zero. Derive a class from this one to
40  // provide nonzero external forces such as gravity, wind, friction,
41  // and so on. This function is called by Acceleration(...) to compute
42  // the impulse F/m generated by the external force F.
43  virtual Vector<N, Real> ExternalAcceleration(int i, Real time,
44  std::vector<Vector<N, Real>> const& position,
45  std::vector<Vector<N, Real>> const& velocity);
46 
47 protected:
48  // Callback for acceleration (ODE solver uses x" = F/m) applied to
49  // particle i. The positions and velocities are not necessarily
50  // mPosition and mVelocity, because the ODE solver evaluates the
51  // impulse function at intermediate positions.
52  virtual Vector<N, Real> Acceleration(int i, Real time,
53  std::vector<Vector<N, Real>> const& position,
54  std::vector<Vector<N, Real>> const& velocity);
55 
56  std::vector<Spring> mSpring;
57 
58  // Each particle has an associated array of spring indices for those
59  // springs adjacent to the particle. The set elements are spring
60  // indices, not indices of adjacent particles.
61  std::vector<std::set<int>> mAdjacent;
62 };
63 
64 
65 template <int N, typename Real>
67 {
68 }
69 
70 template <int N, typename Real>
72  int numSprings, Real step)
73  :
74  ParticleSystem<N, Real>(numParticles, step),
75  mSpring(numSprings),
76  mAdjacent(numParticles)
77 {
78  memset(&mSpring[0], 0, numSprings * sizeof(Spring));
79 }
80 
81 template <int N, typename Real> inline
83 {
84  return static_cast<int>(mSpring.size());
85 }
86 
87 template <int N, typename Real>
89 {
90  mSpring[index] = spring;
91  mAdjacent[spring.particle0].insert(index);
92  mAdjacent[spring.particle1].insert(index);
93 }
94 
95 template <int N, typename Real> inline
98 {
99  return mSpring[index];
100 }
101 
102 template <int N, typename Real>
104  std::vector<Vector<N, Real>> const&, std::vector<Vector<N, Real>> const&)
105 {
106  return Vector<N, Real>::Zero();
107 }
108 
109 template <int N, typename Real>
111  std::vector<Vector<N, Real>> const& position,
112  std::vector<Vector<N, Real>> const& velocity)
113 {
114  // Compute spring forces on position X[i]. The positions are not
115  // necessarily mkPosition, because the RK4 solver in ParticleSystem
116  // evaluates the acceleration function at intermediate positions.
117 
118  Vector<N, Real> acceleration = ExternalAcceleration(i, time, position,
119  velocity);
120 
121  for (auto adj : mAdjacent[i])
122  {
123  // Process a spring connected to particle i.
124  Spring const& spring = mSpring[adj];
125  Vector<N, Real> diff;
126  if (i != spring.particle0)
127  {
128  diff = position[spring.particle0] - position[i];
129  }
130  else
131  {
132  diff = position[spring.particle1] - position[i];
133  }
134 
135  Real ratio = spring.length / Length(diff);
136  Vector<N, Real> force = spring.constant * ((Real)1 - ratio) * diff;
137  acceleration += this->mInvMass[i] * force;
138  }
139 
140  return acceleration;
141 }
142 
143 
144 }
void SetSpring(int index, Spring const &spring)
Spring const & GetSpring(int index) const
virtual Vector< N, Real > Acceleration(int i, Real time, std::vector< Vector< N, Real >> const &position, std::vector< Vector< N, Real >> const &velocity)
std::vector< Spring > mSpring
static Vector Zero()
Definition: GteVector.h:295
MassSpringArbitrary(int numParticles, int numSprings, Real step)
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
GLuint index
Definition: glcorearb.h:781
std::vector< Real > mInvMass
std::vector< std::set< int > > mAdjacent
virtual Vector< N, Real > ExternalAcceleration(int i, Real time, std::vector< Vector< N, Real >> const &position, std::vector< Vector< N, Real >> const &velocity)


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