示例#1
0
        /// <summary>
        /// creates an asteroid that will collide with the given entity on the given date.
        /// </summary>
        /// <param name="starSys"></param>
        /// <param name="target"></param>
        /// <param name="collisionDate"></param>
        /// <returns></returns>
        public static Entity CreateAsteroid(StarSystem starSys, Entity target, DateTime collisionDate, double asteroidMass = -1.0)
        {
            //todo rand these a bit.
            double radius = Distance.KmToAU(0.5);

            double mass;

            if (asteroidMass == -1.0)
            {
                mass = 1.5e+12; //about 1.5 billion tonne
            }
            else
            {
                mass = asteroidMass;
            }
            Vector3 velocity = new Vector3(8, 7, 0);

            var position     = new PositionDB(0, 0, 0, Guid.Empty);
            var massVolume   = MassVolumeDB.NewFromMassAndRadius(mass, radius);
            var planetInfo   = new SystemBodyInfoDB();
            var balisticTraj = new NewtonBalisticDB(target.Guid, collisionDate);
            var name         = new NameDB("Ellie");
            var AsteroidDmg  = new AsteroidDamageDB();
            var sensorPfil   = new SensorProfileDB();

            planetInfo.SupportsPopulations = false;
            planetInfo.BodyType            = BodyType.Asteroid;

            Vector3  targetPos       = OrbitProcessor.GetAbsolutePosition_AU(target.GetDataBlob <OrbitDB>(), collisionDate);
            TimeSpan timeToCollision = collisionDate - StaticRefLib.CurrentDateTime;


            Vector3 offset = velocity * timeToCollision.TotalSeconds;

            targetPos -= Distance.KmToAU(offset);
            position.AbsolutePosition_AU = targetPos;
            position.SystemGuid          = starSys.Guid;
            balisticTraj.CurrentSpeed    = velocity;



            var planetDBs = new List <BaseDataBlob>
            {
                position,
                massVolume,
                planetInfo,
                name,
                balisticTraj,
                AsteroidDmg,
                sensorPfil
            };

            Entity newELE = new Entity(starSys, planetDBs);

            return(newELE);
        }
示例#2
0
        /// <summary>
        /// This intercept only works if time to intercept is less than the orbital period.
        /// </summary>
        /// <returns>The ntercept.</returns>
        /// <param name="mover">Mover.</param>
        /// <param name="targetOrbit">Target orbit.</param>
        /// <param name="atDateTime">At date time.</param>
        public static (Vector3, TimeSpan) FTLIntercept(Entity mover, OrbitDB targetOrbit, DateTime atDateTime)
        {
            //OrbitDB targetOrbit = target.GetDataBlob<OrbitDB>();
            //PositionDB targetPosition = target.GetDataBlob<PositionDB>();
            //PositionDB moverPosition = mover.GetDataBlob<PositionDB>();

            OrbitDB moverOrbit   = mover.GetDataBlob <OrbitDB>();
            Vector3 moverPosInKM = Distance.AuToKm(OrbitProcessor.GetAbsolutePosition_AU(moverOrbit, atDateTime));

            PropulsionAbilityDB moverPropulsion = mover.GetDataBlob <PropulsionAbilityDB>();

            Vector3 targetPosInKM = Distance.AuToKm((OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, atDateTime)));

            int speed = 25000;//moverPropulsion.MaximumSpeed * 100; //299792458;

            (Vector3, TimeSpan)intercept = (new Vector3(), TimeSpan.Zero);



            TimeSpan eti      = new TimeSpan();
            TimeSpan eti_prev = new TimeSpan();
            DateTime edi      = atDateTime;
            DateTime edi_prev = atDateTime;

            Vector3 predictedPosKM = Distance.AuToKm(OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, edi_prev));
            double  distance       = (predictedPosKM - moverPosInKM).Length();

            eti = TimeSpan.FromSeconds((distance * 1000) / speed);

            int steps = 0;

            if (eti < targetOrbit.OrbitalPeriod)
            {
                double timeDifference     = double.MaxValue;
                double distanceDifference = timeDifference * speed;
                while (distanceDifference >= 1000)
                {
                    eti_prev = eti;
                    edi_prev = edi;

                    predictedPosKM = Distance.AuToKm(OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, edi_prev));

                    distance = (predictedPosKM - moverPosInKM).Length();
                    eti      = TimeSpan.FromSeconds((distance * 1000) / speed);
                    edi      = atDateTime + eti;

                    timeDifference     = Math.Abs(eti.TotalSeconds - eti_prev.TotalSeconds);
                    distanceDifference = timeDifference * speed;
                    steps++;
                }
            }

            return(intercept);
        }
