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
00014 using NewGamePhysics.Mathematics;
00015 using NewGamePhysics.Physics;
00016
00020 public class CircularObjectSimulation
00021 {
00025 private CircularObjectAcceleration circularObjectAcceleration;
00026
00030 private NystromIntegrator circularObjectIntegrator;
00031
00035 private Vector2 circularObjectPosition;
00036
00040 private double t;
00041
00045 private double h;
00046
00050 private VectorN p;
00051
00055 private VectorN v;
00056
00060 private VectorN acceleration;
00061
00065 private double mass;
00066
00071 private bool integratorNeedsReset;
00072
00080 public CircularObjectSimulation(double objectDiameter, double objectDensity, double gravity, double atmosphereDensity)
00081 {
00082
00083 t = 0;
00084 h = 0.01;
00085
00086
00087 double dragSphere = DragCoefficient.Sphere;
00088
00089
00090 this.mass = objectDensity * Volume.Sphere(objectDiameter / 2.0);
00091
00092
00093 this.circularObjectAcceleration =
00094 new CircularObjectAcceleration(objectDiameter, objectDensity, dragSphere, -gravity, atmosphereDensity);
00095
00096
00097 this.p = new VectorN(2);
00098 this.v = new VectorN(2);
00099
00100
00101 this.circularObjectIntegrator = new NystromIntegrator(
00102 (ISecondDerivative)this.circularObjectAcceleration,
00103 this.h,
00104 this.p,
00105 this.v);
00106 this.integratorNeedsReset = false;
00107
00108
00109 circularObjectPosition = new Vector2();
00110 }
00111
00116 public void InitialConditionsAtRest()
00117 {
00118 SetInitialConditions(0.0, 0.0, 0.0, 0.0);
00119 }
00120
00129 public void SetInitialConditions(double x, double y, double vx, double vy)
00130 {
00131
00132 this.p[0] = x;
00133 this.p[1] = y;
00134 this.v[0] = vx;
00135 this.v[1] = vy;
00136
00137
00138 this.integratorNeedsReset = true;
00139 }
00140
00144 public void Animate()
00145 {
00146
00147 if (this.integratorNeedsReset)
00148 {
00149 this.acceleration = circularObjectIntegrator.Reset(this.p, this.v);
00150 }
00151
00152
00153
00154 circularObjectIntegrator.Step(out t, out p, out v, out acceleration);
00155 }
00156
00161 public void Drive(Vector2 force)
00162 {
00163 v[0] = this.h * force.X * this.mass;
00164 v[1] = this.h * force.Y * this.mass;
00165 }
00166
00172 public void SetPosition(Vector2 position)
00173 {
00174
00175 p[0] = position.X;
00176 p[1] = position.Y;
00177
00178
00179 v[0] = 0.0f;
00180 v[1] = 0.0f;
00181 }
00182
00188 public void SetPosition(Vector2 position, double scale)
00189 {
00190
00191 if (scale != 0.0)
00192 {
00193 p[0] = position.X / scale;
00194 p[1] = position.Y / scale;
00195 }
00196
00197
00198 v[0] = 0.0f;
00199 v[1] = 0.0f;
00200 }
00201
00206 public Vector2 GetPosition()
00207 {
00208
00209 circularObjectPosition.X = (float)(p[0]);
00210 circularObjectPosition.Y = (float)(p[1]);
00211
00212 return circularObjectPosition;
00213 }
00214
00220 public Vector2 GetPosition(double scale)
00221 {
00222
00223 circularObjectPosition.X = (float)(scale * p[0]);
00224 circularObjectPosition.Y = (float)(scale * p[1]);
00225
00226 return circularObjectPosition;
00227 }
00228 }
00229 }
00230