Exemplo n.º 1
0
        internal static Vector3.Vector RotateVector3(
            QuaternionRec RotationQ,
            QuaternionRec InverseRotationQ,
            Vector3.Vector StartPoint)
        {
            // A quaternion rotation is clockwise around a vector
            // if you are looking down the vector from the origin point.
            // Like an archer with an arrow in the bow, you are sighting
            // down the arrow.
            // Compare this with representing a rotation or a moment
            // of inertia, or a torque, by using a vector cross product
            // in a right-handed coordinate system.  It goes in the
            // right direction like it should.  If the Z axis is pointing
            // straight toward you then it is the opposite
            // point of view from what an archer would see when he
            // is sighting down an arrow in his bow.  That opposite
            // point of view is a counter-clockwise rotation.


            QuaternionRec MiddlePoint = MultiplyWithLeftVector3(
                StartPoint, InverseRotationQ);

            Vector3.Vector Result = MultiplyWithResultVector3(
                RotationQ, MiddlePoint);
            return(Result);
        }
Exemplo n.º 2
0
 internal void SetNextPositionFromVelocity(
     double TimeDelta)
 {
     Vector3.Vector MoveBy = Velocity;
     // It moves by this much in TimeDelta time.
     MoveBy   = Vector3.MultiplyWithScalar(MoveBy, TimeDelta);
     Position = Vector3.Add(Position, MoveBy);
 }
Exemplo n.º 3
0
        internal int MakeSurfaceVertexRow(
            double ApproxLatitude,
            double LongitudeHoursRadians,
            int GraphicsIndex)
        {
            try
            {
                SetupReferenceVertexes(ApproxLatitude,
                                       LongitudeHoursRadians);

                if (LatLonRowLast < 2)
                {
                    return(MakeSurfacePoleRow(ApproxLatitude,
                                              GraphicsIndex));
                }

                double LonStart = -180.0;

                // There is a beginning vertex at -180 longitude
                // and there is an ending vertex at 180
                // longitude, which is the same place, but they
                // are associated with different texture
                // coordinates.  One at the left end of the
                // texture and one at the right end.
                // So this is minus 1:
                double LonDelta = 360.0d / (double)(LatLonRowLast - 1);

                for (int Count = 0; Count < LatLonRowLast; Count++)
                {
                    Vector3.Vector Position = RefVertexArray[0].
                                              GetPosition(Count);

                    LatLongPosition Pos = new LatLongPosition();

                    Pos.GraphicsIndex = GraphicsIndex;
                    GraphicsIndex++;

                    Pos.Longitude = LonStart + (LonDelta * Count);
                    SetLatLonValues(ref Pos);
                    LatLonRow[Count] = Pos;
                }

                return(GraphicsIndex);
            }
            catch (Exception Except)
            {
                ShowStatus("Exception in EarthSlice.MakeVertexRow(): " + Except.Message);
                return(-1);
            }
        }
Exemplo n.º 4
0
        internal void DoEarthTiltRotations(
            ref Vector3.Vector[] InArray)
        {
            int Last = InArray.Length;

            for (int Count = 0; Count < Last; Count++)
            {
                Vector3.Vector Vec = InArray[Count];

                Vector3.Vector ResultPoint = QuaternionEC.RotateVector3(
                    RotationQ,
                    InverseRotationQ,
                    Vec);

                InArray[Count] = ResultPoint;
            }
        }
Exemplo n.º 5
0
        internal static Vector3.Vector RotationWithSetupDegrees(
            double AngleDegrees,
            QuaternionRec Axis,
            Vector3.Vector InVector)
        {
            double Angle = NumbersEC.DegreesToRadians(AngleDegrees);

            QuaternionRec RotationQ        = SetAsRotation(Axis, Angle);
            QuaternionRec InverseRotationQ = Inverse(RotationQ);

            Vector3.Vector ResultPoint = RotateVector3(
                RotationQ,
                InverseRotationQ,
                InVector);

            return(ResultPoint);
        }
