00001 
00002
00003
00004
00005
00006 namespace NewGamePhysics.PhysicalElements
00007 {
00008 using System;
00009
00010 using Microsoft.Xna.Framework;
00011 using Microsoft.Xna.Framework.Graphics;
00012
00013 using NewGamePhysics.Mathematics;
00014 using NewGamePhysics.Physics;
00015
00021 public enum DoublePendulumHinges
00022 {
00026 Hinge1 = 0,
00027
00031 Hinge2 = 1,
00032 }
00033
00038 public enum DoublePendulumStateValues
00039 {
00043 Angle1 = 0,
00044
00048 Angle2 = 1,
00049
00053 Velocity1 = 2,
00054
00058 Velocity2 = 3,
00059
00063 Acceleration1 = 4,
00064
00068 Acceleration2 = 5,
00069 }
00070
00074 public abstract class DoublePendulumSimulationBase
00075 {
00079 private ISecondDerivative pendulumAcceleration;
00080
00084 internal NystromIntegrator pendulumIntegrator;
00085
00089 private double t;
00090
00094 private double h;
00095
00099 private RotationalFrictionModel frictionModel;
00100
00104 internal Vector2 origin;
00105
00109 internal VectorN theta;
00110
00114 internal VectorN omega;
00115
00119 internal VectorN acceleration;
00120
00124 internal static double sqrt2 = Math.Sqrt(2.0);
00125
00126 #region public_properties
00127
00131 public double H
00132 {
00133 get { return h; }
00134 set { h = value; }
00135 }
00136
00140 public double T
00141 {
00142 get { return t; }
00143 set { t = value; }
00144 }
00145
00146 #endregion
00147
00148 #region internal_properties
00149
00153 internal RotationalFrictionModel FrictionModel
00154 {
00155 get { return this.frictionModel; }
00156 set { this.frictionModel = value; }
00157 }
00158
00162 internal ISecondDerivative PendulumAcceleration
00163 {
00164 get { return this.pendulumAcceleration; }
00165 set { this.pendulumAcceleration = value; }
00166 }
00167
00168 #endregion
00169
00170 #region abstract_methods
00171
00176 public abstract void SetInitialConditionsAtRest();
00177
00182 public abstract Vector2[] GetPosition();
00183
00190 public abstract Vector2[] GetPosition(Vector2 origin, double scale);
00191
00196 public abstract double[] GetSize();
00197
00203 public abstract double[] GetSize(double scale);
00204
00209 public abstract double GetEnergy();
00210
00211 #endregion
00212
00213 #region common_public_methods
00214
00234 public void SetInitialConditions(double theta1, double omega1, double theta2, double omega2)
00235 {
00236
00237 this.theta[0] = theta1;
00238 this.theta[1] = theta2;
00239 this.omega[0] = omega1;
00240 this.omega[1] = omega2;
00241
00242
00243 this.pendulumIntegrator = new NystromIntegrator(
00244 (ISecondDerivative)this.pendulumAcceleration,
00245 this.H,
00246 this.theta,
00247 this.omega);
00248 }
00249
00256 public double Drive(DoublePendulumHinges which, double force)
00257 {
00258
00259 double deltaOmega = force * this.H;
00260 this.omega[(int)which] += deltaOmega;
00261 return deltaOmega;
00262 }
00263
00267 public void Animate()
00268 {
00269
00270
00271 this.pendulumIntegrator.Step(
00272 out this.t,
00273 out this.theta,
00274 out this.omega,
00275 out this.acceleration);
00276
00278 for (int i = 0; i < 2; i++)
00279 {
00280 this.omega[i] = this.FrictionModel.ApplyFriction(this.omega[i]);
00281 }
00282 }
00283
00288 public double[] GetAngle()
00289 {
00290 double[] angles = new double[2];
00291 angles[0] = this.theta[0];
00292 angles[1] = this.theta[1];
00293 return angles;
00294 }
00295
00301 public double GetAngle(DoublePendulumHinges which)
00302 {
00303 return this.theta[(int)which];
00304 }
00305
00310 public double[] GetVelocity()
00311 {
00312 double[] omega = new double[2];
00313 omega[0] = this.omega[0];
00314 omega[1] = this.omega[1];
00315 return omega;
00316 }
00317
00323 public double GetVelocity(DoublePendulumHinges which)
00324 {
00325 return this.omega[(int)which];
00326
00327 }
00328
00333 public double[] GetAcceleration()
00334 {
00335 double[] omega = new double[2];
00336 omega[0] = this.acceleration[0];
00337 omega[1] = this.acceleration[1];
00338 return omega;
00339 }
00340
00346 public double GetAcceleration(DoublePendulumHinges which)
00347 {
00348 return this.acceleration[(int)which];
00349 }
00350
00356 public double[] GetState()
00357 {
00358 double[] values = new double[6];
00359 values[(int)DoublePendulumStateValues.Angle1] =
00360 this.theta[(int)DoublePendulumHinges.Hinge1];
00361 values[(int)DoublePendulumStateValues.Angle2] =
00362 this.theta[(int)DoublePendulumHinges.Hinge2];
00363 values[(int)DoublePendulumStateValues.Velocity1]
00364 = this.omega[(int)DoublePendulumHinges.Hinge1];
00365 values[(int)DoublePendulumStateValues.Velocity2]
00366 = this.omega[(int)DoublePendulumHinges.Hinge2];
00367 values[(int)DoublePendulumStateValues.Acceleration1]
00368 = this.theta[(int)DoublePendulumHinges.Hinge1];
00369 values[(int)DoublePendulumStateValues.Acceleration2]
00370 = this.theta[(int)DoublePendulumHinges.Hinge2];
00371 return values;
00372 }
00373
00380 public double GetState(DoublePendulumStateValues which)
00381 {
00382 return this.GetState()[(int)which];
00383 }
00384
00385 #endregion
00386 }
00387 }