Esempio n. 1
0
        /// <summary>
        /// Calculates distance/s on an orbit by calculating positions now and second in the future.
        /// </summary>
        /// <returns>the distance traveled in a second</returns>
        /// <param name="orbit">Orbit.</param>
        /// <param name="atDatetime">At datetime.</param>
        double hackspeed(OrbitDB orbit, DateTime atDatetime)
        {
            var pos1 = OrbitProcessor.GetPosition_AU(orbit, atDatetime);
            var pos2 = OrbitProcessor.GetPosition_AU(orbit, atDatetime + TimeSpan.FromSeconds(1));

            return(Distance.DistanceBetween(pos1, pos2));
        }
Esempio n. 2
0
        public void TestOrbitEpoch()
        {
            Game          game = new Game();
            EntityManager man  = new EntityManager(game, false);

            double  parentMass = 1.989e30;
            double  objMass    = 2.2e+15;
            Vector3 position   = new Vector3()
            {
                X = Distance.AuToMt(0.57)
            };                                                              //Halley's Comet at periapse aprox
            Vector3 velocity = new Vector3()
            {
                Y = 54000
            };

            BaseDataBlob[] parentblobs = new BaseDataBlob[3];
            parentblobs[0] = new PositionDB(man.ManagerGuid)
            {
                X_AU = 0, Y_AU = 0, Z_AU = 0
            };
            parentblobs[1] = new MassVolumeDB()
            {
                Mass = parentMass
            };
            parentblobs[2] = new OrbitDB();
            Entity parentEntity = new Entity(man, parentblobs);
            double sgp_m        = OrbitMath.CalculateStandardGravityParameterInM3S2(parentMass, objMass);

            OrbitDB objOrbit  = OrbitDB.FromVector(parentEntity, objMass, parentMass, sgp_m, position, velocity, new DateTime());
            Vector3 resultPos = OrbitProcessor.GetPosition_AU(objOrbit, new DateTime());
        }
Esempio n. 3
0
        public void TestOrbitEpoch()
        {
            Game          game = new Game();
            EntityManager man  = new EntityManager(game, false);

            double  parentMass = 1.989e30;
            double  objMass    = 2.2e+15;
            Vector3 position   = new Vector3()
            {
                X = 0.57
            };                                             //Halley's Comet at periapse aprox
            Vector3 velocity = new Vector3()
            {
                Y = Distance.KmToAU(54)
            };

            BaseDataBlob[] parentblobs = new BaseDataBlob[3];
            parentblobs[0] = new PositionDB(man.ManagerGuid)
            {
                X = 0, Y = 0, Z = 0
            };
            parentblobs[1] = new MassVolumeDB()
            {
                Mass = parentMass
            };
            parentblobs[2] = new OrbitDB();
            Entity parentEntity = new Entity(man, parentblobs);
            double sgp          = GameConstants.Science.GravitationalConstant * (parentMass + objMass) / 3.347928976e33;

            OrbitDB objOrbit  = OrbitDB.FromVector(parentEntity, objMass, parentMass, sgp, position, velocity, new DateTime());
            Vector3 resultPos = OrbitProcessor.GetPosition_AU(objOrbit, new DateTime());
        }
