public void updatePotentialEncounters(GravityElementsClass newManeuver) { foreach (Encounter encounter in encounters.maneuverEncounters) { Destroy(encounter.PerigeeIcon.poiIcon); } encounters.maneuverEncounters.Clear(); //initial setup GameObject tempPerigeeIcon = Instantiate(perigeeIcon); OrbitalPOI perigeePOI = new OrbitalPOI(tempPerigeeIcon, newManeuver.Perigee); Encounter currentEncounter = new Encounter(newManeuver, newManeuver.TrueAnomaly, double.PositiveInfinity, 0, perigeePOI); iterations = 0; predictAnEncounter(currentEncounter, ref encounters.maneuverEncounters); }
//Finds all encounters within one orbit of the craft public void updateEncounters() { foreach (Encounter encounter in encounters.predictedEncounters) { Destroy(encounter.PerigeeIcon.poiIcon); } encounters.predictedEncounters.Clear(); //initial setup GravityElementsClass currentShipsGravityElements = shipElements.getClassVersion(); double startingTrueAnomaly = shipElements.TrueAnomaly; GameObject tempPerigeeIcon = Instantiate(perigeeIcon); OrbitalPOI perigeePOI = new OrbitalPOI(tempPerigeeIcon, currentShipsGravityElements.Perigee); Encounter currentEncounter = new Encounter(currentShipsGravityElements, startingTrueAnomaly, double.PositiveInfinity, 0, perigeePOI); iterations = 0; predictAnEncounter(currentEncounter, ref encounters.predictedEncounters); instantiatePOIs(encounters.predictedEncounters); }
public Encounter(GravityElementsClass gravElements, double startingTrueAnomaly, double endingTrueAnomaly, double timeOfEncounter, OrbitalPOI perigeeIcon) { this.gravElements = gravElements; this.startingTrueAnomaly = startingTrueAnomaly; this.endingTrueAnomaly = endingTrueAnomaly; this.timeOfEncounter = timeOfEncounter; this.perigeeIcon = perigeeIcon; }
//Takes in the ships current gravity elements according to its last encounter, current massive body elements as they are at tiem 0 and current massivebodyelements as they are at time 0 private void predictAnEncounter(Encounter currentEncounter, ref List <Encounter> encounters) { encounters.Add(currentEncounter); //data sources MassiveBodyElements currentMassiveBody = currentEncounter.GravElements.massiveBody.GetComponent <MassiveBodyElements>(); GravityElementsClass currentMassiveBodyGravElements = currentEncounter.GravElements.massiveBody.GetComponent <GravityElements>().getClassVersion(); iterations++; double time = 0; double currentOrbitalPeriod = calculatePeriod(currentEncounter.GravElements.OrbitType, currentEncounter.GravElements.SemiMajorAxis, currentEncounter.GravElements.Mu); bool foundNewEncounter = false; GameObject encounteredMassiveBody = null; while (time < currentOrbitalPeriod && !foundNewEncounter) { time += 0.01; //have we exited the current soi? double altitude = currentEncounter.GravElements.calculateLocalPositionAtFutureTime(time).magnitude; //the ships massive body is always at time 0 if (currentMassiveBody.SphereOfInfluence < altitude) { foundNewEncounter = true; encounteredMassiveBody = currentEncounter.GravElements.massiveBody.GetComponent <GravityElements>().massiveBody; break; } //have we entered a new soi? foreach (GameObject satelite in currentMassiveBody.satelites) { double sateliteSphereOfInfluence = satelite.GetComponent <MassiveBodyElements>().SphereOfInfluence; Vector2 sateliteLocalPosition = satelite.GetComponent <GravityElements>().calculateLocalPositionAtFutureTime(time + currentEncounter.TimeOfEncounter); Vector2 shipsLocalPosition = currentEncounter.GravElements.calculateLocalPositionAtFutureTime(time); if (Vector2.Distance(shipsLocalPosition, sateliteLocalPosition) < sateliteSphereOfInfluence) { foundNewEncounter = true; encounteredMassiveBody = satelite; break; } } if (time > 100) //hyperbolic orbit with infinite periode, this prevents infinite loops { break; } } //We have encountered nothing, just a regular eliptical orbit, or a hyperbolic one that's really long if (encounteredMassiveBody == null) { return; } //We have encountered a massive body, time to assemble a new encounter Tuple <Vector2, Vector2> returnInfo; returnInfo = currentEncounter.GravElements.calculateLocalPositionAndVelocityAtFutureTime(time); Vector2 shipPredictedLocalPosition = returnInfo.item1; Vector2 shipPredictedLocalVelocity = returnInfo.item2; returnInfo = currentMassiveBodyGravElements.calculateGlobalPositionAndVelocityAtFutureTime(time + currentEncounter.TimeOfEncounter); Vector2 currentMassiveBodyPredictedGlobalPosition = returnInfo.item1; Vector2 currentMassiveBodyPredictedGlobalVelocity = returnInfo.item2; returnInfo = encounteredMassiveBody.GetComponent <GravityElements>().calculateGlobalPositionAndVelocityAtFutureTime(time + currentEncounter.TimeOfEncounter); Vector2 encounteredMassiveBodyPredictedGlobalPosition = returnInfo.item1; Vector2 encounteredmassiveBodyPredictedGlobalVelocity = returnInfo.item2; Vector2 shipPositionRelativeToEncounter = (shipPredictedLocalPosition + currentMassiveBodyPredictedGlobalPosition) - encounteredMassiveBodyPredictedGlobalPosition; Vector2 shipVelocityRelativeToEncounter = (shipPredictedLocalVelocity + currentMassiveBodyPredictedGlobalVelocity) - encounteredmassiveBodyPredictedGlobalVelocity; GravityElementsClass newShipsGravityElements = calculateInitialOrbitalElements(shipPositionRelativeToEncounter, shipVelocityRelativeToEncounter, encounteredMassiveBody); //massive body is inputed in its state at time 0 //Change the ending true anomaly of the last encounter double startingTrueAnomaly = newShipsGravityElements.TrueAnomaly; double endingTrueAnomaly = MiscHelperFuncs.AngleBetweenVector2(currentEncounter.GravElements.Eccentricity, shipPredictedLocalPosition); encounters[encounters.Count - 1].EndingTrueAnomaly = endingTrueAnomaly; if (iterations < MAX_ITERATIONS) { GameObject tempPerigeeIcon = Instantiate(perigeeIcon); OrbitalPOI perigeePOI = new OrbitalPOI(tempPerigeeIcon, newShipsGravityElements.Perigee); Encounter newEncounter = new Encounter(newShipsGravityElements, startingTrueAnomaly, double.PositiveInfinity, time + currentEncounter.TimeOfEncounter, perigeePOI); predictAnEncounter(newEncounter, ref encounters); } }