00001
00002
00003
00004
00005
00006 namespace NewGamePhysics.PhysicalElements
00007 {
00008 using System;
00009 using System.Collections.Generic;
00010 using System.Text;
00011
00012 using Microsoft.Xna.Framework;
00013 using Microsoft.Xna.Framework.Graphics;
00014
00015 using NewGamePhysics.Utilities;
00016 using NewGamePhysics.GraphicalElements;
00017 using NewGamePhysics.Mathematics;
00018 using NewGamePhysics.Physics;
00019
00023 public class DoubleRegularPendulumSimulation : DoublePendulumSimulationBase
00024 {
00035 public DoubleRegularPendulumSimulation(
00036 Vector2 origin,
00037 double l1,
00038 double m1,
00039 double l2,
00040 double m2,
00041 double g,
00042 RotationalFrictionType f)
00043 {
00044
00045 this.origin = origin;
00046
00047
00048 this.T = 0.0;
00049 this.H = 0.01;
00050
00051
00052 this.PendulumAcceleration =
00053 (ISecondDerivative)new DoubleRegularPendulumAcceleration(l1, m1, l2, m2, g);
00054
00055
00056 this.theta = new VectorN(2);
00057 this.omega = new VectorN(2);
00058 this.SetInitialConditionsAtRest();
00059
00060
00061 this.FrictionModel = new RotationalFrictionModel(f);
00062 }
00063
00068 public override void SetInitialConditionsAtRest()
00069 {
00070 SetInitialConditions(0.0, 0.0, 0.0, 0.0);
00071 }
00072
00077 public override Vector2[] GetPosition()
00078 {
00079
00080 Vector2[] pendulumPoints = new Vector2[3];
00081 for (int i = 0; i < pendulumPoints.Length; i++)
00082 {
00083 pendulumPoints[i] = new Vector2();
00084 }
00085
00086
00087 double angle = this.theta[0];
00088
00089
00090 pendulumPoints[0].X = this.origin.X;
00091 pendulumPoints[0].Y = this.origin.Y;
00092
00093 double[] pendulumSize = this.GetSize();
00094
00095
00096 pendulumPoints[1].X =
00097 (float)(pendulumPoints[0].X + (pendulumSize[0] * Math.Sin(angle)));
00098 pendulumPoints[1].Y =
00099 (float)(pendulumPoints[0].Y + (pendulumSize[0] * Math.Cos(angle)));
00100
00101
00102 angle = this.theta[1];
00103
00104
00105 pendulumPoints[2].X =
00106 (float)(pendulumPoints[1].X + (pendulumSize[1] * Math.Sin(angle)));
00107 pendulumPoints[2].Y =
00108 (float)(pendulumPoints[1].Y + (pendulumSize[1] * Math.Cos(angle)));
00109
00110 return pendulumPoints;
00111 }
00112
00119 public override Vector2[] GetPosition(Vector2 screenOrigin, double screenScale)
00120 {
00121
00122 Vector2[] pendulumPoints = this.GetPosition();
00123
00124
00125 for (int i=0; i<pendulumPoints.Length; i++)
00126 {
00127 pendulumPoints[i].X = screenOrigin.X + (float)(screenScale * pendulumPoints[i].X);
00128 pendulumPoints[i].Y = screenOrigin.Y + (float)(screenScale * pendulumPoints[i].Y);
00129 }
00130
00131 return pendulumPoints;
00132 }
00133
00139 public override double[] GetSize()
00140 {
00141 DoubleRegularPendulumAcceleration pendulumAcceleration =
00142 this.PendulumAcceleration as DoubleRegularPendulumAcceleration;
00143
00144 double[] pendulumSize = new double[2];
00145 pendulumSize[0] = pendulumAcceleration.L1;
00146 pendulumSize[1] = pendulumAcceleration.L2;
00147
00148 return pendulumSize;
00149 }
00150
00157 public override double[] GetSize(double scale)
00158 {
00159 double[] size = this.GetSize();
00160 for (int i = 0; i < size.Length; i++)
00161 {
00162 size[i] *= scale;
00163 }
00164
00165 return size;
00166 }
00167
00172 public override double GetEnergy()
00173 {
00174 DoubleRegularPendulumAcceleration pendulumAcceleration =
00175 this.PendulumAcceleration as DoubleRegularPendulumAcceleration;
00176
00177 double f1 = (1 - Math.Cos(theta[0]));
00178 double f2 = (1 - Math.Cos(theta[1]));
00179 double v = pendulumAcceleration.M1 * pendulumAcceleration.G * (pendulumAcceleration.L1 * f1) +
00180 pendulumAcceleration.M2 * pendulumAcceleration.G * ((pendulumAcceleration.L1 * f1) + (pendulumAcceleration.L2 * f2));
00181 double k = 0.5 * (pendulumAcceleration.M1 + pendulumAcceleration.M2) * pendulumAcceleration.L1 * pendulumAcceleration.L1 * omega[0] * omega[0] +
00182 0.5 * pendulumAcceleration.M2 * pendulumAcceleration.L2 * pendulumAcceleration.L2 * omega[1] * omega[1] +
00183 pendulumAcceleration.M2 * pendulumAcceleration.L1 * pendulumAcceleration.L2 * Math.Cos(theta[0] - theta[1]) * omega[0] * omega[1];
00184 return (v + k);
00185 }
00186 }
00187 }