Exemplo n.º 6
0
        internal static QuaternionRec MultiplyWithLeftVector3(
            Vector3.Vector L,
            QuaternionRec R)
        {
            QuaternionRec Result;

            // Result.X =  (L.X * R.W) +  (0 * R.X) +  (L.Y * R.Z) + (-L.Z * R.Y);
            // Result.Y = (-L.X * R.Z) +  (L.Y * R.W) +  (L.Z * R.X) +  (0 * R.Y);
            // Result.Z =  (L.X * R.Y) + (-L.Y * R.X) +  (L.Z * R.W) +  (0 * R.Z);
            // Result.W = (-L.X * R.X) + (-L.Y * R.Y) + (-L.Z * R.Z) +  (0 * R.W);

            Result.X = (L.X * R.W) + (L.Y * R.Z) + (-L.Z * R.Y);
            Result.Y = (-L.X * R.Z) + (L.Y * R.W) + (L.Z * R.X);
            Result.Z = (L.X * R.Y) + (-L.Y * R.X) + (L.Z * R.W);
            Result.W = (-L.X * R.X) + (-L.Y * R.Y) + (-L.Z * R.Z);
            return(Result);
        }
Exemplo n.º 7
0
/*
 * private void SetPlanetGravityAcceleration(
 *                ref ReferenceFrame RefFrame )
 *  {
 *
 *  RefFrame.SetPlanetGravityAcceleration(
 *                ref Vector3.Vector Position )
 *                ref Vector3.Vector Acceleration )
 *
 *
 *  }
 */



        private void AddSurfaceVertex(
            Vector3.Vector RefPosition,
            Vector3.Vector RefNormal,
            EarthSlice.LatLongPosition Pos,
            double TextureY)
        {
            // Surface.Positions.Count
            // Surface.Positions.Items[Index];
            // Surface.Positions.Add() adds it to the end.
            // Surface.Positions.Clear(); Removes all values.

            // Use a scale for drawing.
            double  ScaledX = (Position.X + RefPosition.X) * ModelConstants.ThreeDSizeScale;
            double  ScaledY = (Position.Y + RefPosition.Y) * ModelConstants.ThreeDSizeScale;
            double  ScaledZ = (Position.Z + RefPosition.Z) * ModelConstants.ThreeDSizeScale;
            Point3D VertexP = new Point3D(ScaledX, ScaledY, ScaledZ);

            Surface.Positions.Add(VertexP);

            // Texture coordinates are "scaled by their
            // bounding box".  You have to create the right
            // "bounding box."  You have to give it bounds
            // by setting vertexes out on the edges.  In
            // the example above for latitude/longitude,
            // you have to set both the North Pole and
            // the South Pole vertexes in order to give
            // the north and south latitudes a "bounding box"
            // so that the texture can be scaled all the way
            // from north to south.  And you have to set
            // vertexes at 180 longitude and -180 longitude
            // (out on the edges) to give it the right
            // bounding box for longitude.  Otherwise it will
            // scale the texture image in ways you don't want.

            Point TexturePoint = new Point(Pos.TextureX, TextureY);

            Surface.TextureCoordinates.Add(TexturePoint);

            Vector3D SurfaceNormal = new Vector3D(RefNormal.X, RefNormal.Y, RefNormal.Z);

            Surface.Normals.Add(SurfaceNormal);
        }
Exemplo n.º 8
0
        private bool MakeOneVertexRow(int RowIndex,
                                      int HowMany,
                                      double ApproxLatitude)
        {
            try
            {
                LastGraphicsIndex = EarthSliceArray[RowIndex].
                                    MakeSurfaceVertexRow(
                    ApproxLatitude,
                    UTCTimeRadians,
                    LastGraphicsIndex);

                for (int Count = 0; Count < HowMany; Count++)
                {
                    EarthSlice.LatLongPosition Pos =
                        EarthSliceArray[RowIndex].
                        GetLatLongPosition(Count);

                    Vector3.Vector RefPosition =
                        EarthSliceArray[RowIndex].GetPosition(Count, 0);

                    Vector3.Vector RefNormal =
                        EarthSliceArray[RowIndex].GetSurfaceNormal(Count, 0);


                    double TextureY = EarthSliceArray[RowIndex].
                                      GetTextureY();

                    AddSurfaceVertex(RefPosition,
                                     RefNormal,
                                     Pos,
                                     TextureY);
                }

                return(true);
            }
            catch (Exception Except)
            {
                ShowStatus("Exception in EarthGeoid.MakeOneVertexRow(): " + Except.Message);
                return(false);
            }
        }
