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; }
internal void RotateView() { double AddHours = NumbersEC.DegreesToRadians(0.5 * (360.0d / 24.0d)); Earth.UTCTimeRadians = Earth.UTCTimeRadians + AddHours; Earth.MakeNewGeometryModel(); ResetGeometryModels(); }
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); } }
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); }
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); }
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); } }
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; } }
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); } }
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); } }
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(); }