void OnPostRender() { //vertices = new List<Vector2>(); if (!mat) { Debug.Log("Mat null"); return; } mat.SetPass(0); GL.PushMatrix(); GL.Begin(GL.LINES); for (int i = 0; i < vertices.Count; i += 2) { GL.Color(vertices[i].Key); GL.Vertex(MiscHelperFuncs.convertToVec3(vertices[i].Value) + new Vector3(0, 0, 1f)); GL.Vertex(MiscHelperFuncs.convertToVec3(vertices[i + 1].Value) + new Vector3(0, 0, 1f)); } GL.End(); GL.PopMatrix(); //Debug.Log(1.0/Time.deltaTime); //clear vertices //vertices = new List<Vector2>(); }
//<summary> //Determines whether or not to change the sphere of influence then changes it //</summary> //<param name="position"> The position of the ship in global coordinates //<param name="velocity"> The velocity relative to the current body being orbited //<param name="the rest"> F**k it you get the idea //<returns> Returns nothing, like anyone who went to blockbuster after netflix got big private void changeSpheresOfInfluence(Vector2 position, Vector2 velocity, GameObject currentMassiveBody) { GameObject newSphereOfInfluence = findInfluencingCelestialBody(position, velocity, currentMassiveBody); //change spheres of influence if (newSphereOfInfluence.transform.GetInstanceID() != currentMassiveBody.transform.GetInstanceID() && sphereChangeImmunity < 1) { //From small to big if (newSphereOfInfluence.GetComponent <MassiveBodyElements>().massiveBodyType > currentMassiveBody.GetComponent <MassiveBodyElements>().massiveBodyType) { gravityElements.massiveBody = newSphereOfInfluence; calculateInitialOrbitalElements(position - MiscHelperFuncs.convertToVec2(newSphereOfInfluence.transform.position), velocity + currentMassiveBody.GetComponent <GravityElements>().velocity); sphereChangeImmunity = 10; shipPatchedConics.updateEncounters(); } else //big to small { gravityElements.massiveBody = newSphereOfInfluence; calculateInitialOrbitalElements(position - MiscHelperFuncs.convertToVec2(newSphereOfInfluence.transform.position), velocity - newSphereOfInfluence.GetComponent <GravityElements>().velocity); sphereChangeImmunity = 10; shipPatchedConics.updateEncounters(); } } else { sphereChangeImmunity--; } }
public void hover(Vector2 mouseLocation) { this.mouseLocation = mouseLocation - MiscHelperFuncs.convertToVec2(shipElements.massiveBody.transform.position); mouseAltitude = this.mouseLocation.magnitude; mouseTrueAnomaly = Math.Atan2(this.mouseLocation.y, this.mouseLocation.x) - Math.Atan2(shipElements.Eccentricity.y, shipElements.Eccentricity.x); if (mouseTrueAnomaly > Math.PI) { mouseTrueAnomaly -= 2 * Math.PI; } orbitalAltitude = OrbitalHelper.calculateAltitude(shipElements.Eccentricity, shipElements.SemiMajorAxis, shipElements.SemiLatusRectum, mouseTrueAnomaly, shipElements.OrbitType); if (mouseAltitude > orbitalAltitude - hoverDistanceTolerance && mouseAltitude < orbitalAltitude + hoverDistanceTolerance && !dragging) { hovering = true; } else { hovering = false; } //Debugging if ((mouseTrueAnomaly > Math.PI || mouseTrueAnomaly < -Math.PI) && shipElements.OrbitType == OrbitTypes.elliptical) { //Debug.Break(); //Debug.LogWarning("ERROR, mouse true anomaly out of bounds"); /*Debug.Log("NODE"); * Debug.Log("Position: " + mouseLocation); * Debug.Log("True Anomaly: " + mouseTrueAnomaly); * Debug.Log("Thrust: " + "heehee");*/ } }
private Vector2 drawOrbitRadiusHelper(Vector2 eccentricity, double globalRotationAngle, double semiMajorAxis, double trueAnomaly) { trueAnomaly = MiscHelperFuncs.convertTo360Angle(trueAnomaly); double radius = (semiMajorAxis * (1 - eccentricity.sqrMagnitude)) / (1 + (eccentricity.magnitude * Math.Cos(trueAnomaly))); return((float)radius * new Vector2((float)Math.Cos(trueAnomaly + globalRotationAngle), (float)Math.Sin(trueAnomaly + globalRotationAngle))); }
public static double convertToWorldAngle(double localAngle, double globalRotationAngle, bool towardsPerigee) { if (towardsPerigee) { if (globalRotationAngle < 0) { localAngle = Math.Abs(localAngle) - Math.Abs(globalRotationAngle); } else { localAngle = Math.Abs(globalRotationAngle) - Math.Abs(localAngle); } } else { if (globalRotationAngle < 0) { localAngle = Math.Abs((2 * Math.PI) - Math.Abs(globalRotationAngle) - Math.Abs(localAngle)); } else { localAngle = -Math.Abs((2 * Math.PI) - globalRotationAngle - localAngle); } } localAngle = MiscHelperFuncs.wrapAngle(localAngle); return(localAngle); }
public static bool clockwiseOrbit(Vector2 position, Vector2 velocity) { Vector3 crossProduct; crossProduct = Vector3.Cross(MiscHelperFuncs.convertToVec3(position), MiscHelperFuncs.convertToVec3(velocity)); if (crossProduct.z > 0) { return(false); } return(true); }
void FixedUpdate() { //detect soi change if (currentMassiveBody.name != shipElements.massiveBody.name) { deleteNode(); } //Have we arrived at a node? if (node != null) { //Is the ship moving clockwise? if (shipElements.Clockwise) { //TODO implement edge case when crossing over 0 if (MiscHelperFuncs.convertTo360Angle(shipElements.TrueAnomaly) < MiscHelperFuncs.convertTo360Angle(node.getTrueAnomaly()) && MiscHelperFuncs.convertTo360Angle(lastTrueAnomaly) > MiscHelperFuncs.convertTo360Angle(node.getTrueAnomaly())) { executeManeuver(); } } else { if (MiscHelperFuncs.convertTo360Angle(shipElements.TrueAnomaly) > MiscHelperFuncs.convertTo360Angle(node.getTrueAnomaly()) && MiscHelperFuncs.convertTo360Angle(lastTrueAnomaly) < MiscHelperFuncs.convertTo360Angle(node.getTrueAnomaly())) { executeManeuver(); } } } //position maneuver node if (node != null) { positionNode(); } else { nodeButton.transform.localScale = new Vector3(0, 0, 0); nodePlacard.transform.localScale = new Vector3(0, 0, 0); thrustVectorHandle.transform.localScale = new Vector3(0, 0, 0); } //Determine thrust vector if (dragging) { thrustVector = MiscHelperFuncs.convertToVec2(Camera.main.ScreenToWorldPoint(Input.mousePosition)) - (node.getNodePosition() + shipElements.GlobalTransformationVector); } //do something lastTrueAnomaly = shipElements.TrueAnomaly; }
//<summary> //Takes in everything in global coordinates (relative to the origin(0, 0)) and returns the game object that is influencing the craft //</summary> //<param name="position"> Re-read the summary //<param name="asdf"> Here's to the little guys private GameObject findInfluencingCelestialBody(Vector2 position, Vector2 velocity, GameObject currentMassiveBody) { GameObject[] massiveBodies = GameObject.FindGameObjectsWithTag("MassiveBody"); List <GameObject> spheresOfInfluence = new List <GameObject>(); for (int i = 0; i < massiveBodies.Length; i++) { //quick and dirty calculation of altitude double mu = massiveBodies[i].GetComponent <MassiveBodyElements>().mass *GlobalElements.GRAV_CONST; Vector2 relativePosition = position - MiscHelperFuncs.convertToVec2(massiveBodies[i].transform.position); Vector2 relativeVelocity = velocity + massiveBodies[i].GetComponent <GravityElements>().velocity; Vector2 eccentricity = OrbitalHelper.calculateEccentricity(relativePosition, relativeVelocity, mu); OrbitTypes orbitType = OrbitalHelper.determineOrbitType(eccentricity); double mechanicalEnergy = OrbitalHelper.calculateMechanicalEnergy(relativePosition, relativeVelocity, mu, orbitType); double semiMajorAxis = OrbitalHelper.calculateSemiMajorAxis(mechanicalEnergy, mu, orbitType); Vector2 perigee = OrbitalHelper.calculatePerigee(semiMajorAxis, eccentricity, orbitType); double semiLatusRectum = OrbitalHelper.calculateSemiLatusRectum(semiMajorAxis, eccentricity, perigee, orbitType); //semiMajorAxis * (1 - Math.Pow(eccentricity.magnitude, 2)); double trueAnomaly = Vector2.Angle(relativePosition, eccentricity); trueAnomaly = MiscHelperFuncs.convertToRadians(trueAnomaly); trueAnomaly = Math.Abs(MiscHelperFuncs.wrapAngle(trueAnomaly)); double altitude = Vector2.Distance(massiveBodies[i].transform.position, transform.position);//semiLatusRectum / (1 + eccentricity.magnitude * Math.Cos(trueAnomaly)); if (massiveBodies[i].GetComponent <MassiveBodyElements>().SphereOfInfluence > altitude && massiveBodies[i].transform.GetInstanceID() != this.transform.GetInstanceID()) { if (altitude < 0) { Debug.Log("altitude: " + altitude); Debug.Log("semilatusrectum: " + semiLatusRectum); Debug.Log("Eccentricity: " + eccentricity.magnitude); Debug.Log("true anomaly: " + trueAnomaly); } spheresOfInfluence.Add(massiveBodies[i]); } } double smallestDistance = double.PositiveInfinity; GameObject returnGameObject = currentMassiveBody; foreach (GameObject massiveBody in spheresOfInfluence) { double distance = Vector2.Distance(massiveBody.transform.position, transform.position); if (distance < smallestDistance) { smallestDistance = distance; returnGameObject = massiveBody; } } return(returnGameObject); }
public static bool towardsPerigeeOrbit(Vector2 velocity, Vector2 eccentricity, OrbitTypes orbitType) { switch (orbitType) { case OrbitTypes.circular: return(MiscHelperFuncs.convertToRadians(Vector2.Angle(Vector2.right, velocity)) < Math.PI / 2); case OrbitTypes.elliptical: return(MiscHelperFuncs.convertToRadians(Vector2.Angle(eccentricity, velocity)) < Math.PI / 2); case OrbitTypes.parabolic: return(true); case OrbitTypes.hyperbolic: return(MiscHelperFuncs.convertToRadians(Vector2.Angle(eccentricity, velocity)) < Math.PI / 2); } return(true); }
public static double calculateMeanAnomaly(Vector2 eccentricity, double semiMajorAxis, double anomalyAtEpoch, double timeStep, double timeAtEpoch, bool clockwise, double mu, OrbitTypes orbitType) { double orbitalSpeed; double returnMeanAnomaly = double.PositiveInfinity; //Calculate percentage of orbit being crossed orbitalSpeed = Math.Sqrt((mu) / Math.Pow(Math.Abs(semiMajorAxis), 3)); if (clockwise) { returnMeanAnomaly = anomalyAtEpoch - (orbitalSpeed * timeStep); } else { returnMeanAnomaly = anomalyAtEpoch + (orbitalSpeed * timeStep); } if (orbitType != OrbitTypes.hyperbolic && orbitType != OrbitTypes.parabolic) { returnMeanAnomaly = MiscHelperFuncs.wrapAngle(returnMeanAnomaly); } return(returnMeanAnomaly); }
private void positionNode() { //position node float width = nodePlacard.rectTransform.rect.width * nodePlacard.transform.localScale.x; float height = nodePlacard.rectTransform.rect.height * nodePlacard.transform.localScale.y; double trueAnomaly = MiscHelperFuncs.AngleBetweenVector2(shipElements.Eccentricity, node.getNodePosition()); if (trueAnomaly > Math.PI) { trueAnomaly -= 2 * Math.PI; } bool towardsPerigeeOrbit; if (trueAnomaly < 0) { if (shipElements.Clockwise) { towardsPerigeeOrbit = false; } else { towardsPerigeeOrbit = true; } } else { if (shipElements.Clockwise) { towardsPerigeeOrbit = true; } else { towardsPerigeeOrbit = false; } } double velocityAngle = OrbitalHelper.calculateVelocityAngle(node.getNodePosition(), shipElements.Eccentricity, shipElements.SemiMajorAxis, trueAnomaly, shipElements.GlobalRotationAngle, shipElements.Clockwise, towardsPerigeeOrbit, shipElements.OrbitType); Vector2 offsetVector; if (shipElements.Clockwise) { offsetVector = OrbitalHelper.assembleVelocityVector(velocityAngle + Math.PI / 2, 1).normalized * Mathf.Sqrt(Mathf.Pow(width / 2, 2) + Mathf.Pow(height / 2, 2)); } else { offsetVector = OrbitalHelper.assembleVelocityVector(velocityAngle - Math.PI / 2, 1).normalized * Mathf.Sqrt(Mathf.Pow(width / 2, 2) + Mathf.Pow(height / 2, 2)); } nodeButton.transform.position = node.getNodePosition() + offsetVector + shipElements.GlobalTransformationVector; nodeButton.transform.localScale = new Vector3(GlobalElements.zoomLevel / GlobalElements.UI_SCALE_CONST, GlobalElements.zoomLevel / GlobalElements.UI_SCALE_CONST, 0); nodePlacard.transform.position = node.getNodePosition() + offsetVector + shipElements.GlobalTransformationVector; nodePlacard.transform.localScale = new Vector3(GlobalElements.zoomLevel / GlobalElements.UI_SCALE_CONST, GlobalElements.zoomLevel / GlobalElements.UI_SCALE_CONST, 0); nodePlacard.transform.rotation = Quaternion.AngleAxis(Mathf.Atan2(offsetVector.y, offsetVector.x) * Mathf.Rad2Deg - 45, Vector3.forward); thrustVectorHandle.transform.position = node.getNodePosition() + shipElements.GlobalTransformationVector + thrustVector; thrustVectorHandle.transform.localScale = new Vector3(GlobalElements.zoomLevel / GlobalElements.UI_SCALE_CONST / 2, GlobalElements.zoomLevel / GlobalElements.UI_SCALE_CONST / 2, 0); lineDrawer.DrawLine(node.getNodePosition() + shipElements.GlobalTransformationVector, node.getNodePosition() + shipElements.GlobalTransformationVector + thrustVector, Color.red); }
//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); } }
// Update is called once per frame void FixedUpdate() { //Display Patched Conics float angle = 0; while (angle < 2 * Math.PI) { lineDrawer.DrawLine(drawOrbitRadiusHelper(gravElements.Eccentricity, gravElements.GlobalRotationAngle, gravElements.SemiMajorAxis, angle) + gravElements.GlobalTransformationVector, drawOrbitRadiusHelper(gravElements.Eccentricity, gravElements.GlobalRotationAngle, gravElements.SemiMajorAxis, angle + 0.01f) + gravElements.GlobalTransformationVector, patchedConicsColor); angle += 0.01f; } //Display SOI angle = 0; while (angle <= 2 * Math.PI) { Vector2 dirVec1 = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)); dirVec1.Normalize(); dirVec1 *= (float)massiveElements.SphereOfInfluence; angle += 0.01f; Vector2 dirVec2 = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)); dirVec2.Normalize(); dirVec2 *= (float)massiveElements.SphereOfInfluence; lineDrawer.DrawLine(dirVec1 + MiscHelperFuncs.convertToVec2(transform.position), dirVec2 + MiscHelperFuncs.convertToVec2(transform.position), patchedConicsColor); } /** * Messy and unnecessary, i might bring it back though */ //Display Orbital POI /*float width = perigeePlacard.rectTransform.rect.width * perigeePlacard.transform.localScale.x; * float height = perigeePlacard.rectTransform.rect.height * perigeePlacard.transform.localScale.y; * Vector2 offsetVector = gravElements.Perigee.normalized * * Mathf.Sqrt(Mathf.Pow(width / 2, 2) + Mathf.Pow(height / 2, 2)); * * perigeeButton.transform.position = gravElements.GlobalTransformationVector + gravElements.Perigee + offsetVector; * perigeeButton.transform.localScale = new Vector3(GlobalElements.zoomLevel / UI_SCALE_CONST, GlobalElements.zoomLevel / UI_SCALE_CONST, 0); * * perigeePlacard.transform.position = gravElements.GlobalTransformationVector + gravElements.Perigee + offsetVector; * perigeePlacard.transform.localScale = new Vector3(GlobalElements.zoomLevel / UI_SCALE_CONST, GlobalElements.zoomLevel / UI_SCALE_CONST, 0); * perigeePlacard.transform.rotation = Quaternion.AngleAxis(Mathf.Atan2(gravElements.Perigee.y, gravElements.Perigee.x) * Mathf.Rad2Deg - 45, Vector3.forward); * * switch (gravElements.OrbitType) * { * case OrbitTypes.circular: * apogeeButton.transform.position = gravElements.GlobalTransformationVector + gravElements.Apogee - offsetVector; * apogeeButton.transform.localScale = new Vector3(GlobalElements.zoomLevel / UI_SCALE_CONST, GlobalElements.zoomLevel / UI_SCALE_CONST, 0); * * apogeePlacard.transform.position = gravElements.GlobalTransformationVector + gravElements.Apogee - offsetVector; * apogeePlacard.transform.localScale = new Vector3(GlobalElements.zoomLevel / UI_SCALE_CONST, GlobalElements.zoomLevel / UI_SCALE_CONST, 0); * apogeePlacard.transform.rotation = Quaternion.AngleAxis(Mathf.Atan2(gravElements.Apogee.y, gravElements.Apogee.x) * Mathf.Rad2Deg - 45, Vector3.forward); * break; * case OrbitTypes.elliptical: * apogeeButton.transform.position = gravElements.GlobalTransformationVector + gravElements.Apogee - offsetVector; * apogeeButton.transform.localScale = new Vector3(GlobalElements.zoomLevel / UI_SCALE_CONST, GlobalElements.zoomLevel / UI_SCALE_CONST, 0); * * apogeePlacard.transform.position = gravElements.GlobalTransformationVector + gravElements.Apogee - offsetVector; * apogeePlacard.transform.localScale = new Vector3(GlobalElements.zoomLevel / UI_SCALE_CONST, GlobalElements.zoomLevel / UI_SCALE_CONST, 0); * apogeePlacard.transform.rotation = Quaternion.AngleAxis(Mathf.Atan2(gravElements.Apogee.y, gravElements.Apogee.x) * Mathf.Rad2Deg - 45, Vector3.forward); * break; * default: * apogeePlacard.transform.localScale = new Vector3(0, 0, 0); * apogeeButton.transform.localScale = new Vector3(0, 0, 0); * break; * * }*/ }
public static double calculateTrueAnomaly(Vector2 eccentricity, Vector2 position, bool towardsPerigee, bool clockwise, OrbitTypes orbitType) { double returnTrueAnomaly = double.PositiveInfinity; switch (orbitType) { case OrbitTypes.circular: returnTrueAnomaly = Vector2.Angle(position, Vector2.right); returnTrueAnomaly = MiscHelperFuncs.convertToRadians(returnTrueAnomaly); break; case OrbitTypes.elliptical: returnTrueAnomaly = Vector2.Angle(eccentricity, position); returnTrueAnomaly = MiscHelperFuncs.convertToRadians(returnTrueAnomaly); if (clockwise) //Copied this section from the hyperbolic section, I havent fully tested it but it looks ok { // if (towardsPerigee) // { returnTrueAnomaly = Math.Abs(returnTrueAnomaly); // } else { returnTrueAnomaly = -Math.Abs(returnTrueAnomaly); // } } else { if (towardsPerigee) { returnTrueAnomaly = -Math.Abs(returnTrueAnomaly); // } else { returnTrueAnomaly = Math.Abs(returnTrueAnomaly); // } } //End break; case OrbitTypes.parabolic: break; case OrbitTypes.hyperbolic: returnTrueAnomaly = Vector2.Angle(eccentricity, position); returnTrueAnomaly = MiscHelperFuncs.convertToRadians(returnTrueAnomaly); if (clockwise) { if (towardsPerigee) { returnTrueAnomaly = Math.Abs(returnTrueAnomaly); } else { returnTrueAnomaly = -Math.Abs(returnTrueAnomaly); } } else { if (towardsPerigee) { returnTrueAnomaly = -Math.Abs(returnTrueAnomaly); } else { returnTrueAnomaly = Math.Abs(returnTrueAnomaly); } } break; } return(returnTrueAnomaly); }