示例#3
0
        /// <summary>
        /// Creates on Orbit at current location from a given velocity
        /// </summary>
        /// <returns>The Orbit Does not attach the OrbitDB to the entity!</returns>
        /// <param name="parent">Parent.</param>
        /// <param name="entity">Entity.</param>
        /// <param name="velocityAU">Velocity.</param>
        public static OrbitDB FromVector(Entity parent, Entity entity, Vector3 velocityAU, DateTime atDateTime)
        {
            var parentMass = parent.GetDataBlob <MassVolumeDB>().Mass;
            var myMass     = entity.GetDataBlob <MassVolumeDB>().Mass;

            var epoch1 = parent.Manager.ManagerSubpulses.StarSysDateTime;                                      //getting epoch from here is incorrect as the local datetime doesn't change till after the subpulse.

            var parentPos = OrbitProcessor.GetAbsolutePosition_AU(parent.GetDataBlob <OrbitDB>(), atDateTime); //need to use the parent position at the epoch
            var posdb     = entity.GetDataBlob <PositionDB>();

            posdb.SetParent(parent);
            var ralitivePos = posdb.RelativePosition_AU;//entity.GetDataBlob<PositionDB>().AbsolutePosition_AU - parentPos;

            if (ralitivePos.Length() > OrbitProcessor.GetSOI(parent))
            {
                throw new Exception("Entity not in target SOI");
            }

            var sgp = GameConstants.Science.GravitationalConstant * (myMass + parentMass) / 3.347928976e33;
            var ke  = OrbitMath.KeplerFromPositionAndVelocity(sgp, ralitivePos, velocityAU, atDateTime);

            var epoch = atDateTime;// - TimeSpan.FromSeconds(ke.Epoch); //ke.Epoch is seconds from periapsis.

            OrbitDB orbit = new OrbitDB(parent, parentMass, myMass,
                                        Math.Abs(ke.SemiMajorAxis),
                                        ke.Eccentricity,
                                        Angle.ToDegrees(ke.Inclination),
                                        Angle.ToDegrees(ke.LoAN),
                                        Angle.ToDegrees(ke.AoP),
                                        Angle.ToDegrees(ke.MeanAnomalyAtEpoch),
                                        epoch);

            var pos = OrbitProcessor.GetPosition_AU(orbit, atDateTime);
            var d   = Distance.AuToKm(pos - ralitivePos).Length();

            if (d > 1)
            {
                var e = new Event(atDateTime, "Positional difference of " + d + "Km when creating orbit from velocity");
                e.Entity     = entity;
                e.SystemGuid = entity.Manager.ManagerGuid;
                e.EventType  = EventType.Opps;
                //e.Faction =  entity.FactionOwner;
                StaticRefLib.EventLog.AddEvent(e);

                //other info:
                var keta  = Angle.ToDegrees(ke.TrueAnomalyAtEpoch);
                var obta  = Angle.ToDegrees(OrbitProcessor.GetTrueAnomaly(orbit, atDateTime));
                var tadif = Angle.ToDegrees(Angle.DifferenceBetweenRadians(keta, obta));
                var pos1  = OrbitProcessor.GetPosition_AU(orbit, atDateTime);
                var pos2  = OrbitProcessor.GetPosition_AU(orbit, ke.TrueAnomalyAtEpoch);
                var d2    = Distance.AuToKm(pos1 - pos2).Length();
            }
            return(orbit);
        }