Esempio n. 4
0
        public void TrueAnomalyCalcs(OrbitDB orbitDB)
        {
            double sgp   = orbitDB.GravitationalParameterAU;
            double o_a   = orbitDB.SemiMajorAxis;
            double o_e   = orbitDB.Eccentricity;
            double o_i   = Angle.ToRadians(orbitDB.Inclination);
            double o_Ω   = Angle.ToRadians(orbitDB.LongitudeOfAscendingNode);
            double o_M0  = Angle.ToRadians(orbitDB.MeanAnomalyAtEpoch);
            double o_n   = Angle.ToRadians(orbitDB.MeanMotion);
            double o_ω   = Angle.ToRadians(orbitDB.ArgumentOfPeriapsis);
            double o_lop = OrbitMath.LonditudeOfPeriapsis2d(o_Ω, o_ω, o_i);

            DateTime o_epoch = orbitDB.Epoch;


            double periodInSeconds = orbitDB.OrbitalPeriod.TotalSeconds;
            double segmentTime     = periodInSeconds / 16;

            //lets break the orbit up and check the paremeters at different points of the orbit:
            for (int i = 0; i < 16; i++)
            {
                TimeSpan timeSinceEpoch  = TimeSpan.FromSeconds(segmentTime * i);
                DateTime segmentDatetime = o_epoch + timeSinceEpoch;
                double   o_M             = OrbitMath.GetMeanAnomalyFromTime(o_M0, o_n, timeSinceEpoch.TotalSeconds); //orbitProcessor uses this calc directly
                double   o_E             = OrbitProcessor.GetEccentricAnomaly(orbitDB, o_M);
                double   o_ν             = OrbitProcessor.GetTrueAnomaly(orbitDB, segmentDatetime);

                var     pos = OrbitProcessor.GetPosition_AU(orbitDB, segmentDatetime);
                Vector3 vel = (Vector3)OrbitMath.InstantaneousOrbitalVelocityVector(sgp, pos, o_a, o_e, o_ν);

                double aop = OrbitMath.ArgumentOfPeriapsis2(pos, i, o_Ω, o_ν);
                double ea  = o_e * o_a;
                double eccentricAnomaly = OrbitMath.GetEccentricAnomalyFromStateVectors(pos, o_a, ea, aop);

                double ν1 = OrbitMath.TrueAnomaly(sgp, pos, vel);

                double ν2 = OrbitMath.TrueAnomaly(o_E, pos, vel);
                double ν3 = OrbitMath.TrueAnomalyFromEccentricAnomaly(o_e, eccentricAnomaly);
                double ν4 = OrbitMath.TrueAnomalyFromEccentricAnomaly2(o_e, eccentricAnomaly);
                //var ν5 = OrbitMath.TrueAnomaly2(ev, pos, vel);
                //var ν6 = OrbitMath.TrueAnomaly(pos, aop);
                double d1 = Angle.ToDegrees(ν1);
                double d2 = Angle.ToDegrees(ν2);
                double d3 = Angle.ToDegrees(ν3);
                double d4 = Angle.ToDegrees(ν4);
                //var d5 = Angle.ToDegrees(ν5);
                //var d6 = Angle.ToDegrees(ν6);

                Assert.AreEqual(0, Angle.DifferenceBetweenRadians(o_ν, ν1), 1.0E-7, "True Anomaly ν expected: " + Angle.ToDegrees(o_ν) + " was: " + Angle.ToDegrees(ν1));
                Assert.AreEqual(0, Angle.DifferenceBetweenRadians(o_ν, ν2), 1.0E-7, "True Anomaly ν expected: " + Angle.ToDegrees(o_ν) + " was: " + Angle.ToDegrees(ν2));
                Assert.AreEqual(0, Angle.DifferenceBetweenRadians(o_ν, ν3), 1.0E-7, "True Anomaly ν expected: " + Angle.ToDegrees(o_ν) + " was: " + Angle.ToDegrees(ν3));
                Assert.AreEqual(0, Angle.DifferenceBetweenRadians(o_ν, ν4), 1.0E-7, "True Anomaly ν expected: " + Angle.ToDegrees(o_ν) + " was: " + Angle.ToDegrees(ν4));
                //Assert.AreEqual(0, Angle.DifferenceBetweenRadians(directAngle, aop - ν5), angleΔ);
                //Assert.AreEqual(0, Angle.DifferenceBetweenRadians(directAngle, aop - ν6), angleΔ);
            }
        }
        public void OnPhysicsUpdate()
        {
            _currentDateTime = _state.PrimarySystemDateTime;
            if (_transitLeaveDateTime < _currentDateTime)
            {
                _transitLeaveDateTime = _currentDateTime;
            }

            _transitLeavePositionRalitive = OrbitProcessor.GetPosition_AU(_movingEntityCurrentOrbit, _transitLeaveDateTime);
        }
 void OnSystemDateTimeChange(DateTime newDate)
 {
     if (_actionDateTime < newDate)
     {
         _actionDateTime     = newDate;
         _positonAtChange_AU = OrbitProcessor.GetPosition_AU(_orderEntityOrbit, _actionDateTime);
         var vector2 = OrbitProcessor.GetOrbitalVector(_orderEntityOrbit, _actionDateTime);
         _orbitalVelocityAtChange = new ECSLib.Vector3(vector2.X, vector2.Y, 0);
         _origionalAngle          = Math.Atan2(_orbitalVelocityAtChange.X, _orbitalVelocityAtChange.Y);
     }
 }
