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);
        }