Exemplo n.º 9
0
        private void MakeNorthPoleVector()
        {
            // The coordinate system is centered at the barycenter of the
            // solar system and the X axis goes to the point where Earth
            // is at the Spring Equinox.  Earth is rotated around that
            // X axis.

            Vector3.Vector StraightUp;
            StraightUp.X = 0;
            StraightUp.Y = 0;
            StraightUp.Z = 1;

            QuaternionEC.QuaternionRec Axis;
            Axis.X = 1; // Rotate around the X axis.
            Axis.Y = 0;
            Axis.Z = 0;
            Axis.W = 0;

            NorthPoleVector = QuaternionEC.RotationWithSetupDegrees(
                ModelConstants.EarthTiltAngleDegrees,
                Axis,
                StraightUp);
        }
Exemplo n.º 10
0
        private void MakePoleRow(double ApproxLatitude)
        {
            Vector3.Vector Position = new Vector3.Vector();
            Vector3.Vector Normal   = new Vector3.Vector();

            Position.X = 0;
            Position.Y = 0;
            Normal.X   = 0;
            Normal.Y   = 0;

            if (ApproxLatitude > 0)
            {
                Position.Z = RadiusMinor;
                Normal.Z   = 1;
            }
            else
            {
                Position.Z = -RadiusMinor;
                Normal.Z   = -1;
            }

            PositionArray[0]      = Position;
            SurfaceNormalArray[0] = Normal;
        }
Exemplo n.º 11
0
        internal void MakeVertexRow(
            double ApproxLatitude,
            double LongitudeHoursRadians)
        {
            try
            {
                if (ArraySize < 2)
                {
                    MakePoleRow(ApproxLatitude);
                    return;
                }

                double LonStart = -180.0;

                // There is a beginning vertex at -180 longitude
                // and there is an ending vertex at 180
                // longitude, which is the same place, but they
                // are associated with different texture
                // coordinates.  One at the left end of the
                // texture and one at the right end.
                // So this is minus 1:
                double LonDelta = 360.0d / (double)(ArraySize - 1);

                for (int Count = 0; Count < ArraySize; Count++)
                {
                    Vector3.Vector Position = new Vector3.Vector();
                    Vector3.Vector Normal   = new Vector3.Vector();

                    double Longitude  = LonStart + (LonDelta * Count);
                    double LonRadians = NumbersEC.DegreesToRadians(
                        Longitude);

                    // Higher hours make the sun set in the west.
                    LonRadians += LongitudeHoursRadians;

                    double CosLonRadians = Math.Cos(LonRadians);
                    double SinLonRadians = Math.Sin(LonRadians);

                    // Along the equatorial axis:
                    Position.X = RadiusMajor * (CosLatRadians * CosLonRadians);
                    Position.Y = RadiusMajor * (CosLatRadians * SinLonRadians);

                    // Along the polar axis:
                    Position.Z = RadiusMinor * SinLatRadians;

                    PositionArray[Count] = Position;

                    // if( It needs to be calculated... )
                    SetSurfaceNormal(Position,
                                     ref Normal,
                                     CosLonRadians,
                                     SinLonRadians,
                                     ApproxLatitude);

                    SurfaceNormalArray[Count] = Normal;
                    //
                }
            }
            catch (Exception Except)
            {
                ShowStatus("Exception in ReferenceVertex.MakeVertexRow(): " + Except.Message);
            }
        }
Exemplo n.º 12
0
        internal void DoTimeStep()
        {
            const double TimeDelta = 60 * 10; // seconds.

            for (int Count = 0; Count < SpaceObjectArrayLast; Count++)
            {
                SpaceObject SpaceObj = SpaceObjectArray[Count];
                SpaceObj.SetNextPositionFromVelocity(
                    TimeDelta);
            }

            Vector3.Vector AccelVector = new Vector3.Vector();
            for (int Count = 0; Count < SpaceObjectArrayLast; Count++)
            {
                SpaceObject SpaceObj = SpaceObjectArray[Count];
                SpaceObj.Acceleration = Vector3.MakeZero();

                for (int Count2 = 0; Count2 < SpaceObjectArrayLast; Count2++)
                {
                    SpaceObject FarAwaySpaceObj = SpaceObjectArray[Count2];
                    if (FarAwaySpaceObj.Mass < 1)
                    {
                        throw(new Exception("The space object has no mass."));
                    }

                    AccelVector = FarAwaySpaceObj.Position;
                    AccelVector = Vector3.Subtract(AccelVector, SpaceObj.Position);

                    double Distance = Vector3.Norm(AccelVector);

                    // Check if it's the same planet at zero
                    // distance.
                    if (Distance < 1.0)
                    {
                        continue;
                    }

                    double Acceleration =
                        (ModelConstants.GravitationConstant *
                         FarAwaySpaceObj.Mass) /
                        (Distance * Distance);

                    AccelVector           = Vector3.Normalize(AccelVector);
                    AccelVector           = Vector3.MultiplyWithScalar(AccelVector, Acceleration);
                    SpaceObj.Acceleration = Vector3.Add(SpaceObj.Acceleration, AccelVector);
                }

                // Add the new Acceleration vector to the
                // velocity vector.
                SpaceObj.Velocity = Vector3.Add(SpaceObj.Velocity, SpaceObj.Acceleration);
            }

            ShowStatus(" ");
            ShowStatus("Velocity.X: " + Earth.Velocity.X.ToString("N2"));
            ShowStatus("Velocity.Y: " + Earth.Velocity.Y.ToString("N2"));
            ShowStatus("Velocity.Z: " + Earth.Velocity.Z.ToString("N2"));
            ShowStatus(" ");


            Earth.AddTimeStepRotateAngle();

            // Earth.SetPlanetGravityAcceleration( this );

            // Move Earth only:
            // Earth.MakeNewGeometryModel();
            // ResetGeometryModels();

            // Move all of the planets:
            MakeNewGeometryModels();
        }