Esempio n. 7
0
        public void TestEccentricAnomalyCalcs(OrbitDB orbitDB)
        {
            double sgp   = orbitDB.GravitationalParameterAU;
            double o_a   = orbitDB.SemiMajorAxis;
            double o_e   = orbitDB.Eccentricity;
            double o_i   = Angle.ToRadians(orbitDB.Inclination);
            double o_Ω   = Angle.ToRadians(orbitDB.LongitudeOfAscendingNode);
            double o_M0  = Angle.ToRadians(orbitDB.MeanAnomalyAtEpoch);
            double o_n   = Angle.ToRadians(orbitDB.MeanMotion);
            double o_ω   = Angle.ToRadians(orbitDB.ArgumentOfPeriapsis);
            double o_lop = OrbitMath.LonditudeOfPeriapsis2d(o_Ω, o_ω, o_i);

            DateTime o_epoch = orbitDB.Epoch;

            double periodInSeconds = orbitDB.OrbitalPeriod.TotalSeconds;
            double segmentTime     = periodInSeconds / 16;

            //lets break the orbit up and check the paremeters at different points of the orbit:
            for (int i = 0; i < 16; i++)
            {
                TimeSpan timeSinceEpoch  = TimeSpan.FromSeconds(segmentTime * i);
                DateTime segmentDatetime = o_epoch + timeSinceEpoch;

                double o_M = OrbitMath.GetMeanAnomalyFromTime(o_M0, o_n, timeSinceEpoch.TotalSeconds); //orbitProcessor uses this calc directly
                double o_E = OrbitProcessor.GetEccentricAnomaly(orbitDB, o_M);
                double o_ν = OrbitProcessor.GetTrueAnomaly(orbitDB, segmentDatetime);

                var pos = OrbitProcessor.GetPosition_AU(orbitDB, segmentDatetime);
                var vel = OrbitMath.InstantaneousOrbitalVelocityVector(sgp, pos, o_a, o_e, o_ν);

                double linierEccentricity = o_e * o_a;

                var E1 = OrbitMath.GetEccentricAnomalyNewtonsMethod(o_e, o_M);  //newtons method.
                var E2 = OrbitMath.GetEccentricAnomalyNewtonsMethod2(o_e, o_M); //newtons method.
                var E3 = OrbitMath.GetEccentricAnomalyFromTrueAnomaly(o_ν, o_e);
                var E4 = OrbitMath.GetEccentricAnomalyFromStateVectors(pos, o_a, linierEccentricity, o_ω);
                //var E5 = OrbitMath.GetEccentricAnomalyFromStateVectors2(sgp, o_a, pos, vel);
                Assert.Multiple(() =>
                {
                    Assert.AreEqual(o_E, E1, "EccentricAnomaly E expected: " + Angle.ToDegrees(o_E) + " was: " + Angle.ToDegrees(E1));// these two should be calculatd the same way.
                    Assert.AreEqual(o_E, E2, 1.0E-7, "EccentricAnomaly E expected: " + Angle.ToDegrees(o_E) + " was: " + Angle.ToDegrees(E2));
                    Assert.AreEqual(o_E, E3, 1.0E-7, "EccentricAnomaly E expected: " + Angle.ToDegrees(o_E) + " was: " + Angle.ToDegrees(E3));
                    Assert.AreEqual(o_E, E4, 1.0E-7, "EccentricAnomaly E expected: " + Angle.ToDegrees(o_E) + " was: " + Angle.ToDegrees(E4));
                    //Assert.AreEqual(o_E, E5, 1.0E-7, "EccentricAnomaly E expected: " + Angle.ToDegrees(o_E) + " was: " + Angle.ToDegrees(E5));
                });
            }
        }
Esempio n. 8
0
        public void TestAngleOfPeriapsCalcs(OrbitDB orbitDB)
        {
            double sgp   = orbitDB.GravitationalParameterAU;
            double o_a   = orbitDB.SemiMajorAxis;
            double o_e   = orbitDB.Eccentricity;
            double o_i   = Angle.ToRadians(orbitDB.Inclination);
            double o_Ω   = Angle.ToRadians(orbitDB.LongitudeOfAscendingNode);
            double o_M0  = Angle.ToRadians(orbitDB.MeanAnomalyAtEpoch);
            double o_n   = Angle.ToRadians(orbitDB.MeanMotion);
            double o_ω   = Angle.ToRadians(orbitDB.ArgumentOfPeriapsis);
            double o_lop = OrbitMath.LonditudeOfPeriapsis2d(o_Ω, o_ω, o_i);

            DateTime o_epoch = orbitDB.Epoch;

            double periodInSeconds = orbitDB.OrbitalPeriod.TotalSeconds;
            double segmentTime     = periodInSeconds / 16;

            //lets break the orbit up and check the paremeters at different points of the orbit:
            for (int i = 0; i < 16; i++)
            {
                TimeSpan timeSinceEpoch  = TimeSpan.FromSeconds(segmentTime * i);
                DateTime segmentDatetime = o_epoch + timeSinceEpoch;
                double   o_M             = OrbitMath.GetMeanAnomalyFromTime(o_M0, o_n, timeSinceEpoch.TotalSeconds); //orbitProcessor uses this calc directly
                double   o_E             = OrbitProcessor.GetEccentricAnomaly(orbitDB, o_M);
                double   o_ν             = OrbitProcessor.GetTrueAnomaly(orbitDB, segmentDatetime);

                var     pos = OrbitProcessor.GetPosition_AU(orbitDB, segmentDatetime);
                Vector3 vel = (Vector3)OrbitMath.InstantaneousOrbitalVelocityVector(sgp, pos, o_a, o_e, o_ν);

                Vector3 angularVelocity = Vector3.Cross(pos, vel);
                Vector3 nodeVector      = Vector3.Cross(new Vector3(0, 0, 1), angularVelocity);
                Vector3 eccentVector    = OrbitMath.EccentricityVector(sgp, pos, vel);


                //var ω1 = OrbitMath.ArgumentOfPeriapsis(nodeVector, eccentVector, position, velocity);
                //var ω2 = OrbitMath.ArgumentOfPeriapsis(nodeVector, eccentVector, position, velocity, o_Ω);
                var ω3 = OrbitMath.ArgumentOfPeriapsis2(pos, o_i, o_Ω, o_ν);

                Assert.Multiple(() =>
                {
                    //Assert.AreEqual(o_ω, ω1, 1.0E-7, "AoP ω expected: " + Angle.ToDegrees(o_ω) + " was: " + Angle.ToDegrees(ω1));
                    //Assert.AreEqual(ω1, ω2, 1.0E-7, "AoP ω expected: " + Angle.ToDegrees(ω1) + " was: " + Angle.ToDegrees(ω2));
                    Assert.AreEqual(o_ω, ω3, 1.0E-7, "AoP ω expected: " + Angle.ToDegrees(o_ω) + " was: " + Angle.ToDegrees(ω3));
                });
            }
        }
        void OnEntityChange(EntityState entity)
        {
            OrderingEntity    = entity;
            _actionDateTime   = _state.PrimarySystemDateTime;
            _orderEntityOrbit = entity.Entity.GetDataBlob <OrbitDB>();

            _massParentBody     = _orderEntityOrbit.Parent.GetDataBlob <MassVolumeDB>().Mass;
            _massOrderingEntity = OrderingEntity.Entity.GetDataBlob <MassVolumeDB>().Mass;
            _stdGravParam       = GameConstants.Science.GravitationalConstant * (_massParentBody + _massOrderingEntity) / 3.347928976e33;

            _positonAtChange_AU = OrbitProcessor.GetPosition_AU(_orderEntityOrbit, _actionDateTime);
            var velAtChange2d = OrbitProcessor.GetOrbitalVector(_orderEntityOrbit, _actionDateTime);

            _orbitalVelocityAtChange = new ECSLib.Vector3(velAtChange2d.X, velAtChange2d.Y, 0);
            _origionalAngle          = Math.Atan2(_orbitalVelocityAtChange.X, _orbitalVelocityAtChange.Y);
            IsActive = true;
        }
