예제 #1
0
        public Vector3d calculateVelocity(double timeEpoch, CelestialBody relativeTo, bool isFromDelta)
        {
            if (orbitalElements == null)
            {
                return(new Vector3d(0, 0, 0));
            }

            var eclipticVelocity = new Vector3d();

            if (isFromDelta)
            {
                Vector3d pos1 = calculatePosition(timeEpoch);
                Vector3d pos2 = calculatePosition(timeEpoch + 60);
                eclipticVelocity = (pos2 - pos1) * (1.0 / 60.0);
            }
            else
            {
                //vis viva to calculate speed (not velocity, i.e not a vector)
                OrbitalElementsPieces el = calculateElements(timeEpoch);
                double speed             = Math.Sqrt(SO.G * SO.U.getBody(relativeTo).mass *((2.0 / (el.r.Value)) - (1.0 / (el.a.Value))));

                //now calculate velocity orientation, that is, a vector tangent to the orbital ellipse
                double?k = el.r / el.a;
                double?o = ((2 - (2 * el.e * el.e)) / (k * (2 - k))) - 1;
                //floating point imprecision
                o = o > 1 ? 1 : o;
                double alpha = Math.PI - Math.Acos(o.Value);
                alpha = el.v < 0 ? (2 * Math.PI) - alpha : alpha;
                double velocityAngle = el.v.Value + (alpha / 2);
                //velocity vector in the plane of the orbit
                Vector3d orbitalVelocity          = new Vector3d(Math.Cos(velocityAngle), Math.Sin(velocityAngle), 0).normalized *speed;
                OrbitalElementsPieces velocityEls = el.Copy();
                velocityEls.pos  = orbitalVelocity;
                velocityEls.v    = 0;
                velocityEls.r    = 0;
                eclipticVelocity = getPositionFromElements(velocityEls);
            }

            //var diff = eclipticVelocityFromDelta.sub(eclipticVelocity);console.log(diff.length());
            return(eclipticVelocity);
        }
예제 #2
0
        public OrbitalElementsPieces calculateElements(double timeEpoch, OrbitalElementsPieces forcedOrbitalElements = null)
        {
            if (forcedOrbitalElements == null && this.orbitalElements == null)
            {
                return(null);
            }

/*        Debug.Log(this.name);
 *
 *      Debug.Log(this.orbitalElements);
 *      Debug.Log(this.orbitalElements.cy);*/

            OrbitalElementsPieces orbitalElements = forcedOrbitalElements ?? this.orbitalElements;

            /*
             *
             *                  Epoch : J2000
             *
             *                  a   Semi-major axis
             *              e   Eccentricity
             *              i   Inclination
             *              o   Longitude of Ascending Node (Ω)
             *              w   Argument of periapsis (ω)
             *                  E   Eccentric Anomaly
             *              T   Time at perihelion
             *              M	Mean anomaly
             *              l   Mean Longitude
             *              lp	longitude of periapsis
             *              r	distance du centre
             *              v	true anomaly
             *
             *              P	Sidereal period (mean value)
             *                  Pw	Argument of periapsis precession period (mean value)
             *                  Pn	Longitude of the ascending node precession period (mean value)
             *
             */
            if (epochCorrection.HasValue)
            {
                timeEpoch -= epochCorrection.Value;
            }
            double tDays = timeEpoch / SO.DAY;
            double T     = tDays / SO.CENTURY;
            //console.log(T);
            var computed = new OrbitalElementsPieces();

            computed.t = timeEpoch;

            if (calculator != null && forcedOrbitalElements == null)
            {
                OrbitalElementsPieces realorbit = calculator(T);
                computed = realorbit.Copy();
            }
            else
            {
                if (orbitalElements.baseElements != null)
                {
                    double variation = 0.0;

                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("a"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("e"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("i"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("l"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("lp"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("o"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("E"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("M"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("r"), computed, T);
                    //CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("t"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("v"), computed, T);
                    CalculateVariation(orbitalElements, orbitalElements.GetType().GetField("w"), computed, T);

/*
 *                                                      variation = orbitalElements.cy ? orbitalElements.cy[el] : (orbitalElements.day[el] * ns.CENTURY);
 *                                                      variation = variation || 0;
 *                                                      computed[el] = orbitalElements.base[el] + (variation * T);
 */

                    // Bomb
                }
                else
                {
                    computed = orbitalElements.Copy();
                }

                if (!computed.w.HasValue)
                {
                    computed.w = computed.lp - computed.o;
                }

                if (!computed.M.HasValue)
                {
                    computed.M = computed.l - computed.lp;
                }

                computed.a = computed.a * SO.KM; //was in km, set it in m
            }


            computed.i = SO.DEG_TO_RAD * computed.i;
            computed.o = SO.DEG_TO_RAD * computed.o;
            computed.w = SO.DEG_TO_RAD * computed.w;
            computed.M = SO.DEG_TO_RAD * computed.M;

            computed.E = solveEccentricAnomaly(computed.e.Value, computed.M.Value);

            computed.E = computed.E % SO.CIRCLE;
            computed.i = computed.i % SO.CIRCLE;
            computed.o = computed.o % SO.CIRCLE;
            computed.w = computed.w % SO.CIRCLE;
            computed.M = computed.M % SO.CIRCLE;

            //in the plane of the orbit
            computed.pos = new Vector3d((computed.a * (Math.Cos(computed.E.Value) - computed.e.Value)).Value,
                                        (computed.a.Value * (Math.Sqrt(1 - (computed.e.Value * computed.e.Value))) * Math.Sin(computed.E.Value)));

            computed.r = computed.pos.magnitude;
            computed.v = Math.Atan2(computed.pos.y, computed.pos.x);
            if (orbitalElements.relativeTo != null)
            {
                var relativeTo = SO.U.getBody(orbitalElements.relativeTo);
                if (relativeTo.tilt.HasValue)
                {
                    computed.tilt = -relativeTo.tilt.Value * SO.DEG_TO_RAD;
                }
            }

            return(computed);
        }