Exemplo n.º 13
0
        private void SetEarthRotationAngle()
        {
            // Earth: Sidereal period, hr  = 23.93419

            Vector3.Vector AlongX;
            AlongX.X = 1;
            AlongX.Y = 0;
            AlongX.Z = 0;

            Vector3.Vector EarthToSun = Earth.Position;

            // Make a vector that goes from the Earth to
            // the center of the coordinate system.
            EarthToSun = Vector3.Negate(EarthToSun);

            // Add the vector from the center of the
            // coordinate system to the sun.
            EarthToSun = Vector3.Add(EarthToSun, Sun.Position);

            // This is now the vector from the Earth to the
            // sun.

            // Set Z to zero so it's only the rotation
            // around the Z axis.
            EarthToSun.Z = 0;

            ShowStatus(" ");
            ShowStatus("EarthToSun.X: " + EarthToSun.X.ToString("N2"));
            ShowStatus("EarthToSun.Y: " + EarthToSun.Y.ToString("N2"));
            // ShowStatus( "EarthToSun.Z: " + EarthToSun.Z.ToString( "N2" ));

            EarthToSun = Vector3.Normalize(EarthToSun);

            // The dot product of two normalized vectors.
            double Dot = Vector3.DotProduct(
                AlongX,
                EarthToSun);

            double SunAngle = Math.Acos(Dot);
            double HalfPi   = Math.PI / 2.0;

            ShowStatus("Dot: " + Dot.ToString("N2"));
            ShowStatus("SunAngle: " + SunAngle.ToString("N2"));
            ShowStatus("HalfPi: " + HalfPi.ToString("N2"));

            // EarthToSun.X: -68,463,078,802.05
            // EarthToSun.Y: 135,732,403,641.45
            // Dot: -0.45
            // SunAngle: 2.04
            // HalfPi: 1.57
            // Hours: 6.93

            double Hours   = SunTime.GetHour();
            double Minutes = SunTime.GetMinute();

            Minutes = Minutes / 60.0d;
            Hours   = Hours + Minutes;
            Hours  -= 12.0;
            ShowStatus("Hours: " + Hours.ToString("N2"));

            double HoursInRadians = NumbersEC.DegreesToRadians(Hours * (360.0d / 24.0d));

            Earth.UTCTimeRadians = HoursInRadians + SunAngle;

            // Make a new Earth geometry model before
            // calling reset.
            Earth.MakeNewGeometryModel();
            ResetGeometryModels();

            // MakeNewGeometryModels();
        }
