PageRenderTime 20ms CodeModel.GetById 11ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/SolarSystem/System.cs

https://bitbucket.org/efouts/solarsystem
C# | 65 lines | 52 code | 13 blank | 0 comment | 2 complexity | 575a26118f9fff1eba4fe5f927af9729 MD5 | raw file
 1using MathNet.Numerics.LinearAlgebra.Double;
 2using System;
 3using System.Collections.Generic;
 4using System.Linq;
 5using System.Text;
 6using System.Threading.Tasks;
 7using MathNet.Numerics.LinearAlgebra.Generic;
 8using MathNet.Numerics;
 9
10namespace SolarSystem
11{
12    public class System
13    {
14        private const Int32 X = 0;
15        private const Int32 Y = 1;
16
17        public IEnumerable<Body> Bodies { get; private set; }
18
19        public System(IEnumerable<Body> bodies)
20        {
21            Bodies = bodies;
22        }
23
24        public void DoTicks(Double ticks)
25        {
26            foreach (var body in Bodies)
27                DoTicks(body, ticks);
28        }
29
30        private void DoTicks(Body body, Double ticks)
31        {
32            var acceleration = GetTotalAccelerationActingOnBody(body);
33
34            body.Velocity = body.Velocity.Add(acceleration * ticks);
35            body.Position = body.Position.Add(body.Velocity * ticks);
36
37            var bodyCircumference = 2 * Math.PI * body.Radius;
38            var rotationPercentage = body.RotationVelocity * ticks / bodyCircumference;
39            body.Rotation += (360 * rotationPercentage) % 360;
40        }
41
42        private Vector<Double> GetTotalAccelerationActingOnBody(Body body)
43        {
44            Vector<Double> totalAcceleration = new DenseVector(new[] { 0d, 0d });
45
46            foreach (var otherBody in Bodies)
47                if (body != otherBody)
48                    totalAcceleration = totalAcceleration + GetAccelerationDueToGravity(body, otherBody);
49
50            return totalAcceleration;
51        }
52
53        private Vector<Double> GetAccelerationDueToGravity(Body body, Body otherBody)
54        {
55            var differenceVector = otherBody.Position.Subtract(body.Position);
56            var differenceMagnitude = Math.Sqrt(Math.Pow(differenceVector[X], 2) + Math.Pow(differenceVector[Y], 2));
57            var differenceUnit = new DenseVector(new[] { differenceVector[X] / differenceMagnitude, differenceVector[Y] / differenceMagnitude });
58
59            var accelerationScalar = Constants.GravitationalConstant * otherBody.Mass / Math.Pow(differenceMagnitude, 2);
60            var accelerationVector = differenceUnit * accelerationScalar;
61
62            return accelerationVector;
63        }
64    }
65}