예제 #1
0
        internal void SetLatLonPositionXYZ(
            ref LatLongPosition Result,
            double CosLatRadians,
            double SinLatRadians)
        {
            double LonRadians = NumbersEC.DegreesToRadians(Result.Longitude);

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

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

            Result.X = Radius * (CosLatRadians * CosLonRadians);
            Result.Y = Radius * (CosLatRadians * SinLonRadians);
            Result.Z = Radius * SinLatRadians;

            Result.SurfaceNormal.X = Result.X;
            Result.SurfaceNormal.Y = Result.Y;
            Result.SurfaceNormal.Z = Result.Z;
            Result.SurfaceNormal   = Vector3.Normalize(Result.SurfaceNormal);

            Result.X += Position.X;
            Result.Y += Position.Y;
            Result.Z += Position.Z;

            Result.TextureX = Result.Longitude + 180.0;
            Result.TextureX = Result.TextureX * (1.0d / 360.0d);

            Result.TextureY = Result.Latitude + 90.0;
            Result.TextureY = Result.TextureY * (1.0d / 180.0d);
            Result.TextureY = 1 - Result.TextureY;
        }
예제 #2
0
        internal void RotateView()
        {
            double AddHours = NumbersEC.DegreesToRadians(0.5 * (360.0d / 24.0d));

            Earth.UTCTimeRadians = Earth.UTCTimeRadians + AddHours;
            Earth.MakeNewGeometryModel();
            ResetGeometryModels();
        }
예제 #3
0
        private bool MakeOneVertexRow(int RowIndex,
                                      int HowMany,
                                      double Latitude)
        {
            try
            {
                VertexRows[RowIndex]         = new VertexRow();
                VertexRows[RowIndex].Row     = new LatLongPosition[HowMany];
                VertexRows[RowIndex].RowLast = HowMany;

                double LatRadians    = NumbersEC.DegreesToRadians(Latitude);
                double CosLatRadians = Math.Cos(LatRadians);
                double SinLatRadians = Math.Sin(LatRadians);

                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)(HowMany - 1);

                for (int Count = 0; Count < HowMany; Count++)
                {
                    LatLongPosition Pos = new LatLongPosition();
                    Pos.Latitude = Latitude;

                    // The sine and cosine of this longitude could
                    // be saved in an array for the next row of
                    // equal size.  (Like 1024 vertexes or what
                    // ever.)

                    Pos.Longitude = LonStart + (LonDelta * Count);
                    Pos.Index     = LastVertexIndex;
                    LastVertexIndex++;

                    SetLatLonPositionXYZ(ref Pos,
                                         CosLatRadians,
                                         SinLatRadians);

                    VertexRows[RowIndex].Row[Count] = Pos;
                    AddSurfaceVertex(Pos);
                }

                return(true);
            }
            catch (Exception Except)
            {
                ShowStatus("Exception in PlanetSphere.MakeSphericalModel(): " + Except.Message);
                return(false);
            }
        }
예제 #4
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);
        }
예제 #5
0
        private void SetupEarthTiltRotations()
        {
            // RotationQ = new QuaternionEC.QuaternionRec();
            // InverseRotationQ = new QuaternionEC.QuaternionRec();

            double Angle = ModelConstants.EarthTiltAngleDegrees;

            Angle = NumbersEC.DegreesToRadians(Angle);

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

            RotationQ = QuaternionEC.SetAsRotation(Axis,
                                                   Angle);

            InverseRotationQ = QuaternionEC.Inverse(RotationQ);
        }
예제 #6
0
        private void ThreeDForm_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