Exemplo n.º 14
0
        private void MakeGeoidModel()
        {
            try
            {
                LastGraphicsIndex = 0;

                Surface = new MeshGeometry3D();

                double ApproxLatitude = 90.0;

                LastGraphicsIndex =
                    EarthSliceArray[0].MakeSurfaceVertexRow(
                        ApproxLatitude,
                        UTCTimeRadians,
                        LastGraphicsIndex);

                EarthSlice.LatLongPosition PosNorthPole =
                    EarthSliceArray[0].
                    GetLatLongPosition(0);

                Vector3.Vector PositionNorthPole =
                    EarthSliceArray[0].GetPosition(0, 0);

                Vector3.Vector NormalNorthPole =
                    EarthSliceArray[0].GetSurfaceNormal(0, 0);

                double TextureY = EarthSliceArray[0].GetTextureY();

                AddSurfaceVertex(PositionNorthPole,
                                 NormalNorthPole,
                                 PosNorthPole,
                                 TextureY);

                ApproxLatitude    = -90.0;
                LastGraphicsIndex =
                    EarthSliceArray[EarthSlice.VertexRowsLast - 1].
                    MakeSurfaceVertexRow(
                        ApproxLatitude,
                        UTCTimeRadians,
                        LastGraphicsIndex);

                EarthSlice.LatLongPosition PosSouthPole =
                    EarthSliceArray[EarthSlice.VertexRowsLast - 1].
                    GetLatLongPosition(0);

                Vector3.Vector PositionSouthPole =
                    EarthSliceArray[EarthSlice.VertexRowsLast - 1].GetPosition(0, 0);

                Vector3.Vector NormalSouthPole =
                    EarthSliceArray[EarthSlice.VertexRowsLast - 1].GetSurfaceNormal(0, 0);

                TextureY = EarthSliceArray[EarthSlice.VertexRowsLast - 1].GetTextureY();

                AddSurfaceVertex(PositionSouthPole,
                                 NormalSouthPole,
                                 PosSouthPole,
                                 TextureY);

                double RowLatitude = 90;
                int    HowMany     = 4;
                for (int Index = 1; Index <= EarthSlice.VertexRowsMiddle; Index++)
                {
                    RowLatitude -= EarthSlice.RowLatDelta;
                    MakeOneVertexRow(Index, HowMany, RowLatitude);
                    if (HowMany < EarthSlice.MaximumVertexesPerRow)
                    {
                        HowMany = HowMany * 2;
                    }
                }

                RowLatitude = -90;
                HowMany     = 4;
                for (int Index = EarthSlice.VertexRowsLast - 2; Index > EarthSlice.VertexRowsMiddle; Index--)
                {
                    RowLatitude += EarthSlice.RowLatDelta;
                    MakeOneVertexRow(Index, HowMany, RowLatitude);
                    if (HowMany < EarthSlice.MaximumVertexesPerRow)
                    {
                        HowMany = HowMany * 2;
                    }
                }

                MakePoleTriangles();

                for (int Index = 0; Index < EarthSlice.VertexRowsLast - 2; Index++)
                {
                    if (EarthSliceArray[Index].
                        GetRefVertexArraySize() ==
                        EarthSliceArray[Index + 1].
                        GetRefVertexArraySize())
                    {
                        MakeRowTriangles(Index, Index + 1);
                    }
                    else
                    {
                        if (EarthSliceArray[Index].
                            GetRefVertexArraySize() <
                            EarthSliceArray[Index + 1].
                            GetRefVertexArraySize())
                        {
                            MakeDoubleRowTriangles(Index, Index + 1);
                        }
                        else
                        {
                            MakeDoubleReverseRowTriangles(Index + 1, Index);
                        }
                    }
                }
            }
            catch (Exception Except)
            {
                ShowStatus("Exception in EarthGeoid.MakeGeoidModel(): " + Except.Message);
            }
        }
Exemplo n.º 15
0
        private void SetSurfaceNormal(
            Vector3.Vector Position,
            ref Vector3.Vector Normal,
            double CosLonRadians,
            double SinLonRadians,
            double ApproxLatitude)
        {
            if (ApproxLatitude < -89.999)
            {
                throw(new Exception("ApproxLatitude < -89.999 in SetSurfaceNormal()."));
            }

            if (ApproxLatitude > 89.999)
            {
                throw(new Exception("ApproxLatitude > 89.999 in SetSurfaceNormal()."));
            }

            // If it's at the equator.
            if ((ApproxLatitude < 0.00001) &&
                (ApproxLatitude > -0.00001))
            {
                // This avoids calculating a perpendicular
                // with two vectors _very_ close to each other.
                // It avoids normalizing a very small vector.
                Normal.X = Position.X;
                Normal.Y = Position.Y;
                Normal.Z = 0;
                Normal   = Vector3.Normalize(Normal);
                return;
            }

            Vector3.Vector PositionAtDelta;
            PositionAtDelta.X = RadiusMajor * (CosLatRadiansPlusDelta * CosLonRadians);
            PositionAtDelta.Y = RadiusMajor * (CosLatRadiansPlusDelta * SinLonRadians);
            PositionAtDelta.Z = RadiusMinor * SinLatRadiansPlusDelta;

            Vector3.Vector Flat;
            Flat = PositionAtDelta;
            Flat = Vector3.Subtract(Flat, Position);

            if (Position.Z > PositionAtDelta.Z)
            {
                throw(new Exception("Position.Z > PositionAtDelta.Z."));
            }

            if (Flat.Z < 0)
            {
                throw(new Exception("Flat.Z < 0."));
            }

            Flat = Vector3.Normalize(Flat);

            // Straight up through the north pole.
            Vector3.Vector StraightUp;
            StraightUp.X = 0;
            StraightUp.Y = 0;
            StraightUp.Z = 1;

            // The dot product of two normalized vectors.
            double Dot = Vector3.DotProduct(StraightUp, Flat);

            if (Dot < 0)
            {
                throw(new Exception("Dot < 0."));
            }

            // Make a vector perpendicular to FlatVector and
            // toward StraightUp.
            Vector3.Vector PerpenVector =
                Vector3.MakePerpendicular(Flat,
                                          StraightUp);

            if (Position.Z < 0)
            {
                PerpenVector = Vector3.Negate(PerpenVector);
            }

            Normal = PerpenVector;
        }