Esempio n. 10
0
        /*
         * this gets the index by attempting to find the angle between the body and the center of the ellipse. possibly faster, but math is hard.
         * TODO: try doing this using TrueAnnomaly.
         * public override void OnPhysicsUpdate()
         * {
         *
         *  //adjust so moons get the right positions
         *  Vector4 pos = _bodyPositionDB.AbsolutePosition;// - _positionDB.AbsolutePosition;
         *  PointD pointD = new PointD() { x = pos.X, y = pos.Y };
         *
         *
         *  //adjust for focal point
         *  pos.X += _focalDistance;
         *
         *  //rotate to the LonditudeOfPeriapsis.
         *  double x2 = (pos.X * Math.Cos(-_orbitAngleRadians)) - (pos.Y * Math.Sin(-_orbitAngleRadians));
         *  double y2 = (pos.X * Math.Sin(-_orbitAngleRadians)) + (pos.Y * Math.Cos(-_orbitAngleRadians));
         *
         *  _ellipseStartArcAngleRadians = (float)(Math.Atan2(y2, x2));  //Atan2 returns a value between -180 and 180;
         *
         *  //PointD pnt = _points.OrderBy(p => CalcDistance(p, new PointD() {x = pos.X, y = pos.Y })).First();
         *
         *  //get the indexPosition in the point array we want to start drawing from: this should be the segment where the planet is.
         *  double unAdjustedIndex = (_ellipseStartArcAngleRadians / _segmentArcSweepRadians);
         *  while (unAdjustedIndex < 0)
         *  {
         *      unAdjustedIndex += (2 * Math.PI);
         *  }
         *  _index = (int)unAdjustedIndex;
         *
         * }
         */

        public override void OnPhysicsUpdate()
        {
            //Vector4 pos = _bodyPositionDB.AbsolutePosition_AU;
            Vector4 pos = OrbitProcessor.GetPosition_AU(_orbitDB, _orbitDB.OwningEntity.Manager.ManagerSubpulses.SystemLocalDateTime);

            _bodyRalitivePos = new PointD()
            {
                X = pos.X, Y = pos.Y
            };

            double minDist = CalcDistance(_bodyRalitivePos, _points[_index]);

            for (int i = 0; i < _points.Count(); i++)
            {
                double dist = CalcDistance(_bodyRalitivePos, _points[i]);
                if (dist < minDist)
                {
                    minDist = dist;
                    _index  = i;
                }
            }
        }
