Exemplo n.º 1
0
    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);
    }
Exemplo n.º 2
0
    //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);
        }
    }