Exemplo n.º 16
0
        internal void SetupLatitude(
            double UseApproximateLatitude,
            double UseRadiusMinor,
            double UseRadiusMajor)
        {
            ApproximateLatitude = UseApproximateLatitude;
            RadiusMinor         = UseRadiusMinor;
            RadiusMajor         = UseRadiusMajor;

            LatRadians             = NumbersEC.DegreesToRadians(ApproximateLatitude);
            CosLatRadians          = Math.Cos(LatRadians);
            SinLatRadians          = Math.Sin(LatRadians);
            CosLatRadiansPlusDelta = Math.Cos(LatRadians + LatitudeRadiansDelta);
            SinLatRadiansPlusDelta = Math.Sin(LatRadians + LatitudeRadiansDelta);

            // If it's at the north or south pole.
            if ((ApproximateLatitude > 89.9999) ||
                (ApproximateLatitude < -89.9999))
            {
                GeodeticLatitude = ApproximateLatitude;
                return;
            }

            // If it's pretty much at the equator at
            // zero latitude.
            if ((ApproximateLatitude > -0.0001) &&
                (ApproximateLatitude < 0.0001))
            {
                GeodeticLatitude = ApproximateLatitude;
                return;
            }

            // Straight up through the north pole.
            Vector3.Vector StraightUp = new Vector3.Vector();
            StraightUp.X = 0;
            StraightUp.Y = 0;
            StraightUp.Z = 1;

            double CosLonRadians = 1;
            double SinLonRadians = 0;

            Vector3.Vector Position = new Vector3.Vector();
            Position.X = RadiusMajor * (CosLatRadians * CosLonRadians);
            Position.Y = RadiusMajor * (CosLatRadians * SinLonRadians);
            Position.Z = RadiusMinor * SinLatRadians;

            Vector3.Vector PositionAtDelta = new Vector3.Vector();
            PositionAtDelta.X = RadiusMajor * (CosLatRadiansPlusDelta * CosLonRadians);
            PositionAtDelta.Y = RadiusMajor * (CosLatRadiansPlusDelta * SinLonRadians);
            PositionAtDelta.Z = RadiusMinor * SinLatRadiansPlusDelta;

            Vector3.Vector Flat = PositionAtDelta;
            Flat = Vector3.Subtract(Flat, Position);

            if (Position.Z > PositionAtDelta.Z)
            {
                throw(new Exception("Position.Z > PositionAtDelta.Z."));
            }

            if (Flat.Z < 0)
            {
                throw(new Exception("Flat.Z < 0."));
            }

            Flat = Vector3.Normalize(Flat);

            // The dot product of two normalized vectors.
            double Dot = Vector3.DotProduct(
                StraightUp,
                Flat);

            if (Dot < 0)
            {
                throw(new Exception("Dot < 0."));
            }

            double StraightUpAngle = Math.Acos(Dot);
            double AngleToEquator  =
                (Math.PI / 2.0) - StraightUpAngle;

            double Degrees = NumbersEC.RadiansToDegrees(StraightUpAngle);

            if (ApproximateLatitude >= 0)
            {
                GeodeticLatitude = Degrees;
            }
            else
            {
                GeodeticLatitude = -Degrees;
            }
        }
