/// <summary> /// In Meters! /// </summary> /// <param name="parent"></param> /// <param name="myMass"></param> /// <param name="parentMass"></param> /// <param name="sgp_m"></param> /// <param name="position_m"></param> /// <param name="velocity_m"></param> /// <param name="atDateTime"></param> /// <returns></returns> /// <exception cref="Exception"></exception> public static OrbitDB FromVector(Entity parent, double myMass, double parentMass, double sgp_m, Vector3 position_m, Vector3 velocity_m, DateTime atDateTime) { if (position_m.Length() > OrbitProcessor.GetSOI_AU(parent)) { throw new Exception("Entity not in target SOI"); } //var sgp = GameConstants.Science.GravitationalConstant * (myMass + parentMass) / 3.347928976e33; var ke = OrbitMath.KeplerFromPositionAndVelocity(sgp_m, position_m, velocity_m, atDateTime); OrbitDB orbit = new OrbitDB(parent) { SemiMajorAxis = ke.SemiMajorAxis, Eccentricity = ke.Eccentricity, Inclination = ke.Inclination, LongitudeOfAscendingNode = ke.LoAN, ArgumentOfPeriapsis = ke.AoP, MeanAnomalyAtEpoch = ke.MeanAnomalyAtEpoch, Epoch = atDateTime, _parentMass = parent.GetDataBlob <MassVolumeDB>().Mass, _myMass = myMass }; orbit.CalculateExtendedParameters(); var pos = OrbitProcessor.GetAbsolutePosition_m(orbit, atDateTime); return(orbit); }
/// <summary> /// Gets a future position for this entity, regarless of wheter it's orbit or newtonion trajectory /// </summary> /// <param name="entity"></param> /// <param name="atDateTime"></param> /// <param name="ralitive"></param> /// <returns>In Meters</returns> /// <exception cref="Exception"></exception> public static Vector3 GetPosition_m(Entity entity, DateTime atDateTime, bool ralitive = true) { if (entity.HasDataBlob<OrbitDB>()) { if (ralitive) return OrbitProcessor.GetPosition_m(entity.GetDataBlob<OrbitDB>(), atDateTime); else return OrbitProcessor.GetAbsolutePosition_m(entity.GetDataBlob<OrbitDB>(), atDateTime); } else if (entity.HasDataBlob<NewtonMoveDB>()) { if (ralitive) return NewtonionMovementProcessor.GetPositon_m(entity, entity.GetDataBlob<NewtonMoveDB>(), atDateTime).pos; else return NewtonionMovementProcessor.GetAbsulutePositon_m(entity, entity.GetDataBlob<NewtonMoveDB>(), atDateTime).pos; } else if (entity.HasDataBlob<PositionDB>()) { if(ralitive) return entity.GetDataBlob<PositionDB>().RelativePosition_m; else return entity.GetDataBlob<PositionDB>().AbsolutePosition_m; } else { throw new Exception("Entity is positionless"); } }
/// <summary> /// Gets a future position for this entity, regarless of wheter it's orbit or newtonion trajectory /// </summary> /// <param name="entity"></param> /// <param name="atDateTime"></param> /// <returns>In Meters</returns> /// <exception cref="Exception"> if entity doesn't have one of the correct datablobs</exception> public static Vector3 GetAbsoluteFuturePosition(Entity entity, DateTime atDateTime) { if (entity.HasDataBlob <OrbitDB>()) { return(OrbitProcessor.GetAbsolutePosition_m(entity.GetDataBlob <OrbitDB>(), atDateTime)); } else if (entity.HasDataBlob <OrbitUpdateOftenDB>()) { return(OrbitProcessor.GetAbsolutePosition_m(entity.GetDataBlob <OrbitUpdateOftenDB>(), atDateTime)); } else if (entity.HasDataBlob <NewtonMoveDB>()) { return(NewtonionMovementProcessor.GetAbsoluteState(entity, entity.GetDataBlob <NewtonMoveDB>(), atDateTime).pos); } else if (entity.HasDataBlob <PositionDB>()) { return(entity.GetDataBlob <PositionDB>().AbsolutePosition_m); } else { throw new Exception("Entity is positionless"); } }
/// <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); }
/// <summary> /// /// </summary> /// <param name="moverAbsolutePos"></param> /// <param name="speed"></param> /// <param name="targetOrbit"></param> /// <param name="atDateTime"></param> /// <param name="offsetPosition">position ralitive to the target object we wish to stop warp.</param> /// <returns></returns> public static (Vector3 position, DateTime etiDateTime) GetInterceptPosition_m(Vector3 moverAbsolutePos, double speed, OrbitDB targetOrbit, DateTime atDateTime, Vector3 offsetPosition = new Vector3()) { var pos = moverAbsolutePos; double tim = 0; var pl = new obit() { position = moverAbsolutePos, 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_m(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_m(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_m(targetOrbit, atDateTime + TimeSpan.FromSeconds(tim));//pl.position(sim_t + tim); p += offsetPosition; //dir = normalize(p - pos); return(p, atDateTime + TimeSpan.FromSeconds(tim)); }