Esempio n. 11
0
        public void TestMeanAnomalyCalcs(OrbitDB orbitDB)
        {
            double sgp   = orbitDB.GravitationalParameterAU;
            double o_a   = orbitDB.SemiMajorAxis;
            double o_e   = orbitDB.Eccentricity;
            double o_i   = Angle.ToRadians(orbitDB.Inclination);
            double o_Ω   = Angle.ToRadians(orbitDB.LongitudeOfAscendingNode);
            double o_M0  = Angle.ToRadians(orbitDB.MeanAnomalyAtEpoch);
            double o_n   = Angle.ToRadians(orbitDB.MeanMotion);
            double o_ω   = Angle.ToRadians(orbitDB.ArgumentOfPeriapsis);
            double o_lop = OrbitMath.LonditudeOfPeriapsis2d(o_Ω, o_ω, o_i);

            DateTime o_epoch = orbitDB.Epoch;



            double periodInSeconds = orbitDB.OrbitalPeriod.TotalSeconds;
            double segmentTime     = periodInSeconds / 16;

            //lets break the orbit up and check the paremeters at different points of the orbit:
            for (int i = 0; i < 16; i++)
            {
                TimeSpan timeSinceEpoch  = TimeSpan.FromSeconds(segmentTime * i);
                DateTime segmentDatetime = o_epoch + timeSinceEpoch;
                double   o_M             = OrbitMath.GetMeanAnomalyFromTime(o_M0, o_n, timeSinceEpoch.TotalSeconds); //orbitProcessor uses this calc directly
                double   o_E             = OrbitProcessor.GetEccentricAnomaly(orbitDB, o_M);
                double   o_ν             = OrbitProcessor.GetTrueAnomaly(orbitDB, segmentDatetime);

                var pos = OrbitProcessor.GetPosition_AU(orbitDB, segmentDatetime);
                var vel = OrbitMath.InstantaneousOrbitalVelocityVector(sgp, pos, o_a, o_e, o_ν);

                var M1 = OrbitMath.GetMeanAnomaly(o_e, o_E);

                Assert.AreEqual(o_M, M1, 1.0E-7, "MeanAnomaly M expected: " + Angle.ToDegrees(o_M) + " was: " + Angle.ToDegrees(M1));
            }
        }
Esempio n. 12
0
        public void TestingKeplerConversions(OrbitDB orbitDB)
        {
            double sgp   = orbitDB.GravitationalParameterAU;
            double o_a   = orbitDB.SemiMajorAxis;
            double o_e   = orbitDB.Eccentricity;
            double o_i   = Angle.ToRadians(orbitDB.Inclination);
            double o_Ω   = Angle.ToRadians(orbitDB.LongitudeOfAscendingNode);
            double o_M0  = Angle.ToRadians(orbitDB.MeanAnomalyAtEpoch);
            double o_n   = Angle.ToRadians(orbitDB.MeanMotion);
            double o_ω   = Angle.ToRadians(orbitDB.ArgumentOfPeriapsis);
            double o_lop = OrbitMath.LonditudeOfPeriapsis2d(o_Ω, o_ω, o_i);

            DateTime o_epoch = orbitDB.Epoch;

            double periodInSeconds = OrbitMath.GetOrbitalPeriodInSeconds(sgp, o_a);

            Assert.AreEqual(periodInSeconds, orbitDB.OrbitalPeriod.TotalSeconds, 0.1);

            //lets break the orbit up and check the rest of the paremeters at different points of the orbit:
            double segmentTime = periodInSeconds / 16;

            for (int i = 0; i < 16; i++)
            {
                TimeSpan timeSinceEpoch  = TimeSpan.FromSeconds(segmentTime * i);
                DateTime segmentDatetime = o_epoch + timeSinceEpoch;

                double o_M = OrbitMath.GetMeanAnomalyFromTime(o_M0, o_n, timeSinceEpoch.TotalSeconds); //orbitProcessor uses this calc directly
                double o_E = OrbitProcessor.GetEccentricAnomaly(orbitDB, o_M);
                double o_ν = OrbitProcessor.GetTrueAnomaly(orbitDB, segmentDatetime);

                var pos = OrbitProcessor.GetPosition_AU(orbitDB, segmentDatetime);
                var vel = (Vector3)OrbitMath.InstantaneousOrbitalVelocityVector(sgp, pos, o_a, o_e, o_ν);

                var ke = OrbitMath.KeplerFromPositionAndVelocity(sgp, pos, vel, segmentDatetime);

                var    ke_epoch = ke.Epoch;
                double ke_a     = ke.SemiMajorAxis;
                double ke_e     = ke.Eccentricity;
                double ke_i     = ke.Inclination;
                double ke_Ω     = ke.LoAN;
                double ke_M0    = ke.MeanAnomalyAtEpoch;
                double ke_n     = ke.MeanMotion;
                double ke_ω     = ke.AoP;

                double ke_E = OrbitMath.GetEccentricAnomalyNewtonsMethod(ke.Eccentricity, ke_M0);
                double ke_ν = OrbitMath.TrueAnomalyFromEccentricAnomaly(ke_e, ke_E);


                Assert.Multiple(() =>
                {
                    //these should not change (other than floating point errors) between each itteration
                    Assert.AreEqual(o_a, ke_a, 0.001, "SemiMajorAxis a"); //should be more accurate than this, though if testing from a given set of ke to state, and back, the calculated could be more acurate...
                    Assert.AreEqual(o_e, ke_e, 0.00001, "Eccentricity e");
                    Assert.AreEqual(o_i, ke_i, 1.0E-7, "Inclination i expected: " + Angle.ToDegrees(o_i) + " was: " + Angle.ToDegrees(ke_i));
                    Assert.AreEqual(o_Ω, ke_Ω, 1.0E-7, "LoAN Ω expected: " + Angle.ToDegrees(o_Ω) + " was: " + Angle.ToDegrees(ke_Ω));
                    Assert.AreEqual(o_ω, ke_ω, 1.0E-7, "AoP ω expected: " + Angle.ToDegrees(o_ω) + " was: " + Angle.ToDegrees(ke_ω));
                    Assert.AreEqual(o_n, ke_n, 1.0E-7, "MeanMotion n expected: " + Angle.ToDegrees(o_n) + " was: " + Angle.ToDegrees(ke_n));

                    //these will change between itterations:

                    Assert.AreEqual(o_E, ke_E, 1.0E-7, "EccentricAnomaly E expected: " + Angle.ToDegrees(o_E) + " was: " + Angle.ToDegrees(ke_E));
                    Assert.AreEqual(o_ν, ke_ν, 1.0E-7, "True Anomaly ν expected: " + Angle.ToDegrees(o_ν) + " was: " + Angle.ToDegrees(ke_ν));
                    Assert.AreEqual(o_M, ke_M0, 1.0E-7, "MeanAnomaly M expected: " + Angle.ToDegrees(o_M) + " was: " + Angle.ToDegrees(ke_M0));
                });
            }
        }
