/// <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. must have massdb</param> /// <param name="entity">Entity. must have massdb</param> /// <param name="velocity_m">Velocity in meters.</param> public static OrbitDB FromVelocity_m(Entity parent, Entity entity, Vector3 velocity_m, 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_m;//entity.GetDataBlob<PositionDB>().AbsolutePosition_AU - parentPos; if (ralitivePos.Length() > OrbitProcessor.GetSOI_m(parent)) { throw new Exception("Entity not in target SOI"); } //var sgp = GameConstants.Science.GravitationalConstant * (myMass + parentMass) / 3.347928976e33; var sgp_m = GMath.StandardGravitationalParameter(myMass + parentMass); var ke_m = OrbitMath.KeplerFromPositionAndVelocity(sgp_m, ralitivePos, velocity_m, atDateTime); OrbitDB orbit = new OrbitDB(parent) { SemiMajorAxis = ke_m.SemiMajorAxis, Eccentricity = ke_m.Eccentricity, Inclination = ke_m.Inclination, LongitudeOfAscendingNode = ke_m.LoAN, ArgumentOfPeriapsis = ke_m.AoP, MeanAnomalyAtEpoch = ke_m.MeanAnomalyAtEpoch, Epoch = atDateTime, _parentMass = parentMass, _myMass = myMass }; orbit.CalculateExtendedParameters(); var pos = OrbitProcessor.GetPosition_m(orbit, atDateTime); var d = (pos - ralitivePos).Length(); if (d > 1) { var e = new Event(atDateTime, "Positional difference of " + Stringify.Distance(d) + " 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_m.TrueAnomalyAtEpoch); var obta = Angle.ToDegrees(OrbitProcessor.GetTrueAnomaly(orbit, atDateTime)); var tadif = Angle.ToDegrees(Angle.DifferenceBetweenRadians(keta, obta)); var pos1 = OrbitProcessor.GetPosition_m(orbit, atDateTime); var pos2 = OrbitProcessor.GetPosition_m(orbit, ke_m.TrueAnomalyAtEpoch); var d2 = (pos1 - pos2).Length(); } return(orbit); }
/* * public TimeSpan RunFrequency => TimeSpan.FromMinutes(60); * * public void ProcessEntity(Entity entity, int deltaSeconds) * { * SetEntityProfile(entity); * } * * public void ProcessManager(EntityManager manager, int deltaSeconds) * { * Stopwatch timer = new Stopwatch(); * timer.Start(); * var entites = manager.GetAllEntitiesWithDataBlob<SensorProfileDB>(); * foreach (var entity in entites) * { * ProcessEntity(entity, deltaSeconds); * } * var ms = timer.ElapsedMilliseconds; * var numEntites = entites.Count; * } */ public static void SetEntityProfile(Entity entity, DateTime atDate) { var position = entity.GetDataBlob <PositionDB>(); var sensorSig = entity.GetDataBlob <SensorProfileDB>(); sensorSig.LastPositionOfReflectionSet = position.AbsolutePosition_AU; sensorSig.LastDatetimeOfReflectionSet = atDate; var emmiters = entity.Manager.GetAllEntitiesWithDataBlob <SensorProfileDB>(); int numberOfEmmitters = emmiters.Count; sensorSig.ReflectedEMSpectra.Clear(); //PercentValue reflectionPercent = 0.1f; //TODO: this should be calculated from crossSection(size), and a reflectivity value(stealth armor?/ other design factors?). //var surfaceArea = sensorSig.TargetCrossSection_msq; double tRad = 500; if (entity.HasDataBlob <MassVolumeDB>()) { tRad = entity.GetDataBlob <MassVolumeDB>().RadiusInM; } foreach (var emittingEntity in emmiters) { if (emittingEntity != entity) // don't reflect our own emmision. { double distance = PositionDB.GetDistanceBetween_m(position, emittingEntity.GetDataBlob <PositionDB>()); if (distance < 1) { distance = 1; } var drad = Math.Sin(tRad / distance); var srad = Math.Sin(drad) * tRad; var surfaceArea = Math.PI * srad * srad; double reflectionCoefficent = surfaceArea * sensorSig.Reflectivity; var emmissionDB = emittingEntity.GetDataBlob <SensorProfileDB>(); foreach (var emitedItem in emmissionDB.EmittedEMSpectra) { var attenuated = SensorProcessorTools.AttenuationCalc(emitedItem.Value, distance);//per meter^2 var reflectedMagnatude = attenuated * reflectionCoefficent; //debug code: if (emitedItem.Value < 0) { throw new Exception("Source should not be less than 0"); } if (attenuated > emitedItem.Value) { throw new Exception("Attenuated value shoudl be less than source"); } if (reflectedMagnatude > emitedItem.Value) { var source = Stringify.Power(emitedItem.Value); var reflec = Stringify.Power(reflectedMagnatude); var dist = Stringify.Distance(distance); var surface = Stringify.Distance(surfaceArea); var dif = Stringify.Power(emitedItem.Value - reflectedMagnatude); //throw new Exception("final magnitude shoudl not be more than source"); //TODO: there's got to be a better way of calculating this. for now I'm just going to hack it. reflectedMagnatude = emitedItem.Value * sensorSig.Reflectivity; } if (reflectedMagnatude < 0) { throw new Exception("Final magnitude should not be less than 0"); } if (reflectedMagnatude > 0.001) //ignore it if the signal is less than a watt { if (sensorSig.ReflectedEMSpectra.ContainsKey(emitedItem.Key)) { sensorSig.ReflectedEMSpectra[emitedItem.Key] = sensorSig.ReflectedEMSpectra[emitedItem.Key] + reflectedMagnatude; } else { sensorSig.ReflectedEMSpectra.Add(emitedItem.Key, reflectedMagnatude); } } } } } }