示例#4
0
        internal override void ActionCommand(Game game)
        {
            if (!IsRunning)
            {
                (Vector3 pos, DateTime eti)targetIntercept = InterceptCalcs.GetInterceptPosition(_entityCommanding, _targetEntity.GetDataBlob <OrbitDB>(), TransitStartDateTime, TargetOffsetPosition_AU);
                OrbitDB orbitDB    = _entityCommanding.GetDataBlob <OrbitDB>();
                Vector3 currentPos = OrbitProcessor.GetAbsolutePosition_AU(orbitDB, TransitStartDateTime);
                var     ralPos     = OrbitProcessor.GetPosition_AU(orbitDB, TransitStartDateTime);
                var     masses     = _entityCommanding.GetDataBlob <MassVolumeDB>().Mass + orbitDB.Parent.GetDataBlob <MassVolumeDB>().Mass;
                var     sgp        = GameConstants.Science.GravitationalConstant * masses / 3.347928976e33;

                //Vector4 currentVec = OrbitProcessor.PreciseOrbitalVector(sgp, ralPos, orbitDB.SemiMajorAxis);
                Vector2 currentVec = OrbitProcessor.GetOrbitalVector(orbitDB, TransitStartDateTime);
                _db = new TranslateMoveDB(targetIntercept.pos);
                _db.TranslateRalitiveExit_AU = TargetOffsetPosition_AU;
                _db.EntryDateTime            = TransitStartDateTime;
                _db.PredictedExitTime        = targetIntercept.eti;
                _db.TranslateEntryPoint_AU   = currentPos;
                _db.SavedNewtonionVector_AU  = currentVec;

                _db.ExpendDeltaV_AU = ExpendDeltaV;
                if (_targetEntity.HasDataBlob <SensorInfoDB>())
                {
                    _db.TargetEntity = _targetEntity.GetDataBlob <SensorInfoDB>().DetectedEntity;
                }
                else
                {
                    _db.TargetEntity = _targetEntity;
                }
                if (EntityCommanding.HasDataBlob <OrbitDB>())
                {
                    EntityCommanding.RemoveDataBlob <OrbitDB>();
                }
                EntityCommanding.SetDataBlob(_db);
                TranslateMoveProcessor.StartNonNewtTranslation(EntityCommanding);
                IsRunning = true;


                var distance   = (currentPos - targetIntercept.Item1).Length();
                var distancekm = Distance.AuToKm(distance);

                var time = targetIntercept.Item2 - TransitStartDateTime;

                double spd = _entityCommanding.GetDataBlob <PropulsionAbilityDB>().MaximumSpeed_MS;
                spd = Distance.MToAU(spd);
                var distb   = spd * time.TotalSeconds;
                var distbKM = Distance.AuToKm(distb);

                var dif = distancekm - distbKM;
                //Assert.AreEqual(distancekm, distbKM);
            }
        }
示例#5
0
        /// <summary>
        /// Calculates a cartisian position for an intercept for a ship and an target's orbit.
        /// </summary>
        /// <returns>The intercept position and DateTime</returns>
        /// <param name="mover">The entity that is trying to intercept a target.</param>
        /// <param name="targetOrbit">Target orbit.</param>
        /// <param name="atDateTime">Datetime of transit start</param>
        public static (Vector3 position, DateTime etiDateTime) GetInterceptPosition(Entity mover, OrbitDB targetOrbit, DateTime atDateTime, Vector3 offsetPosition = new Vector3())
        {
            Vector3 moverPos;

            if (mover.HasDataBlob <OrbitDB>())
            {
                //moverPos = Distance.AuToMt(OrbitProcessor.GetAbsolutePosition_AU(mover.GetDataBlob<OrbitDB>(), atDateTime));
                moverPos = OrbitProcessor.GetAbsolutePosition_AU(mover.GetDataBlob <OrbitDB>(), atDateTime);
            }
            else
            {
                moverPos = mover.GetDataBlob <PositionDB>().AbsolutePosition_AU;
            }
            double spd  = mover.GetDataBlob <PropulsionAbilityDB>().MaximumSpeed_MS;
            var    spd1 = Distance.MToAU(spd);

            return(GetInterceptPosition2(moverPos, spd1, targetOrbit, atDateTime, offsetPosition));
        }
示例#6
0
        public static OrbitDB FromVectorKM(Entity parent, double myMass, double parentMass, double sgp, Vector3 position, Vector3 velocity, DateTime atDateTime)
        {
            if (Distance.KmToAU(position.Length()) > OrbitProcessor.GetSOI(parent))
            {
                throw new Exception("Entity not in target SOI");
            }
            //var sgp  = GameConstants.Science.GravitationalConstant * (myMass + parentMass) / 3.347928976e33;
            var     ke    = OrbitMath.KeplerFromPositionAndVelocity(sgp, position, velocity, atDateTime);
            OrbitDB orbit = new OrbitDB(parent, parentMass, myMass,
                                        Distance.KmToAU(ke.SemiMajorAxis),
                                        ke.Eccentricity,
                                        Angle.ToDegrees(ke.Inclination),
                                        Angle.ToDegrees(ke.LoAN),
                                        Angle.ToDegrees(ke.AoP),
                                        Angle.ToDegrees(ke.MeanAnomalyAtEpoch),
                                        atDateTime);// - TimeSpan.FromSeconds(ke.Epoch));
            var pos = OrbitProcessor.GetAbsolutePosition_AU(orbit, atDateTime);

            return(orbit);
        }