Esempio n. 13
0
        public void TestOrbitalVelocityCalcs(OrbitDB orbitDB)
        {
            double sgp   = orbitDB.GravitationalParameterAU;
            double o_a   = orbitDB.SemiMajorAxis;
            double o_e   = orbitDB.Eccentricity;
            double o_i   = Angle.ToRadians(orbitDB.Inclination);
            double o_Ω   = Angle.ToRadians(orbitDB.LongitudeOfAscendingNode);
            double o_M0  = Angle.ToRadians(orbitDB.MeanAnomalyAtEpoch);
            double o_n   = Angle.ToRadians(orbitDB.MeanMotion);
            double o_ω   = Angle.ToRadians(orbitDB.ArgumentOfPeriapsis);
            double o_lop = OrbitMath.LonditudeOfPeriapsis2d(o_Ω, o_ω, o_i);

            DateTime o_epoch = orbitDB.Epoch;

            double periodInSeconds = orbitDB.OrbitalPeriod.TotalSeconds;
            double segmentTime     = periodInSeconds / 16;

            //lets break the orbit up and check the paremeters at different points of the orbit:
            for (int i = 0; i < 16; i++)
            {
                TimeSpan timeSinceEpoch  = TimeSpan.FromSeconds(segmentTime * i);
                DateTime segmentDatetime = o_epoch + timeSinceEpoch;
                double   o_M             = OrbitMath.GetMeanAnomalyFromTime(o_M0, o_n, timeSinceEpoch.TotalSeconds); //orbitProcessor uses this calc directly
                double   o_E             = OrbitProcessor.GetEccentricAnomaly(orbitDB, o_M);
                double   o_ν             = OrbitProcessor.GetTrueAnomaly(orbitDB, segmentDatetime);

                var pos = OrbitProcessor.GetPosition_AU(orbitDB, segmentDatetime);
                var vel = (Vector3)OrbitMath.InstantaneousOrbitalVelocityVector(sgp, pos, o_a, o_e, o_ν);

                Vector3 angularVelocity = Vector3.Cross(pos, vel);
                double  r       = pos.Length();
                double  speedau = OrbitMath.InstantaneousOrbitalSpeed(sgp, r, o_a);
                (double speed, double heading)polarVelocity = OrbitMath.InstantaneousOrbitalVelocityPolarCoordinate(sgp, pos, o_a, o_e, o_ν);
                //Tuple<double, double> polarVelocity2 = OrbitMath.PreciseOrbitalVelocityPolarCoordinate2(sgp, pos, o_a, o_e, o_ν, o_lop);
                double heading = OrbitMath.HeadingFromPeriaps(pos, o_e, o_a, o_ν);
                heading += o_lop;
                //Assert.IsTrue(angularVelocity.Z > 0); //TODO:this will break if we test an anti clockwise orbit.
                Assert.IsTrue(speedau > 0); //I'm assuming that speed will be <0 if retrograde orbit.
                Assert.AreEqual(vel.Length(), speedau, 1.0E-7);
                Assert.AreEqual(vel.Length(), polarVelocity.Item1, 1.0E-7);

                double hackHeading = OrbitMath.HackVelocityHeading(orbitDB, segmentDatetime);
                double hackheadD   = Angle.ToDegrees(hackHeading);
                double headingD    = Angle.ToDegrees(heading);


                if (o_e == 0)                   //we can make this work with ellipses if we add the lop to the position.
                {
                    if (pos.X > 0 && pos.Y > 0) //top right quadrant
                    {
                        //Assert.IsTrue(polarVelocity.Item2 > Math.PI * 0.5 && polarVelocity.Item2 < Math.PI);
                        //Assert.IsTrue(hackHeading > Math.PI * 0.5 && hackHeading < Math.PI);
                        Assert.IsTrue(heading >= Math.PI * 0.5 && heading <= Math.PI);
                    }
                    if (pos.X < 0 && pos.Y > 0)//top left quadrant
                    {
                        //Assert.IsTrue(polarVelocity.Item2 > Math.PI && polarVelocity.Item2 < Math.PI * 1.5);
                        //Assert.IsTrue(hackHeading > Math.PI && hackHeading < Math.PI * 1.5);
                        Assert.IsTrue(heading >= Math.PI && heading <= Math.PI * 1.5);
                    }
                    if (pos.X < 0 && pos.Y < 0)//bottom left quadrant
                    {
                        //Assert.IsTrue(polarVelocity.Item2 > Math.PI * 1.5 && polarVelocity.Item2 < Math.PI * 2);
                        //Assert.IsTrue(hackHeading > Math.PI * 1.5 && hackHeading < Math.PI * 2);
                        Assert.IsTrue(heading >= Math.PI * 1.5 && heading <= Math.PI * 2);
                    }
                    if (pos.X > 0 && pos.Y < 0)//bottom right quadrant
                    {
                        //Assert.IsTrue(polarVelocity.Item2 > 0 && polarVelocity.Item2 < Math.PI * 0.5);
                        //Assert.IsTrue(hackHeading > 0 && hackHeading < Math.PI * 0.5);
                        Assert.IsTrue(heading >= 0 && heading <= Math.PI * 0.5);
                    }
                }
            }
        }