// A  The A key.
// Add The add key.
// D0 The 0 key.
// D1 The 1 key.
// Delete The DEL key.
// End The END key.
// Enter The ENTER key.
// Home The HOME key.
// Insert The INS key.
// NumPad2 The 2 key on the numeric keypad.
// Return The RETURN key.
// Space The SPACEBAR key.
// Subtract The subtract key.
// Tab The TAB key.

                double Angle = NumbersEC.DegreesToRadians(2);

                if (e.Control)
                {
                    if (e.KeyCode == Keys.T)
                    {
                        Scene.RotateView();

/*
 * private void SetCameraTo( double X,
 *                          double Y,
 *                          double Z,
 *                          double LookX,
 *                          double LookY,
 *                          double LookZ,
 *                          double UpX,
 *                          double UpY,
 *                          double UpZ )
 */
                        return;
                    }

                    if (e.KeyCode == Keys.S)
                    {
                        Scene.DoTimeStep();

/*
 * private void SetCameraTo( double X,
 *                          double Y,
 *                          double Z,
 *                          double LookX,
 *                          double LookY,
 *                          double LookZ,
 *                          double UpX,
 *                          double UpY,
 *                          double UpZ )
 */
                        return;
                    }

                    if (e.KeyCode == Keys.E)
                    {
                        Scene.MoveToEarthView();
                        return;
                    }

                    if (e.KeyCode == Keys.Z)
                    {
                        Scene.SetEarthPositionToZero();
                        Scene.MoveToEarthView();
                        return;
                    }

                    if (e.KeyCode == Keys.J)
                    {
                        Scene.SolarS.AddMinutesToSunTime(10);
                        Scene.SolarS.SetJPLTimes();
                        Scene.MoveToEarthView();
                        return;
                    }


                    if (e.KeyCode == Keys.Left)
                    {
                        Scene.RotateLeftRight(-Angle);
                    }

                    if (e.KeyCode == Keys.Right)
                    {
                        Scene.RotateLeftRight(Angle);
                    }

                    if (e.KeyCode == Keys.PageUp)
                    {
                        Scene.MoveForwardBack(1000.0);
                    }

                    if (e.KeyCode == Keys.PageDown)
                    {
                        Scene.MoveForwardBack(-1000.0);
                    }

                    return;
                }


                if (e.Alt)
                {
                    return;
                }


                if (e.Shift)
                {
                    if (e.KeyCode == Keys.Left)
                    {
                        Scene.ShiftLeftRight(-3.0);
                    }

                    if (e.KeyCode == Keys.Right)
                    {
                        Scene.ShiftLeftRight(3.0);
                    }

                    if (e.KeyCode == Keys.Up)
                    {
                        Scene.ShiftUpDown(3.0);
                    }

                    if (e.KeyCode == Keys.Down)
                    {
                        Scene.ShiftUpDown(-3.0);
                    }

                    return;
                }

                if (e.KeyCode == Keys.Escape) //  && (e.Alt || e.Control || e.Shift))
                {
                    // MessageBox.Show( "Escape.", MainForm.MessageBoxTitle, MessageBoxButtons.OK );
                }

                if (e.KeyCode == Keys.F1)
                {
                    MessageBox.Show("Control E gets back to Earth. Z goes to barycenter. J is plus 10 minutes.", MainForm.MessageBoxTitle, MessageBoxButtons.OK);
                    return;
                }

                if (e.KeyCode == Keys.PageUp)
                {
                    // MessageBox.Show( "Page up.", MainForm.MessageBoxTitle, MessageBoxButtons.OK );
                    Scene.MoveForwardBack(2.0);
                }

                if (e.KeyCode == Keys.PageDown)
                {
                    Scene.MoveForwardBack(-2.0);
                }

                if (e.KeyCode == Keys.Left)
                {
                    // See the notes in ThreeDScene.cs and in QuaternionEC.cs
                    // about rotation directions and positive or negative
                    // rotation angles.
                    Scene.MoveLeftRight(Angle);
                }

                if (e.KeyCode == Keys.Right)
                {
                    Scene.MoveLeftRight(-Angle);
                }

                if (e.KeyCode == Keys.Up)
                {
                    Scene.MoveUpDown(Angle);
                }

                if (e.KeyCode == Keys.Down)
                {
                    Scene.MoveUpDown(-Angle);
                }
            }
            catch (Exception Except)
            {
                MessageBox.Show("Exception in ThreeDForm.KeyDown: " + Except.Message, MainForm.MessageBoxTitle, MessageBoxButtons.OK);
            }
        }