Exemplo n.º 17
0
/*
 * private void InitializeTimes()
 *  {
 *  SunTime.SetToNow();
 *
 *  // https://en.wikipedia.org/wiki/March_equinox
 *
 *  // "Spring Equinox 2018 was at 10:15 AM on
 *  // March 20."
 *  SpringTime.SetUTCTime( 2018,
 *                          3,
 *                          20,
 *                          10,
 *                          15,
 *                          0,
 *                          0 );
 *
 *
 *  }
 */



/*
 * private void SetPositionsAndTime( ECTime SetTime )
 *  {
 *  SunTime.Copy( SetTime );
 *
 *  }
 */



        private void AddInitialSpaceObjects()
        {
            try
            {
                // Sun:
                string JPLFileName = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLSun.txt";
                Sun                 = new PlanetSphere(MForm, "Sun", true, JPLFileName);
                Sun.Radius          = 695700 * ModelConstants.TenTo3;
                Sun.Mass            = ModelConstants.MassOfSun;
                Sun.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\sun.jpg";
                AddSpaceObject(Sun);

                // Earth:
                JPLFileName           = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLEarth.txt";
                Earth                 = new EarthGeoid(MForm, "Earth", JPLFileName);
                Earth.Mass            = ModelConstants.MassOfEarth;
                Earth.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\earth.jpg";
                AddSpaceObject(Earth);

                // Moon:
                JPLFileName = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLMoon.txt";
                Moon        = new PlanetSphere(MForm, "Moon", false, JPLFileName);
                // Radius: About 1,737.1 kilometers.
                Moon.Radius          = 1737100;
                Moon.Mass            = ModelConstants.MassOfMoon;
                Moon.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\moon.jpg";
                AddSpaceObject(Moon);

                // Space Station:
                // Both Earth and the Space Station need to be
                // using the same time intervals for the JPL
                // data.
                // JPLFileName = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLSpaceStation.txt";
                // SpaceStation = new PlanetSphere( MForm, "Space Station", false, JPLFileName );
                // It's about 418 kilometers above the Earth.
                // SpaceStation.Radius = 400000; // 418000;
                // SpaceStation.Mass = 1.0;
                // SpaceStation.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\TestImage2.jpg";
                // AddSpaceObject( SpaceStation );

/*
 * I would need to set this position after getting
 * Earth rotation angle and all that.
 *  // Leadville marker:
 *  JPLFileName = "";
 *  Leadville = new PlanetSphere( MForm, "Leadville", false, JPLFileName );
 *  Leadville.Radius = 1000000;
 *  Leadville.Mass = 0;
 *  Leadville.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\TestImage.jpg";
 *  AddSpaceObject( Leadville );
 */

                // Mercury:
                JPLFileName = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLMercury.txt";
                PlanetSphere Mercury = new PlanetSphere(
                    MForm, "Mercury", false, JPLFileName);

                Mercury.Radius          = 2440000d * RadiusScale;
                Mercury.Mass            = ModelConstants.MassOfMercury;
                Mercury.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\Mercury.jpg";
                AddSpaceObject(Mercury);

                // Venus:
                JPLFileName = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLVenus.txt";
                PlanetSphere Venus = new PlanetSphere(
                    MForm, "Venus", false, JPLFileName);

                Venus.Radius          = 6051000 * RadiusScale; // 6,051 km
                Venus.Mass            = ModelConstants.MassOfVenus;
                Venus.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\Venus.jpg";
                AddSpaceObject(Venus);

                // Mars:
                JPLFileName = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLMars.txt";
                PlanetSphere Mars = new PlanetSphere(
                    MForm, "Mars", false, JPLFileName);

                Mars.Radius          = 3396000 * RadiusScale;
                Mars.Mass            = ModelConstants.MassOfMars;
                Mars.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\mars.jpg";
                AddSpaceObject(Mars);


                // Jupiter:
                JPLFileName = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLJupiter.txt";
                PlanetSphere Jupiter = new PlanetSphere(
                    MForm, "Jupiter", false, JPLFileName);

                //                m  t
                Jupiter.Radius          = 69911000d * RadiusScale; // 69,911 km
                Jupiter.Mass            = ModelConstants.MassOfJupiter;
                Jupiter.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\Jupiter.jpg";
                AddSpaceObject(Jupiter);

                // Saturn:
                JPLFileName = "C:\\Eric\\ClimateModel\\EphemerisData\\JPLSaturn.txt";
                PlanetSphere Saturn = new PlanetSphere(
                    MForm, "Saturn", false, JPLFileName);

                //               m  t
                Saturn.Radius          = 58232000d * RadiusScale; // 58,232 km
                Saturn.Mass            = ModelConstants.MassOfSaturn;
                Saturn.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\Saturn.jpg";
                AddSpaceObject(Saturn);

                // North Pole:
                PlanetSphere NorthPole = new PlanetSphere(
                    MForm, "North Pole", false, "");

                NorthPole.Radius          = 400000d;
                NorthPole.Mass            = 0;
                NorthPole.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\TestImage2.jpg";
                AddSpaceObject(NorthPole);

                // Moon Axis:
                PlanetSphere MoonAxis = new PlanetSphere(
                    MForm, "Moon Axis", false, "");

                MoonAxis.Radius          = 200000d;
                MoonAxis.Mass            = 0;
                MoonAxis.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\TestImage2.jpg";
                AddSpaceObject(MoonAxis);


                // Solar North:
                PlanetSphere SolarNorth = new PlanetSphere(
                    MForm, "Solar North", false, "");

                SolarNorth.Radius          = 100000d;
                SolarNorth.Mass            = 0;
                SolarNorth.TextureFileName = "C:\\Eric\\ClimateModel\\bin\\Release\\TestImage2.jpg";
                AddSpaceObject(SolarNorth);


                ///////////////////////////////////
                // Set the positions of the objects from the JPL data.
                SetJPLTimes();


                // Now that the Earth's position has been set...

                Vector3.Vector NorthPoleUnit = Earth.GetNorthPoleVector();

                Vector3.Vector NorthPolePos =
                    Vector3.MultiplyWithScalar(NorthPoleUnit,
                                               ModelConstants.EarthRadiusMinor + NorthPole.Radius);

                NorthPolePos       = Vector3.Add(NorthPolePos, Earth.Position);
                NorthPole.Position = NorthPolePos;


                // Set the moon axis.
                Vector3.Vector MoonFirstPosition = Moon.Position;
                // Subtract the Earth's position so this is just in relation
                // to the Earth.
                MoonFirstPosition = Vector3.Subtract(MoonFirstPosition, Earth.Position);

                ECTime OneWeek   = new ECTime(SunTime.GetIndex());
                int    SevenDays = 7 * 24 * 60;
                OneWeek.AddMinutes(SevenDays);

                JPLHorizonsData.JPLRec Rec =
                    Moon.JPLData.GetNearestRecByDateTime(OneWeek.GetIndex());

                // if( Rec.CalDate == 0 ) then it's not found.

                Vector3.Vector MoonSecondPosition;
                MoonSecondPosition.X = Rec.PositionX;
                MoonSecondPosition.Y = Rec.PositionY;
                MoonSecondPosition.Z = Rec.PositionZ;

                // Get the Earth's position a week from now.
                Rec = Earth.JPLData.GetNearestRecByDateTime(OneWeek.GetIndex());

                Vector3.Vector EarthSecondPosition;
                EarthSecondPosition.X = Rec.PositionX;
                EarthSecondPosition.Y = Rec.PositionY;
                EarthSecondPosition.Z = Rec.PositionZ;


                MoonSecondPosition = Vector3.Subtract(MoonSecondPosition, EarthSecondPosition);

                // MoonFirstPosition = Vector3.Normalize( MoonFirstPosition );
                // MoonSecondPosition = Vector3.Normalize( MoonSecondPosition );

                Vector3.Vector MoonAxisPos = Vector3.CrossProduct(
                    MoonFirstPosition,
                    MoonSecondPosition);

                MoonAxisPos = Vector3.Normalize(MoonAxisPos);
                MoonAxisPos = Vector3.MultiplyWithScalar(MoonAxisPos,
                                                         ModelConstants.EarthRadiusMinor + MoonAxis.Radius);

                MoonAxisPos = Vector3.Add(MoonAxisPos, Earth.Position);

                MoonAxis.Position = MoonAxisPos;


                Vector3.Vector SolarNorthPos;
                SolarNorthPos.X = 0;
                SolarNorthPos.Y = 0;
                SolarNorthPos.Z = 1;
                SolarNorthPos   = Vector3.MultiplyWithScalar(SolarNorthPos,
                                                             ModelConstants.EarthRadiusMinor + SolarNorth.Radius);

                SolarNorthPos       = Vector3.Add(SolarNorthPos, Earth.Position);
                SolarNorth.Position = SolarNorthPos;
            }
            catch (Exception Except)
            {
                MForm.ShowStatus("Exception in SolarSystem.AddMercury(): " + Except.Message);
            }
        }