public PlanetElm(int planetNo, ATime atime) { switch (planetNo) { case Planet.EARTH: GetPlanetElmEarth(atime.JD); break; case Planet.MERCURY: case Planet.VENUS: case Planet.MARS: case Planet.JUPITER: case Planet.SATURN: GetPlanetElm1(planetNo, atime.JD); break; case Planet.URANUS: case Planet.NEPTUNE: case Planet.PLUTO: GetPlanetElm2(planetNo, atime.JD); break; default: throw new ArithmeticException(); } }
private void UpdateRotationMatrix(ATime atime) { if (PaintEnabled) { Matrix mtxPrec = Matrix.PrecMatrix(Astro.JD2000, atime.JD); Matrix mtxEqt2Ecl = Matrix.RotateX(ATime.GetEp(atime.JD)); MtxToEcl = mtxEqt2Ecl.Mul(mtxPrec); EpochToEcl = atime.JD; } }
public void LoadPanel(Comet comet, ATime atime) { Comet = comet; ATime = atime; ObjectOrbit = new CometOrbit(Comet, 1000); UpdatePositions(atime); UpdatePlanetOrbit(atime); UpdateRotationMatrix(atime); }
private void UpdatePositions(ATime atime) { if (PaintEnabled) { ObjectPos = Comet.GetPos(atime.JD); for (int i = 0; i < 9; i++) { PlanetPos[i] = Planet.GetPos(Planet.MERCURY + i, atime); } } }
/// <summary> /// Limit ATime between minATime and maxATime /// </summary> /// <param name="atime"></param> /// <returns></returns> public static ATime LimitATime(ATime atime) { if (atime.GetJD() <= MinATime.GetJD()) { atime = new ATime(MinATime); } else if (atime.GetJD() >= MaxATime.GetJD()) { atime = new ATime(MaxATime); } return(atime); }
public ATime(ATime atime) { this.Year = atime.Year; this.Month = atime.Month; this.Day = atime.Day; this.Hour = atime.Hour; this.Minute = atime.Minute; this.Second = atime.Second; this.JD = atime.JD; this.Timezone = atime.Timezone; this.T = atime.T; this.T2 = atime.T2; }
private void UpdatePlanetOrbit(ATime atime) { if (PaintEnabled) { int nDivision = 300; for (int i = Planet.MERCURY; i <= Planet.PLUTO; i++) { PlanetOrbit[i - Planet.MERCURY] = new PlanetOrbit(i, atime, nDivision); } EpochPlanetOrbit = atime.JD; } }
/// <summary> /// Get Vector Constant from Angle Elements /// </summary> /// <param name="peri"></param> /// <param name="node"></param> /// <param name="incl"></param> /// <param name="equinox"></param> /// <returns></returns> public static Matrix VectorConstant(double peri, double node, double incl, ATime equinox) { // Equinox double t1 = equinox.T; double t2 = equinox.T2; // Obliquity of Ecliptic double eps; if (t2 < -40.0) { eps = 23.83253 * Math.PI / 180.0; } else if (t2 > 40.0) { eps = 23.05253 * Math.PI / 180.0; } else { eps = 23.44253 - 0.00013 * t1 + 0.00256 * Math.Cos((249.0 - 19.3 * t1) * Math.PI / 180.0) + 0.00015 * Math.Cos((198.0 + 720.0 * t1) * Math.PI / 180.0); eps *= Math.PI / 180.0; } double sinEps = Math.Sin(eps); double cosEps = Math.Cos(eps); double sinPeri = Math.Sin(peri); double sinNode = Math.Sin(node); double sinIncl = Math.Sin(incl); double cosPeri = Math.Cos(peri); double cosNode = Math.Cos(node); double cosIncl = Math.Cos(incl); double wa = cosPeri * sinNode + sinPeri * cosIncl * cosNode; double wb = -sinPeri * sinNode + cosPeri * cosIncl * cosNode; double a11 = cosPeri * cosNode - sinPeri * cosIncl * sinNode; double a21 = wa * cosEps - sinPeri * sinIncl * sinEps; double a31 = wa * sinEps + sinPeri * sinIncl * cosEps; double a12 = -sinPeri * cosNode - cosPeri * cosIncl * sinNode; double a22 = wb * cosEps - cosPeri * sinIncl * sinEps; double a32 = wb * sinEps + cosPeri * sinIncl * cosEps; return(new Matrix(a11, a12, 0.0, a21, a22, 0.0, a31, a32, 0.0)); }
public PlanetOrbit(int planetNo, ATime atime, int division) { this.PlanetNo = planetNo; this.JD = atime.JD; this.Division = division; PlanetElm planetElm = new PlanetElm(planetNo, atime); this.Orbit = new Xyz[division + 1]; DoGetPlanetOrbit(planetElm); Matrix vec = Matrix.VectorConstant(planetElm.w * Math.PI / 180.0, planetElm.N * Math.PI / 180.0, planetElm.i * Math.PI / 180.0, atime); Matrix prec = Matrix.PrecMatrix(atime.JD, 2451512.5); for (int i = 0; i <= division; i++) { this.Orbit[i] = this.Orbit[i].Rotate(vec).Rotate(prec); } }
public static Xyz GetPos(int planetNo, ATime atime) { switch (planetNo) { case Planet.EARTH: return(GetPosExp0(atime.T)); case Planet.VENUS: case Planet.MARS: return(GetPosExp1(planetNo, atime.T)); case Planet.JUPITER: case Planet.SATURN: return(GetPosExp2(planetNo, atime.T)); case Planet.MERCURY: case Planet.URANUS: case Planet.NEPTUNE: case Planet.PLUTO: return(GetPosExp3(planetNo, atime.T2)); } return(null); }
/// <summary> /// Create Precession Matrix /// </summary> /// <param name="oldEpoch"></param> /// <param name="newEpoch"></param> /// <returns></returns> public static Matrix PrecMatrix(double oldEpoch, double newEpoch) { double jd = 0.0; bool swapEpoch = false; bool outerNewcomb = false; if (newEpoch == oldEpoch) { return(new Matrix(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)); } double T = (oldEpoch - Astro.JD2000) / 36525.0; if (T < -PrecLimit || PrecLimit < T) { swapEpoch = true; double temp = newEpoch; newEpoch = oldEpoch; oldEpoch = temp; T = (oldEpoch - Astro.JD2000) / 36525.0; } double T2 = T * T; double tt, t; tt = t = (newEpoch - oldEpoch) / 36525.0; if (tt < -PrecLimit) { outerNewcomb = true; t = -PrecLimit; jd = -PrecLimit * 36525.0 + Astro.JD2000; } if (PrecLimit < tt) { outerNewcomb = true; t = PrecLimit; jd = PrecLimit * 36525.0 + Astro.JD2000; } double t2 = t * t; double t3 = t2 * t; double zeta0 = ((2306.2181 + 1.39656 * T - 0.000139 * T2) * t + (0.30188 - 0.000344 * T) * t2 + 0.017998 * t3) / 3600.0; double zpc = ((2306.2181 + 1.39656 * T - 0.000139 * T2) * t + (1.09468 + 0.000066 * T) * t2 + 0.018203 * t3) / 3600.0; double theta = ((2004.3109 - 0.85330 * T - 0.000217 * T2) * t - (0.42665 + 0.000217 * T) * t2 - 0.041833 * t3) / 3600.0; Matrix mtx1, mtx2, mtx3; mtx1 = RotateZ((90.0 - zeta0) * Math.PI / 180.0); mtx2 = RotateX(theta * Math.PI / 180.0); mtx3 = mtx2.Mul(mtx1); mtx1 = RotateZ((-90 - zpc) * Math.PI / 180.0); Matrix mtxPrec; mtxPrec = mtx1.Mul(mtx3); if (outerNewcomb) { double dJd; if (tt < -PrecLimit) { dJd = (newEpoch - oldEpoch) + PrecLimit * 36525.0; } else { dJd = (newEpoch - oldEpoch) - PrecLimit * 36525.0; } double precPrm = -dJd / 365.24 * GeneralPrec * Math.PI / 180.0; double eps = ATime.GetEp(jd); mtx1 = RotateX(eps); mtx2 = RotateZ(precPrm); mtx3 = mtx2.Mul(mtx1); mtx2 = RotateX(-eps); mtx1 = mtx2.Mul(mtx3); mtxPrec = mtx1.Mul(mtxPrec); } if (swapEpoch) { mtxPrec.Invert(); } return(mtxPrec); }
public void ChangeDate(ATimeSpan span, int direction) { // // First, calculate new Hour,Minute,Second // double hms1 = this.Hour * 60.0 * 60.0 + this.Minute * 60.0 + this.Second; double hms2 = span.Hour * 60.0 * 60.0 + span.Minute * 60.0 + span.Second; hms1 += hms2 * direction; int day; if (0.0 <= hms1 && hms1 < 24.0 * 60.0 * 60.0) { day = 0; } else if (hms1 >= 24.0 * 60.0 * 60.0) { day = (int)Math.Floor(hms1 / 24.0 / 60.0 / 60.0); hms1 = UdMath.fmod(hms1, 24.0 * 60.0 * 60.0); } else { day = (int)Math.Ceiling(hms1 / 24.0 / 60.0 / 60.0) - 1; hms1 = UdMath.fmod(hms1, 24.0 * 60.0 * 60.0) + 24.0 * 60.0 * 60.0; } int newHour = (int)Math.Floor(hms1 / 60.0 / 60.0); int newMin = (int)Math.Floor(hms1 / 60.0) - newHour * 60; double newSec = hms1 - ((double)newHour * 60.0 * 60.0 + (double)newMin * 60.0); // // Next, calculate new Year, Month, Day // ATime newDate = new ATime(this.Year, this.Month, this.Day, 12, 0, 0.0, 0.0); double jd = newDate.JD; jd += day + span.Day * direction; newDate = new ATime(jd, 0.0); int newYear = newDate.Year; int newMonth = newDate.Month; int newDay = newDate.Day; newMonth += span.Month * direction; if (1 > newMonth) { newYear -= newMonth / 12 + 1; newMonth = 12 + newMonth % 12; } else if (newMonth > 12) { newYear += newMonth / 12; newMonth = 1 + (newMonth - 1) % 12; } newYear += span.Year * direction; // check bound between julian and gregorian if (newYear == 1582 && newMonth == 10) { if (5 <= newDay && newDay < 10) { newDay = 4; } else if (10 <= newDay && newDay < 15) { newDay = 15; } } newDate = LimitATime(new ATime(newYear, newMonth, newDay, 12, 0, 0, 0.0)); newYear = newDate.Year; newMonth = newDate.Month; newDay = newDate.Day; this.Year = newYear; this.Month = newMonth; this.Day = newDay; this.Hour = newHour; this.Minute = newMin; this.Second = newSec; this.JD = GetJD() - this.Timezone / 24.0; this.T = GetT(); this.T2 = GetT2(); }
public void Update(Graphics g) { Point point3; Xyz xyz, xyz1; // Calculate Drawing Parameter Matrix mtxRotH = Matrix.RotateZ(RotateHorz * Math.PI / 180.0); Matrix mtxRotV = Matrix.RotateX(RotateVert * Math.PI / 180.0); MtxRotate = mtxRotV.Mul(mtxRotH); X0 = Size.Width / 2; Y0 = Size.Height / 2; if (Math.Abs(EpochToEcl - ATime.JD) > 365.2422 * 5) { UpdateRotationMatrix(ATime); } if (CenterObjectSelected == (int)CenteredObjectEnum.CometAsteroid) { xyz = ObjectPos.Rotate(MtxToEcl).Rotate(MtxRotate); point3 = GetDrawPoint(xyz); X0 = Size.Width - point3.X; Y0 = Size.Height - point3.Y; } else if (CenterObjectSelected >= (int)CenteredObjectEnum.Mercury) { xyz = PlanetPos[CenterObjectSelected - 2].Rotate(MtxRotate); point3 = GetDrawPoint(xyz); X0 = Size.Width - point3.X; Y0 = Size.Height - point3.Y; } using (Graphics graphics = Graphics.FromImage(Offscreen)) { Pen pen = new Pen(Color.White); // Clear background SolidBrush sb = new SolidBrush(Color.Black); graphics.FillRectangle(sb, 0, 0, Size.Width, Size.Height); DrawEclipticAxis(graphics); // Draw Sun sb.Color = ColorSun; graphics.FillPie(sb, X0 - 2, Y0 - 2, 5, 5, 0, 360); // Draw Orbit of Object xyz = ObjectOrbit.GetAt(0).Rotate(MtxToEcl).Rotate(MtxRotate); Point point1, point2; point1 = GetDrawPoint(xyz); if (OrbitDisplay[(int)OrbitDisplayEnum.CometAsteroid]) { for (int i = 1; i <= ObjectOrbit.Division; i++) { xyz = ObjectOrbit.GetAt(i).Rotate(MtxToEcl); pen.Color = xyz.Z >= 0.0 ? ColorObjectOrbitUpper : ColorObjectOrbitLower; xyz = xyz.Rotate(MtxRotate); point2 = GetDrawPoint(xyz); graphics.DrawLine(pen, point1.X, point1.Y, point2.X, point2.Y); point1 = point2; } } // Draw Object Body sb.Color = ColorObject; xyz = ObjectPos.Rotate(MtxToEcl).Rotate(MtxRotate); point1 = GetDrawPoint(xyz); graphics.FillPie(sb, point1.X - 2, point1.Y - 2, 5, 5, 0, 360); if (ShowObjectName) { sb.Color = ColorObjectName; graphics.DrawString(Comet.Name, FontObjectName, sb, point1.X + 5, point1.Y); } // Draw Orbit of Planets if (Math.Abs(EpochPlanetOrbit - ATime.JD) > 365.2422 * 5) { UpdatePlanetOrbit(ATime); } double zoom = 30.0; if (Zoom * 39.5 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Pluto]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.PLUTO - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitLower); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[8], "Pluto"); } if (Zoom * 30.1 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Neptune]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.NEPTUNE - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitLower); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[7], "Neptune"); } if (Zoom * 19.2 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Uranus]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.URANUS - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitLower); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[6], "Uranus"); } if (Zoom * 9.58 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Saturn]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.SATURN - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitLower); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[5], "Saturn"); } if (Zoom * 5.2 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Jupiter]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.JUPITER - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitLower); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[4], "Jupiter"); } if (Zoom * 1.524 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Mars]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.MARS - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitLower); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[3], "Mars"); } if (Zoom * 1.0 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Earth]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.EARTH - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitUpper); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[2], "Earth"); } if (Zoom * 0.723 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Venus]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.VENUS - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitLower); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[1], "Venus"); } if (Zoom * 0.387 >= zoom) { if (OrbitDisplay[(int)OrbitDisplayEnum.Mercury]) { DrawPlanetOrbit(graphics, PlanetOrbit[Planet.MERCURY - 1], ColorPlanetOrbitUpper, ColorPlanetOrbitLower); } DrawPlanetBody(graphics, FontPlanetName, PlanetPos[0], "Mercury"); } // Information sb.Color = ColorInformation; // Object Name string int labelMargin = 8; double fontSize = (double)FontInformation.Size; point1.X = labelMargin; point1.Y = labelMargin; graphics.DrawString(Comet.Name, FontInformation, sb, point1.X, point1.Y); if (ShowDistanceLabel) { // Earth & Sun Distance double edistance, sdistance; double xdiff, ydiff, zdiff; string dstr, rstr; xyz = ObjectPos.Rotate(MtxToEcl).Rotate(MtxRotate); xyz1 = PlanetPos[2].Rotate(MtxRotate); sdistance = Math.Sqrt((xyz.X * xyz.X) + (xyz.Y * xyz.Y) + (xyz.Z * xyz.Z)) + .0005; xdiff = xyz.X - xyz1.X; ydiff = xyz.Y - xyz1.Y; zdiff = xyz.Z - xyz1.Z; edistance = Math.Sqrt((xdiff * xdiff) + (ydiff * ydiff) + (zdiff * zdiff)) + .0005; dstr = String.Format("Earth Distance: {0:#0.0000} AU", edistance); rstr = String.Format("Sun Distance: {0:#0.0000} AU", sdistance); point1.Y = Size.Height - labelMargin - (int)(fontSize * 3.5); graphics.DrawString(dstr, FontInformation, sb, point1.X, point1.Y); point1.Y = Size.Height - labelMargin - (int)(fontSize * 2.0); graphics.DrawString(rstr, FontInformation, sb, point1.X, point1.Y); } if (ShowDateLabel) { // Date string string strDate = String.Format("{0} {1}, {2}", ATime.MonthAbbr(ATime.Month), ATime.Day, ATime.Year); point1.X = Size.Width - (int)graphics.MeasureString(strDate, FontInformation).Width - labelMargin; point1.Y = Size.Height - labelMargin - (int)(fontSize * 2.0); graphics.DrawString(strDate, FontInformation, sb, point1.X, point1.Y); } } g.DrawImage(Offscreen, 0, 0); }