public Orbit(EOE elements, int segments, Color color, float thickness, float scale) { this.elements = elements; this.segmentCount = segments; this.orbitColor = color; this.scale = scale; }
internal static EOE Create(BinaryReader br) { EOE tmp = new EOE(); tmp.a = br.ReadSingle(); tmp.e = br.ReadSingle(); tmp.i = br.ReadSingle(); tmp.w = br.ReadSingle(); tmp.omega = br.ReadSingle(); tmp.JDEquinox = br.ReadSingle(); tmp.T = br.ReadSingle(); return(tmp); }
public static Vector3d CalculateRectangularJD(double JD, EOE elements) { double JD0 = JD; double omega = CT.D2R(elements.omega); double w = CT.D2R(elements.w); double i = CT.D2R(elements.i); double sinEpsilon = 0; double cosEpsilon = 1; double sinOmega = Math.Sin(omega); double cosOmega = Math.Cos(omega); double cosi = Math.Cos(i); double sini = Math.Sin(i); double F = cosOmega; double G = sinOmega * cosEpsilon; double H = sinOmega * sinEpsilon; double P = -sinOmega * cosi; double Q = cosOmega * cosi * cosEpsilon - sini * sinEpsilon; double R = cosOmega * cosi * sinEpsilon + sini * cosEpsilon; double a = Math.Sqrt(F * F + P * P); double b = Math.Sqrt(G * G + Q * Q); double c = Math.Sqrt(H * H + R * R); double A = Math.Atan2(F, P); double B = Math.Atan2(G, Q); double C = Math.Atan2(H, R); //double n = CAAElliptical.MeanMotionFromSemiMajorAxis(elements.a); // double n = ; double M = elements.n * (JD0 - elements.T); elements.meanAnnomolyOut = M; double E = CAAKepler.Calculate(M, elements.e); E = CT.D2R(E); double v = 2 * Math.Atan(Math.Sqrt((1 + elements.e) / (1 - elements.e)) * Math.Tan(E / 2)); double r = elements.a * (1 - elements.e * Math.Cos(E)); double x = r * a * Math.Sin(A + w + v); double y = r * b * Math.Sin(B + w + v); double z = r * c * Math.Sin(C + w + v); //elements.meanAnnomolyOut contains the mean annomoly return(Vector3d.Create(x, y, z)); }
private static void ReadFromBin(BinaryReader br) { MPCList = new List <EOE>(); int len = (int)br.Length; EOE ee; try { while (br.Position < len) { ee = EOE.Create(br); MPCList.Add(ee); } } catch { } br.Close(); }
public static Vector3d CalculateRectangular(EOE elements, double meanAnomoly) { // double JD0 = JD; double omega = CT.D2R(elements.omega); double w = CT.D2R(elements.w); double i = CT.D2R(elements.i); double sinEpsilon = 0; double cosEpsilon = 1; double sinOmega = Math.Sin(omega); double cosOmega = Math.Cos(omega); double cosi = Math.Cos(i); double sini = Math.Sin(i); double F = cosOmega; double G = sinOmega * cosEpsilon; double H = sinOmega * sinEpsilon; double P = -sinOmega * cosi; double Q = cosOmega * cosi * cosEpsilon - sini * sinEpsilon; double R = cosOmega * cosi * sinEpsilon + sini * cosEpsilon; double a = Math.Sqrt(F * F + P * P); double b = Math.Sqrt(G * G + Q * Q); double c = Math.Sqrt(H * H + R * R); double A = Math.Atan2(F, P); double B = Math.Atan2(G, Q); double C = Math.Atan2(H, R); double n = elements.n; double M = meanAnomoly; double E = CAAKepler.Calculate(M, elements.e); E = CT.D2R(E); double v = 2 * Math.Atan(Math.Sqrt((1 + elements.e) / (1 - elements.e)) * Math.Tan(E / 2)); double r = elements.a * (1 - elements.e * Math.Cos(E)); double x = r * a * Math.Sin(A + w + v); double y = r * b * Math.Sin(B + w + v); double z = r * c * Math.Sin(C + w + v); return(Vector3d.Create(x, y, z)); }
public static Vector3d CalculateRectangularJD(double JD, EOE elements) { double JD0 = JD; double omega = CT.D2R(elements.omega); double w = CT.D2R(elements.w); double i = CT.D2R(elements.i); double sinEpsilon = 0; double cosEpsilon = 1; double sinOmega = Math.Sin(omega); double cosOmega = Math.Cos(omega); double cosi = Math.Cos(i); double sini = Math.Sin(i); double F = cosOmega; double G = sinOmega * cosEpsilon; double H = sinOmega * sinEpsilon; double P = -sinOmega * cosi; double Q = cosOmega * cosi * cosEpsilon - sini * sinEpsilon; double R = cosOmega * cosi * sinEpsilon + sini * cosEpsilon; double a = Math.Sqrt(F * F + P * P); double b = Math.Sqrt(G * G + Q * Q); double c = Math.Sqrt(H * H + R * R); double A = Math.Atan2(F, P); double B = Math.Atan2(G, Q); double C = Math.Atan2(H, R); //double n = CAAElliptical.MeanMotionFromSemiMajorAxis(elements.a); // double n = ; double M = elements.n * (JD0 - elements.T); elements.meanAnnomolyOut = M; double E = CAAKepler.Calculate(M, elements.e); E = CT.D2R(E); double v = 2 * Math.Atan(Math.Sqrt((1 + elements.e) / (1 - elements.e)) * Math.Tan(E / 2)); double r = elements.a * (1 - elements.e * Math.Cos(E)); double x = r * a * Math.Sin(A + w + v); double y = r * b * Math.Sin(B + w + v); double z = r * c * Math.Sin(C + w + v); //elements.meanAnnomolyOut contains the mean annomoly return Vector3d.Create(x, y, z); }
public static Vector3d CalculateRectangular(EOE elements, double meanAnomoly) { // double JD0 = JD; double omega = CT.D2R(elements.omega); double w = CT.D2R(elements.w); double i = CT.D2R(elements.i); double sinEpsilon = 0; double cosEpsilon = 1; double sinOmega = Math.Sin(omega); double cosOmega = Math.Cos(omega); double cosi = Math.Cos(i); double sini = Math.Sin(i); double F = cosOmega; double G = sinOmega * cosEpsilon; double H = sinOmega * sinEpsilon; double P = -sinOmega * cosi; double Q = cosOmega * cosi * cosEpsilon - sini * sinEpsilon; double R = cosOmega * cosi * sinEpsilon + sini * cosEpsilon; double a = Math.Sqrt(F * F + P * P); double b = Math.Sqrt(G * G + Q * Q); double c = Math.Sqrt(H * H + R * R); double A = Math.Atan2(F, P); double B = Math.Atan2(G, Q); double C = Math.Atan2(H, R); double n = elements.n; double M = meanAnomoly; double E = CAAKepler.Calculate(M, elements.e); E = CT.D2R(E); double v = 2 * Math.Atan(Math.Sqrt((1 + elements.e) / (1 - elements.e)) * Math.Tan(E / 2)); double r = elements.a * (1 - elements.e * Math.Cos(E)); double x = r * a * Math.Sin(A + w + v); double y = r * b * Math.Sin(B + w + v); double z = r * c * Math.Sin(C + w + v); return Vector3d.Create(x, y, z); }
public static EOD CalculateElements(double JD, EOE elements) { double Epsilon = CAANutation.MeanObliquityOfEcliptic(elements.JDEquinox); double JD0 = JD; //What will be the return value EOD details = new EOD(); Epsilon = CT.D2R(Epsilon); double omega = CT.D2R(elements.omega); double w = CT.D2R(elements.w); double i = CT.D2R(elements.i); double sinEpsilon = Math.Sin(Epsilon); double cosEpsilon = Math.Cos(Epsilon); double sinOmega = Math.Sin(omega); double cosOmega = Math.Cos(omega); double cosi = Math.Cos(i); double sini = Math.Sin(i); double F = cosOmega; double G = sinOmega * cosEpsilon; double H = sinOmega * sinEpsilon; double P = -sinOmega * cosi; double Q = cosOmega *cosi *cosEpsilon - sini *sinEpsilon; double R = cosOmega *cosi *sinEpsilon + sini *cosEpsilon; double a = Math.Sqrt(F *F + P *P); double b = Math.Sqrt(G *G + Q *Q); double c = Math.Sqrt(H *H + R *R); double A = Math.Atan2(F, P); double B = Math.Atan2(G, Q); double C = Math.Atan2(H, R); double n = ELL.MeanMotionFromSemiMajorAxis(elements.a); C3D SunCoord = CAASun.EquatorialRectangularCoordinatesAnyEquinox(JD, elements.JDEquinox); for (int j =0; j<2; j++) { double M = n * (JD0 - elements.T); double E = CAAKepler.Calculate(M, elements.e); E = CT.D2R(E); double v = 2 *Math.Atan(Math.Sqrt((1 + elements.e) / (1 - elements.e)) * Math.Tan(E/2)); double r = elements.a * (1 - elements.e *Math.Cos(E)); double x = r * a * Math.Sin(A + w + v); double y = r * b * Math.Sin(B + w + v); double z = r * c * Math.Sin(C + w + v); if (j == 0) { details.HeliocentricRectangularEquatorial.X = x; details.HeliocentricRectangularEquatorial.Y = y; details.HeliocentricRectangularEquatorial.Z = z; //Calculate the heliocentric ecliptic coordinates also double u = omega + v; double cosu = Math.Cos(u); double sinu = Math.Sin(u); details.HeliocentricRectangularEcliptical.X = r * (cosOmega *cosu - sinOmega *sinu *cosi); details.HeliocentricRectangularEcliptical.Y = r * (sinOmega *cosu + cosOmega *sinu *cosi); details.HeliocentricRectangularEcliptical.Z = r *sini *sinu; details.HeliocentricEclipticLongitude = Math.Atan2(y, x); details.HeliocentricEclipticLongitude = CT.M24(CT.R2D(details.HeliocentricEclipticLongitude) / 15); details.HeliocentricEclipticLatitude = Math.Asin(z / r); details.HeliocentricEclipticLatitude = CT.R2D(details.HeliocentricEclipticLatitude); } double psi = SunCoord.X + x; double nu = SunCoord.Y + y; double sigma = SunCoord.Z + z; double Alpha = Math.Atan2(nu, psi); Alpha = CT.R2D(Alpha); double Delta = Math.Atan2(sigma, Math.Sqrt(psi *psi + nu *nu)); Delta = CT.R2D(Delta); double Distance = Math.Sqrt(psi *psi + nu *nu + sigma *sigma); if (j == 0) { details.TrueGeocentricRA = CT.M24(Alpha / 15); details.TrueGeocentricDeclination = Delta; details.TrueGeocentricDistance = Distance; details.TrueGeocentricLightTime = DistanceToLightTime(Distance); } else { details.AstrometricGeocenticRA = CT.M24(Alpha / 15); details.AstrometricGeocentricDeclination = Delta; details.AstrometricGeocentricDistance = Distance; details.AstrometricGeocentricLightTime = DistanceToLightTime(Distance); double RES = Math.Sqrt(SunCoord.X *SunCoord.X + SunCoord.Y *SunCoord.Y + SunCoord.Z *SunCoord.Z); details.Elongation = Math.Acos((RES *RES + Distance *Distance - r *r) / (2 * RES * Distance)); details.Elongation = CT.R2D(details.Elongation); details.PhaseAngle = Math.Acos((r *r + Distance *Distance - RES *RES) / (2 * r * Distance)); details.PhaseAngle = CT.R2D(details.PhaseAngle); } if (j == 0) //Prepare for the next loop around JD0 = JD - details.TrueGeocentricLightTime; } return details; }
//private Vector3d GetTragectoryPoint(double jNow, out Vector3d vector) //{ //int min = 0; //int max = Trajectory.Count - 1; //Vector3d point = new Vector3d(); //vector = new Vector3d(); //int current = max / 2; //bool found = false; //while (!found) //{ // if (current < 1) // { // vector = Trajectory[0].Position - Trajectory[1].Position; // return Trajectory[0].Position; // } // if (current == Trajectory.Count - 1) // { // vector = Trajectory[current - 1].Position - Trajectory[current].Position; // return Trajectory[current].Position; // } // if ((Trajectory[current-1].Time <= jNow) && (Trajectory[current].Time > jNow)) // { // double denominator = Trajectory[current].Time -Trajectory[current-1].Time; // double numerator = jNow - Trajectory[current - 1].Time; // double tween = numerator / denominator; // vector = Trajectory[current - 1].Position - Trajectory[current].Position; // point = Vector3d.Lerp(Trajectory[current - 1].Position, Trajectory[current].Position, tween); // return point; // } // if (Trajectory[current].Time < jNow) // { // int next = current + ( max - current + 1) / 2; // min = current; // current = next; // } // else // if (Trajectory[current - 1].Time > jNow) // { // int next = current - ( current - min + 1) / 2; // max = current; // current = next; // } //} //return point; //} private void ComputeOrbital(RenderContext renderContext) { EOE ee = Elements; Vector3d point = ELL.CalculateRectangularJD(SpaceTimeController.JNow, ee); Vector3d pointInstantLater = ELL.CalculateRectangular(ee, MeanAnomoly + .001); Vector3d direction = Vector3d.SubtractVectors(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; WorldMatrix = Matrix3d.Identity; Matrix3d look = Matrix3d.LookAtLH(Vector3d.Create(0, 0, 0), direction, up); look.Invert(); WorldMatrix = Matrix3d.Identity; double localScale = (1 / renderContext.NominalRadius) * Scale * MeanRadius; WorldMatrix.Scale(Vector3d.Create(localScale, localScale, localScale)); Matrix3d mat = Matrix3d.MultiplyMatrix(Matrix3d.MultiplyMatrix(Matrix3d.RotationY(Heading), Matrix3d.RotationX(Pitch)), Matrix3d.RotationZ(Roll)); if (RotationalPeriod != 0) { double rotationCurrent = (((SpaceTimeController.JNow - this.ZeroRotationDate) / RotationalPeriod) * 360) % (360); WorldMatrix.Multiply(Matrix3d.RotationX(-rotationCurrent)); } point = Vector3d.Scale(point, scaleFactor); WorldMatrix.Translate(point); if (StationKeeping) { WorldMatrix = Matrix3d.MultiplyMatrix(look, WorldMatrix); } }
public static EOD CalculateElements(double JD, EOE elements) { double Epsilon = CAANutation.MeanObliquityOfEcliptic(elements.JDEquinox); double JD0 = JD; //What will be the return value EOD details = new EOD(); Epsilon = CT.D2R(Epsilon); double omega = CT.D2R(elements.omega); double w = CT.D2R(elements.w); double i = CT.D2R(elements.i); double sinEpsilon = Math.Sin(Epsilon); double cosEpsilon = Math.Cos(Epsilon); double sinOmega = Math.Sin(omega); double cosOmega = Math.Cos(omega); double cosi = Math.Cos(i); double sini = Math.Sin(i); double F = cosOmega; double G = sinOmega * cosEpsilon; double H = sinOmega * sinEpsilon; double P = -sinOmega * cosi; double Q = cosOmega * cosi * cosEpsilon - sini * sinEpsilon; double R = cosOmega * cosi * sinEpsilon + sini * cosEpsilon; double a = Math.Sqrt(F * F + P * P); double b = Math.Sqrt(G * G + Q * Q); double c = Math.Sqrt(H * H + R * R); double A = Math.Atan2(F, P); double B = Math.Atan2(G, Q); double C = Math.Atan2(H, R); double n = ELL.MeanMotionFromSemiMajorAxis(elements.a); C3D SunCoord = CAASun.EquatorialRectangularCoordinatesAnyEquinox(JD, elements.JDEquinox); for (int j = 0; j < 2; j++) { double M = n * (JD0 - elements.T); double E = CAAKepler.Calculate(M, elements.e); E = CT.D2R(E); double v = 2 * Math.Atan(Math.Sqrt((1 + elements.e) / (1 - elements.e)) * Math.Tan(E / 2)); double r = elements.a * (1 - elements.e * Math.Cos(E)); double x = r * a * Math.Sin(A + w + v); double y = r * b * Math.Sin(B + w + v); double z = r * c * Math.Sin(C + w + v); if (j == 0) { details.HeliocentricRectangularEquatorial.X = x; details.HeliocentricRectangularEquatorial.Y = y; details.HeliocentricRectangularEquatorial.Z = z; //Calculate the heliocentric ecliptic coordinates also double u = omega + v; double cosu = Math.Cos(u); double sinu = Math.Sin(u); details.HeliocentricRectangularEcliptical.X = r * (cosOmega * cosu - sinOmega * sinu * cosi); details.HeliocentricRectangularEcliptical.Y = r * (sinOmega * cosu + cosOmega * sinu * cosi); details.HeliocentricRectangularEcliptical.Z = r * sini * sinu; details.HeliocentricEclipticLongitude = Math.Atan2(y, x); details.HeliocentricEclipticLongitude = CT.M24(CT.R2D(details.HeliocentricEclipticLongitude) / 15); details.HeliocentricEclipticLatitude = Math.Asin(z / r); details.HeliocentricEclipticLatitude = CT.R2D(details.HeliocentricEclipticLatitude); } double psi = SunCoord.X + x; double nu = SunCoord.Y + y; double sigma = SunCoord.Z + z; double Alpha = Math.Atan2(nu, psi); Alpha = CT.R2D(Alpha); double Delta = Math.Atan2(sigma, Math.Sqrt(psi * psi + nu * nu)); Delta = CT.R2D(Delta); double Distance = Math.Sqrt(psi * psi + nu * nu + sigma * sigma); if (j == 0) { details.TrueGeocentricRA = CT.M24(Alpha / 15); details.TrueGeocentricDeclination = Delta; details.TrueGeocentricDistance = Distance; details.TrueGeocentricLightTime = DistanceToLightTime(Distance); } else { details.AstrometricGeocenticRA = CT.M24(Alpha / 15); details.AstrometricGeocentricDeclination = Delta; details.AstrometricGeocentricDistance = Distance; details.AstrometricGeocentricLightTime = DistanceToLightTime(Distance); double RES = Math.Sqrt(SunCoord.X * SunCoord.X + SunCoord.Y * SunCoord.Y + SunCoord.Z * SunCoord.Z); details.Elongation = Math.Acos((RES * RES + Distance * Distance - r * r) / (2 * RES * Distance)); details.Elongation = CT.R2D(details.Elongation); details.PhaseAngle = Math.Acos((r * r + Distance * Distance - RES * RES) / (2 * r * Distance)); details.PhaseAngle = CT.R2D(details.PhaseAngle); } if (j == 0) //Prepare for the next loop around { JD0 = JD - details.TrueGeocentricLightTime; } } return(details); }
public void Fill(EOE ee) { double F = Math.Cos(ee.omega * degrad); double sinOmega = Math.Sin(ee.omega * degrad); double cosi = Math.Cos(ee.i * degrad); double sini = Math.Sin(ee.i * degrad); double G = sinOmega * cose; double H = sinOmega * sine; double P = -sinOmega * cosi; double Q = (F * cosi * cose) - (sini * sine); double R = (F * cosi * sine) + (sini * cose); double checkA = (F * F) + (G * G) + (H * H); // Should be 1.0 double checkB = (P * P) + (Q * Q) + (R * R); // should be 1.0 as well ABC.X = (float)Math.Atan2(F, P); ABC.Y = (float)Math.Atan2(G, Q); ABC.Z = (float)Math.Atan2(H, R); abc1.X = (float)Math.Sqrt((F * F) + (P * P)); abc1.Y = (float)Math.Sqrt((G * G) + (Q * Q)); abc1.Z = (float)Math.Sqrt((H * H) + (R * R)); PointSize = .1f; if (ee.a < 2.5) { Color = Colors.White; } else if (ee.a < 2.83) { Color = Colors.Red; } else if (ee.a < 2.96) { Color = Colors.Green; } else if (ee.a < 3.3) { Color = Colors.Magenta; } else if (ee.a < 5) { Color = Colors.Cyan; } else if (ee.a < 10) { Color = Colors.Yellow; PointSize = .9f; } else { Color = Colors.White; PointSize = 8f; } w = (float)ee.w; e = (float)ee.e; if (ee.n == 0) { n = (float)((0.9856076686 / (ee.a * Math.Sqrt(ee.a)))); } else { n = (float)ee.n; } T = (float)(ee.T - baseDate); a = (float)ee.a; z = 0; orbitPos = 0; orbits = 0; }