示例#7
0
        /// <summary>
        /// creates an asteroid that will collide with the given entity on the given date.
        /// </summary>
        /// <param name="starSys"></param>
        /// <param name="target"></param>
        /// <param name="collisionDate"></param>
        /// <returns></returns>
        public static Entity CreateAsteroid(StarSystem starSys, Entity target, DateTime collisionDate, double asteroidMass = -1.0)
        {
            //todo rand these a bit.
            double radius = Distance.KmToAU(0.5);

            double mass;

            if (asteroidMass < 0)
            {
                mass = 1.5e+12; //about 1.5 billion tonne
            }
            else
            {
                mass = asteroidMass;
            }

            var     speed    = 40000;
            Vector3 velocity = new Vector3(speed, 0, 0);


            var massVolume  = MassVolumeDB.NewFromMassAndRadius_AU(mass, radius);
            var planetInfo  = new SystemBodyInfoDB();
            var name        = new NameDB("Ellie");
            var AsteroidDmg = new AsteroidDamageDB();

            AsteroidDmg.FractureChance = new PercentValue(0.75f);
            var dmgPfl     = EntityDamageProfileDB.AsteroidDamageProfile(massVolume.Volume_km3, massVolume.Density, massVolume.RadiusInM, 50);
            var sensorPfil = new SensorProfileDB();

            planetInfo.SupportsPopulations = false;
            planetInfo.BodyType            = BodyType.Asteroid;

            Vector3  targetPos       = OrbitProcessor.GetAbsolutePosition_m(target.GetDataBlob <OrbitDB>(), collisionDate);
            TimeSpan timeToCollision = collisionDate - StaticRefLib.CurrentDateTime;


            var parent     = target.GetDataBlob <OrbitDB>().Parent;
            var parentMass = parent.GetDataBlob <MassVolumeDB>().Mass;
            var myMass     = massVolume.Mass;

            double  sgp   = OrbitMath.CalculateStandardGravityParameterInM3S2(myMass, parentMass);
            OrbitDB orbit = OrbitDB.FromVector(parent, myMass, parentMass, sgp, targetPos, velocity, collisionDate);

            var currentpos = OrbitProcessor.GetAbsolutePosition_AU(orbit, StaticRefLib.CurrentDateTime);
            var posDB      = new PositionDB(currentpos.X, currentpos.Y, currentpos.Z, parent.Manager.ManagerGuid, parent);


            var planetDBs = new List <BaseDataBlob>
            {
                posDB,
                massVolume,
                planetInfo,
                name,
                orbit,
                AsteroidDmg,
                dmgPfl,
                sensorPfil
            };

            Entity newELE = new Entity(starSys, planetDBs);

            return(newELE);
        }
