00001 00003 // 00004 // -= ODE solver using a Modified Euler's Method =- 00005 // 00006 // Definition: "a 1st order ordinary differential equation solver" 00007 // 00009 // 00010 // $RCSfile: ModifiedEulerODEsolver.h,v $ 00011 // $Date: 2002/01/10 03:10:47 $ 00012 // $Revision: 1.4 $ 00013 // Copyright (C) 1998, 1999, 2000 Kevin Meinert, kevin@vrsource.org 00014 // 00015 // This library is free software; you can redistribute it and/or 00016 // modify it under the terms of the GNU Library General Public 00017 // License as published by the Free Software Foundation; either 00018 // version 2 of the License, or (at your option) any later version. 00019 // 00020 // This library is distributed in the hope that it will be useful, 00021 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00023 // Library General Public License for more details. 00024 // 00025 // You should have received a copy of the GNU Library General Public 00026 // License along with this library; if not, write to the Free 00027 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00028 // 00030 #ifndef MODIFIED_EULER_METHOD 00031 #define MODIFIED_EULER_METHOD 00032 00033 #include "ani/Dynamics/ODEsolver.h" 00034 00035 namespace ani 00036 { 00037 //: simple, fast, unstable at times. 00038 template <class _item> 00039 class ModifiedEulerODEsolver : public ODEsolver<_item> 00040 { 00041 public: 00042 ModifiedEulerODEsolver() {} 00043 virtual ~ModifiedEulerODEsolver() {} 00044 00045 // dx = dx/dt*currentState * changeInTime 00046 // nextState = currentState = currentState + dx 00047 // before executing this function, 00048 // - you must have zeroed all forces, 00049 // - run each operator on the particle system 00050 virtual void exec( _item& currentState, float timeDelta ) 00051 { 00052 // compute next state. 00053 00054 // any particle that is put into f() needs to have its mass and force accums set 00055 // to equal the current _item, since all the operations only act on the phase space 00056 // (pos, vel), this is needed: 00057 _item temp( currentState ); 00058 00059 // k1 = h * func( x0, t0 ); 00060 // f = func(..., ...) 00061 f.computeDerivative( currentState, 0.0f * timeDelta ); 00062 // k1 = h * f 00063 k1.multiplyPhase( f, timeDelta ); 00064 00065 //: k2 = h * func( x0 + 1/2*k1, t0 + 1/2 * h ); 00066 // f = func(..., ...) 00067 temp.multiplyPhase( k1, 0.5f ); 00068 temp.addPhase( temp, currentState ); 00069 f.computeDerivative( temp, 0.5f * timeDelta ); 00070 // k2 = h * f 00071 k2.multiplyPhase( f, timeDelta ); 00072 00073 // xt0h = x0 + k2; 00074 currentState.addPhase( k2 ); 00075 currentState.normalize(); 00076 } 00077 00078 _item k1, k2; 00079 00080 // temporary used to catch the value of the derivitive function (computeDerivative) 00081 _item f; 00082 }; 00083 }; 00084 #endif