Esempio n. 14
0
        public void TestOrbitDBFromVectors(double parentMass, double objMass, Vector3 position, Vector3 velocity)
        {
            double         angleΔ = 0.0000000001;
            double         sgp_m  = OrbitMath.CalculateStandardGravityParameterInM3S2(objMass, parentMass);
            KeplerElements ke     = OrbitMath.KeplerFromPositionAndVelocity(sgp_m, position, velocity, new DateTime());

            Game          game = new Game();
            EntityManager man  = new EntityManager(game, false);

            BaseDataBlob[] parentblobs = new BaseDataBlob[3];
            parentblobs[0] = new PositionDB(man.ManagerGuid)
            {
                X_AU = 0, Y_AU = 0, Z_AU = 0
            };
            parentblobs[1] = new MassVolumeDB()
            {
                Mass = parentMass
            };
            parentblobs[2] = new OrbitDB();
            Entity parentEntity = new Entity(man, parentblobs);


            OrbitDB objOrbit  = OrbitDB.FromVector(parentEntity, objMass, parentMass, sgp_m, position, velocity, new DateTime());
            Vector3 resultPos = OrbitProcessor.GetPosition_AU(objOrbit, new DateTime());

            //check LoAN
            var objLoAN        = objOrbit.LongitudeOfAscendingNode;
            var keLoAN         = ke.LoAN;
            var loANDifference = objLoAN - keLoAN;

            Assert.AreEqual(keLoAN, objLoAN, angleΔ);

            //check AoP
            var objAoP     = objOrbit.ArgumentOfPeriapsis;
            var keAoP      = ke.AoP;
            var difference = objAoP - keAoP;

            Assert.AreEqual(keAoP, objAoP, angleΔ);


            //check MeanAnomalyAtEpoch
            var objM0 = objOrbit.MeanAnomalyAtEpoch;
            var keM0  = ke.MeanAnomalyAtEpoch;

            Assert.AreEqual(keM0, objM0, angleΔ);
            Assert.AreEqual(objM0, OrbitMath.GetMeanAnomalyFromTime(objM0, objOrbit.MeanMotion_DegreesSec, 0), "meanAnomalyError");

            //checkEpoch
            var objEpoch = objOrbit.Epoch;
            var keEpoch  = ke.Epoch;

            Assert.AreEqual(keEpoch, objEpoch);



            //check EccentricAnomaly:
            var objE = (OrbitProcessor.GetEccentricAnomaly(objOrbit, objOrbit.MeanAnomalyAtEpoch_Degrees));
            //var keE =   (OrbitMath.Gete(position, ke.SemiMajorAxis, ke.LinearEccentricity, ke.AoP));

            /*
             * if (objE != keE)
             * {
             *  var dif = objE - keE;
             *  Assert.AreEqual(keE, objE, angleΔ);
             * }
             */
            //check trueAnomaly
            var orbTrueAnom         = OrbitProcessor.GetTrueAnomaly(objOrbit, new DateTime());
            var orbtaDeg            = Angle.ToDegrees(orbTrueAnom);
            var differenceInRadians = orbTrueAnom - ke.TrueAnomalyAtEpoch;
            var differenceInDegrees = Angle.ToDegrees(differenceInRadians);

            if (ke.TrueAnomalyAtEpoch != orbTrueAnom)
            {
                Vector3 eccentVector = OrbitMath.EccentricityVector(sgp_m, position, velocity);
                var     tacalc1      = OrbitMath.TrueAnomaly(eccentVector, position, velocity);
                var     tacalc2      = OrbitMath.TrueAnomaly(sgp_m, position, velocity);

                var diffa = differenceInDegrees;
                var diffb = Angle.ToDegrees(orbTrueAnom - tacalc1);
                var diffc = Angle.ToDegrees(orbTrueAnom - tacalc2);

                var ketaDeg = Angle.ToDegrees(tacalc1);
            }

            Assert.AreEqual(0, Angle.DifferenceBetweenRadians(ke.TrueAnomalyAtEpoch, orbTrueAnom), angleΔ,
                            "more than " + angleΔ + " radians difference, at " + differenceInRadians + " \n " +
                            "(more than " + Angle.ToDegrees(angleΔ) + " degrees difference at " + differenceInDegrees + ")" + " \n " +
                            "ke Angle: " + ke.TrueAnomalyAtEpoch + " obj Angle: " + orbTrueAnom + " \n " +
                            "ke Angle: " + Angle.ToDegrees(ke.TrueAnomalyAtEpoch) + " obj Angle: " + Angle.ToDegrees(orbTrueAnom));

            Assert.AreEqual(ke.Eccentricity, objOrbit.Eccentricity);
            Assert.AreEqual(ke.SemiMajorAxis, objOrbit.SemiMajorAxis);


            var lenke1 = ke.SemiMajorAxis * 2;
            var lenke2 = ke.Apoapsis + ke.Periapsis;

            Assert.AreEqual(lenke1, lenke2, 1.0E-10);
            var lendb1 = objOrbit.SemiMajorAxis_AU * 2;
            var lendb2 = objOrbit.Apoapsis_AU + objOrbit.Periapsis_AU;

            Assert.AreEqual(lendb1, lendb2, 1.0E-10);
            Assert.AreEqual(lenke1, lendb1, 1.0E-10);
            Assert.AreEqual(lenke2, lendb2, 1.0E-10);



            var ke_apkm   = Distance.AuToKm(ke.Apoapsis);
            var db_apkm   = Distance.AuToKm(objOrbit.Apoapsis_AU);
            var differnce = ke_apkm - db_apkm;

            Assert.AreEqual(ke.Apoapsis, objOrbit.Apoapsis_AU, 1.0E-10);
            Assert.AreEqual(ke.Periapsis, objOrbit.Periapsis_AU, 1.0E-10);

            Vector3 posKM    = Distance.AuToKm(position);
            Vector3 resultKM = Distance.AuToKm(resultPos);

            double  keslr       = EllipseMath.SemiLatusRectum(ke.SemiMajorAxis, ke.Eccentricity);
            double  keradius    = OrbitMath.RadiusAtAngle(ke.TrueAnomalyAtEpoch, keslr, ke.Eccentricity);
            Vector3 kemathPos   = OrbitMath.GetRalitivePosition(ke.LoAN, ke.AoP, ke.Inclination, ke.TrueAnomalyAtEpoch, keradius);
            Vector3 kemathPosKM = Distance.AuToKm(kemathPos);

            Assert.AreEqual(kemathPosKM.Length(), posKM.Length(), 0.01);

            Assert.AreEqual(posKM.Length(), resultKM.Length(), 0.01, "TA: " + orbtaDeg);
            Assert.AreEqual(posKM.X, resultKM.X, 0.01, "TA: " + orbtaDeg);
            Assert.AreEqual(posKM.Y, resultKM.Y, 0.01, "TA: " + orbtaDeg);
            Assert.AreEqual(posKM.Z, resultKM.Z, 0.01, "TA: " + orbtaDeg);

            if (velocity.Z == 0)
            {
                Assert.IsTrue(ke.Inclination == 0);
                Assert.IsTrue(objOrbit.Inclination_Degrees == 0);
            }

            //var speedVectorAU = OrbitProcessor.PreciseOrbitalVector(sgp, position, ke.SemiMajorAxis);
            //var speedVectorAU2 = OrbitProcessor.PreciseOrbitalVector(objOrbit, new DateTime());
            //Assert.AreEqual(speedVectorAU, speedVectorAU2);
        }