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