예제 #7
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;
            }
        }
예제 #8
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);
            }
        }
예제 #9
0
        private void MakeSphericalModel()
        {
            try
            {
                Surface = new MeshGeometry3D();

                LastVertexIndex = 0;
                VertexRowsLast  = 20 - 1;
                int VertexRowsMiddle = 9;

                VertexRows = new VertexRow[VertexRowsLast];

                LatLongPosition PosNorthPole = new LatLongPosition();
                PosNorthPole.Latitude  = 90.0;
                PosNorthPole.Longitude = 0;
                PosNorthPole.Index     = LastVertexIndex;
                LastVertexIndex++;

                double LatRadians    = NumbersEC.DegreesToRadians(PosNorthPole.Latitude);
                double CosLatRadians = Math.Cos(LatRadians);
                double SinLatRadians = Math.Sin(LatRadians);

                SetLatLonPositionXYZ(ref PosNorthPole,
                                     CosLatRadians,
                                     SinLatRadians);

                LatLongPosition PosSouthPole = new LatLongPosition();
                PosSouthPole.Latitude  = -90.0;
                PosSouthPole.Longitude = 0;
                PosSouthPole.Index     = LastVertexIndex;
                LastVertexIndex++;

                LatRadians    = NumbersEC.DegreesToRadians(PosSouthPole.Latitude);
                CosLatRadians = Math.Cos(LatRadians);
                SinLatRadians = Math.Sin(LatRadians);
                SetLatLonPositionXYZ(ref PosSouthPole,
                                     CosLatRadians,
                                     SinLatRadians);

                VertexRows[0]         = new VertexRow();
                VertexRows[0].Row     = new LatLongPosition[1];
                VertexRows[0].RowLast = 1;
                VertexRows[0].Row[0]  = PosNorthPole;
                AddSurfaceVertex(PosNorthPole);

                VertexRows[VertexRowsLast - 1]         = new VertexRow();
                VertexRows[VertexRowsLast - 1].Row     = new LatLongPosition[1];
                VertexRows[VertexRowsLast - 1].RowLast = 1;
                VertexRows[VertexRowsLast - 1].Row[0]  = PosSouthPole;
                AddSurfaceVertex(PosSouthPole);


                double RowLatitude = 90;
                double RowLatDelta = 10;

                int MaximumVertexes = 64;
                int HowMany         = 4;
                for (int Index = 1; Index <= VertexRowsMiddle; Index++)
                {
                    RowLatitude -= RowLatDelta;
                    MakeOneVertexRow(Index, HowMany, RowLatitude);
                    if (HowMany < MaximumVertexes)
                    {
                        HowMany = HowMany * 2;
                    }
                }


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

                MakePoleTriangles();

                for (int Index = 0; Index < VertexRowsLast - 2; Index++)
                {
                    if (VertexRows[Index].RowLast == VertexRows[Index + 1].RowLast)
                    {
                        MakeRowTriangles(Index, Index + 1);
                    }
                    else
                    {
                        if (VertexRows[Index].RowLast < VertexRows[Index + 1].RowLast)
                        {
                            MakeDoubleRowTriangles(Index, Index + 1);
                        }
                        else
                        {
                            MakeDoubleReverseRowTriangles(Index + 1, Index);
                        }
                    }
                }

                FreeVertexRows();
            }
            catch (Exception Except)
            {
                ShowStatus("Exception in PlanetSphere.MakeSphericalModel(): " + Except.Message);
            }
        }
예제 #10
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();
        }