/// <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); }
/// <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); }
/// <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); }
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); } }
/// <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)); }
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); }
/// <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); }
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)); }
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); }