synfig-core  1.0.3
valuenode_dynamic.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
21 /* ========================================================================= */
22 
23 /* === S T A R T =========================================================== */
24 
25 #ifndef __SYNFIG_VALUENODE_DYNAMIC_H
26 #define __SYNFIG_VALUENODE_DYNAMIC_H
27 
28 /* === H E A D E R S ======================================================= */
29 
30 #include <synfig/valuenode.h>
31 #include "valuenode_derivative.h"
32 #include "valuenode_const.h"
33 
34 /* === M A C R O S ========================================================= */
35 #define MASS_INERTIA_MINIMUM 0.0000001
36 /* === C L A S S E S & S T R U C T S ======================================= */
37 
38 namespace synfig {
39 
40 class Oscillator;
41 
43 {
44  friend class Oscillator;
45 private:
46 
47  ValueNode::RHandle tip_static_; // Equilibrium position without external forces
48  ValueNode::RHandle origin_; // Basement of the dynamic system
49  ValueNode::RHandle force_; // External force applied on the mass center of gravity
50  ValueNode::RHandle torque_; // Momentum applied at the origin
51  ValueNode::RHandle damping_coef_; // Radial Damping coeficient
52  ValueNode::RHandle friction_coef_; // Rotational friction coeficient
53  ValueNode::RHandle spring_coef_; // Spring coeficient
54  ValueNode::RHandle torsion_coef_; // Torsion coeficient
55  ValueNode::RHandle mass_; // Mass
56  ValueNode::RHandle inertia_; // Moment of Inertia
57  ValueNode::RHandle spring_rigid_; // True if spring is solid rigid
58  ValueNode::RHandle torsion_rigid_; // True if torsion is solid rigid
59  ValueNode::RHandle origin_drags_tip_; // If true result=origin+state otherwise result=state
60 
61 
62  ValueNode_Derivative::RHandle origin_d_; // Derivative of the origin along the time
63  mutable Time last_time;
64  ValueNode_Dynamic(const ValueBase &value);
65  /*
66  State types (4) for:
67  q=radius
68  p=d/dt(radius)
69  b=angle
70  g=d/dt(angle)
71 
72  where
73 
74  p=dxdt[0]
75  p'=dxdt[1]
76  g=dxdt[2]
77  g'=dxdt[3]
78  q=x[0]
79  q'=x[1]
80  b=x[2]
81  b'=x[3]
82  */
83  mutable std::vector<double> state;
84  void reset_state(Time t)const;
85 public:
86 
87  typedef etl::handle<ValueNode_Dynamic> Handle;
88  typedef etl::handle<const ValueNode_Dynamic> ConstHandle;
89 
90  virtual ValueBase operator()(Time t)const;
91 
92  virtual ~ValueNode_Dynamic();
93 
94  virtual String get_name()const;
95  virtual String get_local_name()const;
96 
97  virtual ValueNode::LooseHandle get_link_vfunc(int i)const;
98 
99 protected:
101  virtual bool set_link_vfunc(int i,ValueNode::Handle x);
102 
103 public:
105 
107  static bool check_type(Type &type);
108  static ValueNode_Dynamic* create(const ValueBase &x);
109  virtual Vocab get_children_vocab_vfunc()const;
110 }; // END of class ValueNode_Dynamic
111 
112 
114 {
115  etl::handle<const ValueNode_Dynamic> d;
116 public:
117  Oscillator(const ValueNode_Dynamic* x) : d(x) { }
118  void operator() ( const std::vector<double> &x , std::vector<double> &dxdt , const double t )
119  {
120  Vector u(cos(x[2]), sin(x[2]));
121  Vector v(-u[1], u[0]);
122  Vector sd=(*(d->origin_d_))(t).get(Vector());
123  Vector f=(*(d->force_))(t).get(Vector());
124  double to=(*(d->torque_))(t).get(double());
125  double c=(*(d->damping_coef_))(t).get(double());
126  double mu=(*(d->friction_coef_))(t).get(double());
127  double k=(*(d->spring_coef_))(t).get(double());
128  double tau=(*(d->torsion_coef_))(t).get(double());
129  double m=(*(d->mass_))(t).get(double());
130  double i=(*(d->inertia_))(t).get(double());
131  Vector tip=(*(d->tip_static_))(t).get(Vector());
132 
133  double fr=f*u;
134  double fa=f*v;
135  // Those are the second derivatives (speed of origin)
136  double srd=sd*u;
137  double sad=sd*v;
138  // Calculate the steady position in terms of state
139  double r0=tip.mag();
140  double a0=(double)(Angle::rad(tip.angle()).get());
141  double r=x[0]-r0; // effective radius
142  double a=x[2]-a0; // effective alpha
143  double rd=x[1]; // radius speed
144  double ad=x[3]; // alpha speed
145  double imr2=i+m*x[0]*x[0]; // effective inertia
146  // Check if the spring rigid
147  bool spring_is_rigid=(*(d->spring_rigid_))(t).get(bool());
148  // Check if the torsion rigid
149  bool torsion_is_rigid=(*(d->torsion_rigid_))(t).get(bool());
150  // Integration operations
151  dxdt[0]=x[1];
152  // Disable movement if the spring is rigid
153  // or if the mass is near to zero but animated.
154  if(spring_is_rigid || fabs(m)<=MASS_INERTIA_MINIMUM)
155  dxdt[1]=0.0;
156  else
157  dxdt[1]=(fr-c*rd-k*r)/m-srd;
158  dxdt[2]=x[3];
159  // Disable rotation if the torsion is rigid
160  // or if the inertia is near to zero but animated.
161  if(torsion_is_rigid || fabs(imr2)<=MASS_INERTIA_MINIMUM)
162  dxdt[3]=0.0;
163  else
164  dxdt[3]=(to+fa*x[0]-mu*ad-tau*a)/imr2-sad;
165  }
166 
167 };
168 }; // END of namespace synfig
169 
170 /* === E N D =============================================================== */
171 
172 #endif