private void ComputeOrbital(RenderContext11 renderContext)
        {
            CAAEllipticalObjectElements ee = Elements;
            Vector3d point = CAAElliptical.CalculateRectangular(SpaceTimeController.JNow, ee, out MeanAnomoly);

            Vector3d pointInstantLater = CAAElliptical.CalculateRectangular(ee, MeanAnomoly + .001);

            Vector3d direction = point - pointInstantLater;

            direction.Normalize();
            Vector3d up = point;
            up.Normalize();
            direction.Normalize();

            double dist = point.Length();
            double scaleFactor = 1.0;
            switch (SemiMajorAxisUnits)
            {
                case AltUnits.Meters:
                    scaleFactor = 1.0;
                    break;
                case AltUnits.Feet:
                    scaleFactor = 1.0 / 3.2808399;
                    break;
                case AltUnits.Inches:
                    scaleFactor = (1.0 / 3.2808399) / 12;
                    break;
                case AltUnits.Miles:
                    scaleFactor = 1609.344;
                    break;
                case AltUnits.Kilometers:
                    scaleFactor = 1000;
                    break;
                case AltUnits.AstronomicalUnits:
                    scaleFactor = UiTools.KilometersPerAu * 1000;
                    break;
                case AltUnits.LightYears:
                    scaleFactor = UiTools.AuPerLightYear * UiTools.KilometersPerAu * 1000;
                    break;
                case AltUnits.Parsecs:
                    scaleFactor = UiTools.AuPerParsec * UiTools.KilometersPerAu * 1000;
                    break;
                case AltUnits.MegaParsecs:
                    scaleFactor = UiTools.AuPerParsec * UiTools.KilometersPerAu * 1000 * 1000000;
                    break;
                case AltUnits.Custom:
                    scaleFactor = 1;
                    break;
                default:
                    break;
            }
            scaleFactor *= 1 / renderContext.NominalRadius;

            Matrix3d look = Matrix3d.LookAtLH(new Vector3d(0, 0, 0), direction, up);
            look.Invert();

            WorldMatrix = Matrix3d.Identity;
            WorldMatrix.Translate(Translation);

            double localScale = (1 / renderContext.NominalRadius) * Scale * MeanRadius;
            WorldMatrix.Scale(new Vector3d(localScale, localScale, localScale));
            WorldMatrix.Rotate(Quaternion.RotationYawPitchRoll((float)((Heading) / 180.0 * Math.PI), (float)(Pitch / 180.0 * Math.PI), (float)(Roll / 180.0 * Math.PI)));
            if (RotationalPeriod != 0)
            {
                double rotationCurrent = (((SpaceTimeController.JNow - this.ZeroRotationDate) / RotationalPeriod) * Math.PI * 2) % (Math.PI * 2);
                WorldMatrix.Multiply(Matrix3d.RotationX(-rotationCurrent));
            }

            point = Vector3d.Scale(point, scaleFactor);

            WorldMatrix.Translate(point);

            if (StationKeeping)
            {
                WorldMatrix = look * WorldMatrix;
            }
        }
        private void ComputeFrameTrajectory(RenderContext11 renderContext)
        {
            Vector3d vector = new Vector3d();
            Vector3d point = GetTragectoryPoint(SpaceTimeController.JNow, out vector);

            Vector3d direction = vector;

            direction.Normalize();
            Vector3d up = point;
            up.Normalize();
            direction.Normalize();

            double dist = point.Length();
            double scaleFactor = 1.0;
            //scaleFactor = UiTools.KilometersPerAu * 1000;
            scaleFactor *= 1 / renderContext.NominalRadius;

            Matrix3d look = Matrix3d.LookAtLH(new Vector3d(0, 0, 0), direction, new Vector3d(0, 1, 0));
            look.Invert();

            WorldMatrix = Matrix3d.Identity;
            WorldMatrix.Translate(Translation);
            double localScale = (1 / renderContext.NominalRadius) * Scale * MeanRadius;
            WorldMatrix.Scale(new Vector3d(localScale, localScale, localScale));
            WorldMatrix.Rotate(Quaternion.RotationYawPitchRoll((float)((Heading) / 180.0 * Math.PI), (float)(Pitch / 180.0 * Math.PI), (float)(Roll / 180.0 * Math.PI)));
            if (RotationalPeriod != 0)
            {
                double rotationCurrent = (((SpaceTimeController.JNow - this.ZeroRotationDate) / RotationalPeriod) * Math.PI * 2) % (Math.PI * 2);
                WorldMatrix.Multiply(Matrix3d.RotationX(-rotationCurrent));
            }

            point = Vector3d.Scale(point, scaleFactor);

            WorldMatrix.Translate(point);

            if (StationKeeping)
            {
                WorldMatrix = look * WorldMatrix;
            }
        }
        private void ComputeFixedSherical(RenderContext11 renderContext)
        {
            if (ObservingLocation)
            {
                Lat = SpaceTimeController.Location.Lat;
                Lng = SpaceTimeController.Location.Lng;
                Altitude = SpaceTimeController.Altitude;
            }

            WorldMatrix = Matrix3d.Identity;
            WorldMatrix.Translate(Translation);
            double localScale = (1 / renderContext.NominalRadius) * Scale * MeanRadius;
            WorldMatrix.Scale(new Vector3d(localScale, localScale, localScale));
            //WorldMatrix.Scale(new Vector3d(1000, 1000, 1000));
            WorldMatrix.Rotate(Quaternion.RotationYawPitchRoll((float)((Heading) / 180.0 * Math.PI), (float)(Pitch / 180.0 * Math.PI), (float)(Roll / 180.0 * Math.PI)));
            WorldMatrix.Multiply(Matrix3d.RotationZ(-90.0 / 180.0 * Math.PI));
            if (RotationalPeriod != 0)
            {
                double rotationCurrent = (((SpaceTimeController.JNow - this.ZeroRotationDate) / RotationalPeriod) * Math.PI * 2) % (Math.PI * 2);
                WorldMatrix.Multiply(Matrix3d.RotationX(-rotationCurrent));
            }
            WorldMatrix.Translate(new Vector3d(1 + (Altitude / renderContext.NominalRadius), 0, 0));
            WorldMatrix.Multiply(Matrix3d.RotationZ(Lat / 180 * Math.PI));
            WorldMatrix.Multiply(Matrix3d.RotationY(-(Lng) / 180 * Math.PI));
        }
        private void ComputeFrameSynodic(RenderContext11 renderContext)
        {
            // A synodic frame is a rotating frame of reference in which
            // the x-axis is the direction between the bodies in a two-body
            // system. The origin is at the secondary body, and +x points
            // in the direction opposite the primary. The z-axis is in the orbital
            // plane and normal to x; it points in the direction of the instantaneous
            // orbital velocity of the secondary.

            // The origin is offset by then translation. The five libration points in a
            // two-body system can be approximated by choosing different offsets. For
            // example, the Sun-Earth L2 point is approximated by using x = 1,500,000 km, y = 0 and z = 0.

            WorldMatrix = Matrix3d.Identity;
            double localScale = (1 / renderContext.NominalRadius) * Scale * MeanRadius;
            WorldMatrix.Scale(new Vector3d(localScale, localScale, localScale));
            WorldMatrix.Rotate(Quaternion.RotationYawPitchRoll((float)((Heading) / 180.0 * Math.PI), (float)(Pitch / 180.0 * Math.PI), (float)(Roll / 180.0 * Math.PI)));
            WorldMatrix.Translate(Translation / 6371.000);

            // Currently we assume the Sun-Earth system
            double jd = SpaceTimeController.JNow;
            double B = CAACoordinateTransformation.DegreesToRadians(CAAEarth.EclipticLatitude(jd));
            double L = CAACoordinateTransformation.DegreesToRadians(CAAEarth.EclipticLongitude(jd));
            Vector3d eclPos = new Vector3d(Math.Cos(L) * Math.Cos(B), Math.Sin(L) * Math.Cos(B), Math.Sin(B));

            // Just approximate the orbital velocity for now
            Vector3d eclVel = Vector3d.Cross(eclPos, new Vector3d(0.0, 0.0, 1.0));
            eclVel.Normalize();

            // Convert to WWT's coordinate convention by swapping Y and Z
            eclPos = new Vector3d(eclPos.X, eclPos.Z, eclPos.Y);
            eclVel = new Vector3d(eclVel.X, eclVel.Z, eclVel.Y);

            Vector3d xaxis = eclPos;
            Vector3d yaxis = Vector3d.Cross(eclVel, eclPos);
            Vector3d zaxis = eclVel;
            Matrix3d rotation = new Matrix3d(xaxis.X, yaxis.X, zaxis.X, 0, xaxis.Y, yaxis.Y, zaxis.Y, 0, xaxis.Z, yaxis.Z, zaxis.Z, 0, 0, 0, 0, 1);

            // Convert from ecliptic to J2000 EME (equatorial) system
            double earthObliquity = CAACoordinateTransformation.DegreesToRadians(Coordinates.MeanObliquityOfEcliptic(jd));
            rotation = rotation * Matrix3d.RotationX(-earthObliquity);

            WorldMatrix.Multiply(rotation);
        }
 private void ComputeFixedRectangular(RenderContext11 renderContext)
 {
     WorldMatrix = Matrix3d.Identity;
     WorldMatrix.Translate(Translation);
     WorldMatrix.Rotate(Quaternion.RotationYawPitchRoll((float)((Heading) / 180.0 * Math.PI), (float)(Pitch / 180.0 * Math.PI), (float)(Roll / 180.0 * Math.PI)));
     WorldMatrix.Scale(new Vector3d(Scale, Scale, Scale));
     WorldMatrix.Rotate(Quaternion.RotationYawPitchRoll((float)(Coordinates.MstFromUTC2(SpaceTimeController.Now, 0) / 180 * Math.PI), (float)0, (float)0));
 }