public Atom(string name, Vector2 p0) { atomID = ATOM_ID++; Name = name; if (ColorMap == null) { ColorMap = new Dictionary <string, SolidBrush>(); ColorMap.Add("Elektron", new SolidBrush(Color.Blue)); ColorMap.Add("Proton", new SolidBrush(Color.Red)); ColorMap.Add("Neutrone", new SolidBrush(Color.DarkGray)); } Atoms = new List <Atom>(); PositionApproximation = new RK4(p0, DELTA0); PositionApproximation.f = (x, y) => { return(VelocityApproximation.Run(y)); }; VelocityApproximation = new RK4(new Vector2(), DELTA0); VelocityApproximation.f = (x, y) => { Vector2 a = new Vector2(); for (int i = 0; i < Atoms.Count; i++) { Vector2 u = Atoms[i].PositionApproximation.Output; Vector2 v = this.PositionApproximation.Output; double q1 = this.q; double q2 = Atoms[i].q; Vector2 d = u - v; double length = d.Length(); d /= length; Vector2 F = (q1 * q2) / (4.0 * Math.PI * E0 * length * length) * d; a += F / Mass; } return(a); }; }
public Saturn() { NumericEccentricity = 0.05648f; TurnAroundTime = 928735200.0f; PlanetMass = 5.683E26; Weights = new Vector2(0.999f, 0.03f); Diameter = 50000000; Initialize(); VelocityApproximation = new RK4(Velocity, CelestialBody.Delta); VelocityApproximation.f = a; PositionApproximation = new Euler(Position, CelestialBody.Delta); PositionApproximation.f = v; Color = Color.SandyBrown; }
public Jupiter() { NumericEccentricity = 0.0484f; TurnAroundTime = 374112000.0f; PlanetMass = 1.898E27; Weights = new Vector2(0.99f, 0.09f); Diameter = 100000000; Initialize(); VelocityApproximation = new RK4(Velocity, CelestialBody.Delta); VelocityApproximation.f = a; PositionApproximation = new Euler(Position, CelestialBody.Delta); PositionApproximation.f = v; Color = Color.Brown; }
public void PreSimulate() { for (double x = 0; x <= TurnAroundTime + Delta; x += Delta) { _vertices.Add(new VertexPositionColor(Position / 1000000000.0f, Color)); _indices.Add(_index); _indices.Add(++_index); Position = PositionApproximation.Run(Position); } _indices.RemoveAt(_indices.Count - 1); _indices.RemoveAt(_indices.Count - 1); Initialize(); VelocityApproximation = new RK4(Velocity, CelestialBody.Delta); VelocityApproximation.f = a; PositionApproximation = new Euler(Position, CelestialBody.Delta); PositionApproximation.f = v; }
public void IntegrateTest() { const float Gravity = -9.81f; const float theta = 0.25f; const float v0 = 500f; var currentState = new State() { Position = new Vector3d() { X = 0, Y = 0, Z = 0 }, Velocity = new Vector3d() { X = v0 * (float)Math.Cos(theta), Y = v0 * (float)Math.Sin(theta), Z = 0 } }; const float timeStep = 0.01f; const float allowedDeviationPosition = 0.8f; const float allowedDeviationVelocity = 0.02f; Vector3d deltaPosition = Vector3d.Zero; Vector3d deltaVelocity = Vector3d.Zero; var rk4 = new RK4(); while (currentState.Position.Y >= -0.1f) { rk4.Integrate(timeStep, ref currentState, out currentState, (double dt, ref State state) => { return(Vector3d.UnitY * Gravity); }); Vector3d analyticalPosition = new Vector3d() { X = (float)(v0 * Math.Cos(theta) * currentState.Time), Y = (float)(v0 * Math.Sin(theta) * currentState.Time - 0.5 * 9.81 * currentState.Time * currentState.Time), Z = 0f }; Vector3d analyticalVelocity = new Vector3d() { X = (float)(v0 * Math.Cos(theta)), Y = (float)(v0 * Math.Sin(theta) - 9.81 * currentState.Time), Z = 0f }; deltaPosition = analyticalPosition - currentState.Position; deltaVelocity = analyticalVelocity - currentState.Velocity; if (deltaPosition.Length > allowedDeviationPosition) { Assert.Fail(string.Format("Position has gone out of error range at time {1,2:F}: {0,8:F}", deltaPosition.Length, currentState.Time)); } if (deltaVelocity.Length > allowedDeviationVelocity) { Assert.Fail(string.Format("Velocity has gone out of error range at time {1,2:F}: {0,8:F}", deltaVelocity.Length, currentState.Time)); } } Console.WriteLine(string.Format("Final deviation: position: {0,8:F}, velocity: {1,8:F}", deltaPosition.Length, deltaVelocity.Length)); }