示例#8
0
        public static (Vector3 position, DateTime etiDateTime) GetInterceptPosition2(Vector3 moverPos, double speed, OrbitDB targetOrbit, DateTime atDateTime, Vector3 offsetPosition = new Vector3())
        {
            var    pos = moverPos;
            double tim = 0;



            var pl = new obit()
            {
                position = moverPos,
                T        = targetOrbit.OrbitalPeriod.TotalSeconds,
            };

            double a = targetOrbit.SemiMajorAxis * 2;



            Vector3 p;
            int     i;
            double  tt, t, dt, a0, a1, T;

            // find orbital position with min error (coarse)
            a1 = -1.0;
            dt = 0.01 * pl.T;


            for (t = 0; t < pl.T; t += dt)
            {
                p  = OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, atDateTime + TimeSpan.FromSeconds(t)); //pl.position(sim_t + t);                     // try time t
                p += offsetPosition;
                tt = Vector3.Magnitude(p - pos) / speed;                                                       //length(p - pos) / speed;
                a0 = tt - t; if (a0 < 0.0)
                {
                    continue;                                 // ignore overshoots
                }
                a0 /= pl.T;                                   // remove full periods from the difference
                a0 -= Math.Floor(a0);
                a0 *= pl.T;
                if ((a0 < a1) || (a1 < 0.0))
                {
                    a1  = a0;
                    tim = tt;
                }   // remember best option
            }
            // find orbital position with min error (fine)
            for (i = 0; i < 10; i++)                               // recursive increase of accuracy
            {
                for (a1 = -1.0, t = tim - dt, T = tim + dt, dt *= 0.1; t < T; t += dt)
                {
                    p  = OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, atDateTime + TimeSpan.FromSeconds(t)); //p = pl.position(sim_t + t);                     // try time t
                    p += offsetPosition;
                    tt = Vector3.Magnitude(p - pos) / speed;                                                       //tt = length(p - pos) / speed;
                    a0 = tt - t; if (a0 < 0.0)
                    {
                        continue;                                 // ignore overshoots
                    }
                    a0 /= pl.T;                                   // remove full periods from the difference
                    a0 -= Math.Floor(a0);
                    a0 *= pl.T;
                    if ((a0 < a1) || (a1 < 0.0))
                    {
                        a1  = a0;
                        tim = tt;
                    }   // remember best option
                }
            }
            // direction
            p  = OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, atDateTime + TimeSpan.FromSeconds(tim));//pl.position(sim_t + tim);
            p += offsetPosition;
            //dir = normalize(p - pos);
            return(p, atDateTime + TimeSpan.FromSeconds(tim));
        }
示例#9
0
        public static Entity CreateAsteroid2(StarSystem starSys, Entity target, DateTime collisionDate, double asteroidMass = -1.0)
        {
            //todo rand these a bit.
            double radius = Distance.KmToAU(0.5);

            double mass;

            if (asteroidMass == -1.0)
            {
                mass = 1.5e+12; //about 1.5 billion tonne
            }
            else
            {
                mass = asteroidMass;
            }
            Vector3 velocity = new Vector3(8, 7, 0);

            var position     = new PositionDB(0, 0, 0, Guid.Empty);
            var massVolume   = MassVolumeDB.NewFromMassAndRadius(mass, radius);
            var planetInfo   = new SystemBodyInfoDB();
            var balisticTraj = new NewtonBalisticDB(target.Guid, collisionDate);
            var name         = new NameDB("Ellie");
            var AsteroidDmg  = new AsteroidDamageDB();
            var sensorPfil   = new SensorProfileDB();

            planetInfo.SupportsPopulations = false;
            planetInfo.BodyType            = BodyType.Asteroid;

            Vector3  targetPos       = OrbitProcessor.GetAbsolutePosition_AU(target.GetDataBlob <OrbitDB>(), collisionDate);
            TimeSpan timeToCollision = collisionDate - StaticRefLib.CurrentDateTime;


            Vector3 offset = velocity * timeToCollision.TotalSeconds;

            targetPos -= Distance.KmToAU(offset);
            position.AbsolutePosition_AU = targetPos;
            position.SystemGuid          = starSys.Guid;
            balisticTraj.CurrentSpeed    = velocity;


            var parent          = target.GetDataBlob <OrbitDB>().Parent;
            var parentMass      = parent.GetDataBlob <MassVolumeDB>().Mass;
            var myMass          = massVolume.Mass;
            var mySemiMajorAxis = 5.055;
            var myEccentricity  = 0.8;
            var myInclination   = 0;
            var myLoAN          = 0;
            var myAoP           = -10;
            //var EccentricAnomaly = Math.Atan2()
            //var meanAnomaly =;
            double myLoP       = 0;
            double myMeanLongd = 355.5;
            //OrbitDB orbit = OrbitDB.FromAsteroidFormat(parent, parentMass, myMass, mySemiMajorAxis, myEccentricity, myInclination, myLoAN, myAoP, meanAnomaly, starSys.Game.CurrentDateTime);
            OrbitDB orbit = OrbitDB.FromMajorPlanetFormat(parent, parentMass, myMass, mySemiMajorAxis, myEccentricity, myInclination, myLoAN, myLoP, myMeanLongd, StaticRefLib.CurrentDateTime);

            var planetDBs = new List <BaseDataBlob>
            {
                position,
                massVolume,
                planetInfo,
                name,
                orbit,
                AsteroidDmg,
                sensorPfil
            };

            Entity newELE = new Entity(starSys, planetDBs);

            return(newELE);
        }