public void TakiExample5_4_4() { using (AscomTools tools = new AscomTools()) { Angle longitude = new Angle("-1°20'20.54\""); tools.Transform.SiteLatitude = new Angle("52°40'6.38\""); tools.Transform.SiteLongitude = longitude; tools.Transform.SiteElevation = 175.5; DateTime initialTime = new DateTime(2017, 03, 28, 21, 0, 0); DateTime observationTime = new DateTime(2017, 03, 28, 21, 27, 56); MountCoordinate star1 = new MountCoordinate(new EquatorialCoordinate("0h7m54.0s", "29.038°"), new AxisPosition(1.732239, 1.463808, true), tools, observationTime); observationTime = new DateTime(2017, 03, 28, 21, 37, 02); MountCoordinate star2 = new MountCoordinate(new EquatorialCoordinate("2h21m45.0s", "89.222°"), new AxisPosition(5.427625, 0.611563, true), tools, observationTime); TakiEQMountMapper taki = new TakiEQMountMapper(star1, star2, initialTime); EquatorialCoordinate bCet = new EquatorialCoordinate("0h43m07s", "-18.038°"); DateTime targetTime = new DateTime(2017, 03, 28, 21, 52, 12); AxisPosition bCetExpected = new AxisPosition(2.27695654215, 0.657465529226, true); // 130.46°, 37.67° AxisPosition bCetCalculated = taki.GetAxisPosition(bCet, targetTime); System.Diagnostics.Debug.WriteLine("Expected: {0}, calculated: {1}", bCetExpected, bCetCalculated); double tolerance = 0.5; // degrees. bool testResult = ((Math.Abs(bCetExpected.DecAxis - bCetCalculated.DecAxis) < tolerance) && (Math.Abs(bCetExpected.RAAxis - bCetCalculated.RAAxis) < tolerance)); Assert.IsTrue(testResult); } }
///* given geographical latitude (n+, radians), lt, altitude (up+, radians), // * alt, and azimuth (angle round to the east from north+, radians), // * return hour angle (radians), ha, and declination (radians), dec. // */ //public static void AltAzToHaDec(double latitude, double altitude, double azimuth, ref double hourAngle, ref double declination) //{ // aaha_aux(latitude, azimuth, altitude, ref hourAngle, ref declination); // if (hourAngle > Math.PI) // hourAngle -= 2 * Math.PI; //} //public static EquatorialCoordinate GetEquatorial(AltAzCoordinate altAz, Angle latitude, Angle longitude, DateTime localTime) //{ // double hourAngle = 0.0; // double declination = 0.0; // aaha_aux(latitude.Radians, altAz.Azimuth.Radians, altAz.Altitude.Radians, ref hourAngle, ref declination); // if (hourAngle > Math.PI) // hourAngle -= 2 * Math.PI; // // LHA = LST - Ra // double lst = AstroConvert.LocalApparentSiderealTime(longitude.Value, localTime); // double rightAscension = lst - hourAngle; // return new EquatorialCoordinate(new HourAngle(rightAscension, true), new Angle(declination, true)); //} ///* given geographical (n+, radians), lt, hour angle (radians), ha, and // * declination (radians), dec, return altitude (up+, radians), alt, and // * azimuth (angle round to the east from north+, radians), //*/ //public static void HaDecToAltAz(double latitude, double hourAngle, double declination, ref double altitude, ref double azimuth) //{ // aaha_aux(latitude, hourAngle, declination, ref azimuth, ref altitude); //} public static AltAzCoordinate GetAltAz(EquatorialCoordinate equatorial, Angle latitude) { double alt = 0.0; double az = 0.0; Aaha_Aux(latitude.Radians, equatorial.RightAscension.Radians, equatorial.Declination.Radians, ref alt, ref az); return(new AltAzCoordinate(new Angle(alt, true), new Angle(az, true))); }
public void GetNCPEquatorial() { MountCoordinate mount = new MountCoordinate(new AxisPosition(0.0, 0.0), _Tools, _Now); EquatorialCoordinate currentRaDec = mount.Equatorial; Assert.AreEqual(2.00536, currentRaDec.RightAscension.Value, 0.00001, "RA Value"); Assert.AreEqual(90.0, currentRaDec.Declination.Value, 0.001, "Declination value"); }
public void SlewDec(double slewAngle, double expectedDec) { MountCoordinate currentPosition = new MountCoordinate(new AxisPosition(0.0, 0.0), _Tools, _Now); currentPosition.MoveRADec(new AxisPosition(0.0, slewAngle), _Tools, _Now); EquatorialCoordinate expected = new EquatorialCoordinate(currentPosition.Equatorial.RightAscension.Value, expectedDec); Assert.AreEqual(expected, currentPosition.Equatorial, "Slewed DEC test"); }
public void TestFromAxisDelta(double dRa, double dDec, double rRa, double rDec) { EquatorialCoordinate datum = new EquatorialCoordinate(0.0, 0.0); double[] delta = new double[] { dRa, dDec }; EquatorialCoordinate result = datum.SlewBy(delta); EquatorialCoordinate expected = new EquatorialCoordinate(rRa, rDec); Assert.AreEqual(expected, result); }
private static void TestCoordinateNorthPole1() { var northpole = new EquatorialCoordinate((Angle)13.7, Angle.FromDegrees(90.0)); var moment = new DateTimeOffset(2012, 5, 7, 23, 20, 12, TimeSpan.FromHours(2)); // If we're on the Earth's pole, Polaris is straight up var result = northpole.GetHorizontalCoordinate(moment, (Angle)34.2, Angle.FromDegrees(90)); AssertEqual(result.Altitude.Degrees, 90.0); }
private static void TestCoordinateNorthPole2() { var northpole = new EquatorialCoordinate((Angle)13.7, Angle.FromDegrees(90.0)); var moment = new DateTimeOffset(2012, 5, 7, 23, 20, 12, TimeSpan.FromHours(2)); var result = northpole.GetHorizontalCoordinate(moment, maassluisLon, maassluisLat); AssertEqual(result.Altitude, maassluisLat); AssertEqual(result.Azimuth, 0.0); }
public void TestCalculateTargetAxis(double targetRa, double targetDec, double expectedAxisRa, double expectedAxisDec, bool decFlipped) { EquatorialCoordinate target = _Tools.GetEquatorial(0.0, 0.0, _Now); MountCoordinate mount = new MountCoordinate(new AxisPosition(0.0, 0.0), _Tools, _Now); AxisPosition axisPosition = mount.GetAxisPositionForRADec(targetRa, targetDec, _Tools); Assert.AreEqual(expectedAxisRa, axisPosition.RAAxis, 0.000001, "RA Axis"); Assert.AreEqual(expectedAxisDec, axisPosition.DecAxis, 0.000001, "Dec Axis"); Assert.AreEqual(decFlipped, axisPosition.DecFlipped, "Dec flipped"); }
private static void TestCoordinateVega() { var vega = new EquatorialCoordinate(Angle.FromTime(new TimeSpan(18, 36, 56)), Angle.FromDegrees(38, 47, 3)); var moment = new DateTimeOffset(2012, 5, 7, 23, 20, 12, TimeSpan.FromHours(2)); // 23:56:04 var result = vega.GetHorizontalCoordinate(moment, maassluisLon, maassluisLat); // expected values from Stellarium AssertEqual(result.Azimuth, Angle.FromDegrees(64, 19, 06)); AssertEqual(result.Altitude, Angle.FromDegrees(30, 09, 21)); }
private static void TestCoordinateVegaOnEpoch() { var vega = new EquatorialCoordinate(Angle.FromTime(new TimeSpan(18, 36, 56)), Angle.FromDegrees(38, 47, 3)); var moment = Constants.J2000Epoch; // 17:05:30 HorizontalCoordinate result; result = vega.GetHorizontalCoordinate(moment, maassluisLon, maassluisLat); // expected values from Stellarium AssertEqual(result.Azimuth, Angle.FromDegrees(197, 29, 13)); AssertEqual(result.Altitude, Angle.FromDegrees(76, 22, 16)); }
public void SlewRA(double slewAngle, double expectedRA) { MountCoordinate currentPosition = new MountCoordinate(new AxisPosition(0.0, 0.0), _Tools, _Now); double targetRA = AstroConvert.RangeRA(currentPosition.Equatorial.RightAscension.Value + expectedRA); double targetDec = currentPosition.Equatorial.Declination.Value; currentPosition.MoveRADec(new AxisPosition(slewAngle, 0.0), _Tools, _Now); EquatorialCoordinate expected = new EquatorialCoordinate(targetRA, targetDec); Assert.AreEqual(expected.RightAscension, currentPosition.Equatorial.RightAscension, 0.000001, "RA test"); Assert.AreEqual(expected.Declination, currentPosition.Equatorial.Declination, 0.000001, "DEc test"); }
public void TestGetDec(double expectedRA, double expectedDec, double RAAxis, double DecAxis, bool decFlipped) { EquatorialCoordinate target = _Tools.GetEquatorial(0.0, 0.0, _Now); MountCoordinate mount = new MountCoordinate( new AltAzCoordinate(_Tools.Transform.SiteLatitude, 0.0), new AxisPosition(0.0, 0.0), _Tools, _Now); AxisPosition axisPosition = new AxisPosition(RAAxis, DecAxis); Angle testDec = mount.GetDec(axisPosition); Assert.AreEqual(expectedDec, testDec, 0.000001, "Dec Value"); }
public void NorthHorizonAltAz() { EquatorialCoordinate target = _Tools.GetEquatorial(0.0, 0.0, _Now); MountCoordinate mount = new MountCoordinate(new AxisPosition(0.0, 0.0), _Tools, _Now); AxisPosition targetAxisPosition = mount.GetAxisPositionForRADec(target.RightAscension, target.Declination, _Tools); mount.MoveRADec(targetAxisPosition, _Tools, _Now); EquatorialCoordinate testRaDec = mount.Equatorial; // Assert.AreEqual(PierSide.pierEast, mount.GetPointingSideOfPier(false), "Pointing side of pier"); Assert.AreEqual(7.98608, testRaDec.RightAscension.Value, 0.00001, "RA Value"); Assert.AreEqual(37.333, testRaDec.Declination.Value, 0.001, "Declination value"); Assert.AreEqual(307.333, mount.ObservedAxes[1], 0.001, "Declination axis value"); }
public void SouthEastHorizonAltAz() { EquatorialCoordinate target = _Tools.GetEquatorial(0.0, 135.0, _Now); MountCoordinate mount = new MountCoordinate(new AxisPosition(0.0, 0.0), _Tools, _Now); AxisPosition targetAxisPosition = mount.GetAxisPositionForRADec(target.RightAscension, target.Declination, _Tools); mount.MoveRADec(targetAxisPosition, _Tools, _Now); EquatorialCoordinate testRaDec = mount.Equatorial; // Assert.AreEqual(PierSide.pierWest, mount.GetPointingSideOfPier(false), "Pointing side of pier"); Assert.AreEqual(23.42014, testRaDec.RightAscension.Value, 0.00001, "RA Value"); Assert.AreEqual(-25.39285, testRaDec.Declination.Value, 0.001, "Declination value"); Assert.AreEqual(244.60715, mount.ObservedAxes[1], 0.001, "Declination axis value"); }
public void TestGetRA(double expectedRa, double expectedDec, double RAAxis, double DecAxis, bool flippedDec) { EquatorialCoordinate target = _Tools.GetEquatorial(0.0, 0.0, _Now); MountCoordinate mount = new MountCoordinate( new AltAzCoordinate(_Tools.Transform.SiteLatitude, 0.0), new AxisPosition(0.0, 0.0), _Tools, _Now); AxisPosition axisPosition = new AxisPosition(RAAxis, DecAxis, flippedDec); System.Diagnostics.Debug.Write($"\nFlipped:{(flippedDec ? "Y" : "N")} Expecting: {expectedRa} ->"); HourAngle testRa = mount.GetRA(axisPosition); //if (Math.Abs(expectedRa-testRa)> 0.000001) //{ // System.Diagnostics.Debug.Write(" - FAIL"); //} Assert.AreEqual(expectedRa, testRa, 0.000001, "RA Value"); }
public void GetTheoreticalFromEquatorial() { using (AscomTools tools = new AscomTools()) { Angle longitude = new Angle("-1°20'20.54\""); tools.Transform.SiteLatitude = new Angle("52°40'6.38\""); tools.Transform.SiteLongitude = longitude; tools.Transform.SiteElevation = 175.5; MountCoordinate mirphac = new MountCoordinate(new EquatorialCoordinate("3h25m34.77s", "49°55'12.0\""), new AxisPosition(1.04551212078025, 0.882804566344625, true), tools, _localTime); MountCoordinate almaak = new MountCoordinate(new EquatorialCoordinate("2h04m58.83s", "42°24'41.1\""), new AxisPosition(0.597795712351665, 0.817146830684098, true), tools, _localTime); MountCoordinate ruchbah = new MountCoordinate(new EquatorialCoordinate("1h26m58.39s", "60°19'33.3\""), new AxisPosition(0.506260233480349, 1.09753088667021, true), tools, _localTime); TakiEQMountMapper taki = new TakiEQMountMapper(mirphac, almaak, ruchbah, _localTime); EquatorialCoordinate gPer = new EquatorialCoordinate("2h03m28.89s", "54°34'10.9\""); AxisPosition gPerExpected = new AxisPosition(0.649384407012042, 0.998796900509728, true); AxisPosition gPerCalculated = taki.GetAxisPosition(gPer, _localTime); System.Diagnostics.Debug.WriteLine("Calculated: {0}, expected: {1}", gPerExpected, gPerCalculated); double tolerance = 0.25; // degrees. bool testResult = ((Math.Abs(gPerExpected.DecAxis - gPerCalculated.DecAxis) < tolerance) && (Math.Abs(gPerExpected.RAAxis - gPerCalculated.RAAxis) < tolerance)); Assert.IsTrue(testResult); } }
//画面を更新する(球体地図) public void updateScreen2() { double hinode_keido, hinoiri_keido, asayake, higure; int hinoiriX = 0, hinodeX = 0; int asayakeX = 0, higureX = 0; double x, y; double halfPI = Math.PI / 2.0; //double scrDist = (scrWidth / 2.0) / Math.Tan(scrAngle / 180.0 * Math.PI); //if (screen == null | screen2 == null) return; //イメージを初期化 Color opaque = new Color(0, 0, 0, 0); for (int i = 0; i < shadow.width; i++) { for (int j = 0; j < shadow.height; j++) { shadow.SetPixel(i, j, opaque); } } EquatorialCoordinate sun = new EquatorialCoordinate(); EquatorialCoordinate moon = new EquatorialCoordinate(); double[] result = new double[3]; double[] result2 = new double[3]; double[] location = new double[2]; double asc = 0.0; double dec = 0.0; double moonasc = 0.0; double moondec = 0.0; try { SunAndMoon.getSunRightAscension(utc, result); sun.setRightAscension(result[0]); sun.setCelestialDeclination(result[1]); sun.setDistance(result[2]); asc = result[0]; //赤経 dec = result[1]; //赤緯 SunAndMoon.getMoonRightAscension(utc, result); moon.setRightAscension(result[0]); moon.setCelestialDeclination(result[1]); moon.setDistance(result[2]); moonasc = result[0]; moondec = result[1]; } catch (Exception) { Debug.Log("Exception1 "); return; } double phai0 = Almanac.getGreenidgeSiderealTime(utc);//グリニッジ恒星時 //恒星時をもとに、背景の回転を行う(恒星時は春分点の時角) Material skybox = RenderSettings.skybox; skybox.SetFloat("_Rotation", (float)-phai0);//時角のマイナス方向に回転。skyboxのマテリアルは左右が逆 //太陽位置計算(orbiterと同じコード) { double Theta = phai0 - asc; if (Theta < 0) { Theta += 360.0; } double DegToRad = Math.PI / 180; double denominator = (Math.Sin(dec * DegToRad) * Math.Cos(90.0 * DegToRad) - Math.Cos(dec * DegToRad) * Math.Sin(90.0 * DegToRad) * Math.Cos(Theta * DegToRad)); double A = Math.Atan((-Math.Cos(dec * DegToRad) * Math.Sin(Theta * DegToRad)) / denominator); double h = Math.Asin(Math.Sin(dec * DegToRad) * Math.Sin(90.0 * DegToRad) + Math.Cos(dec * DegToRad) * Math.Cos(90.0 * DegToRad) * Math.Cos(Theta * DegToRad)); A = A / DegToRad; h = h / DegToRad; //Arctanの象限を検討せよ if (denominator > 0) { //何故か解説書とは逆だが、分母が正の時に180度加算して象限を変える必要がある A += 180.0; } Vector3 sunvector = new Vector3(1.0f, 0.0f, 0.0f); sunvector = Quaternion.Euler(0.0f, 0.0f, (float)h) * sunvector; sunvector = Quaternion.Euler(0.0f, (float)A, 0.0f) * sunvector; float ratio = 1500.0f / sunvector.magnitude; sunvector *= ratio; GameObject game = GameObject.Find("Directional Light"); if (game != null) { game.transform.position = sunvector; Vector3 forward = sunvector; forward.Normalize(); game.transform.forward = -forward; } } //日の出・日の入りの同時線を描く double dist = sun.getDistance(); double parallax = SunAndMoon.getSunParallax(dist);//太陽視差 double k = SunAndMoon.getSunriseAltitude(SunAndMoon.getSunDiameter(dist), 0.0, SunAndMoon.refraction, parallax); double celestialdeclination = sun.getCelestialDeclination(); for (int i = -90; i < 90; i++) { //緯度を取得 double latitude = i;//getLatitudeFromY(Yequator - i); //緯度を元に時角を計算する double jikaku = SunAndMoon.getTimeAngle(k, celestialdeclination, latitude); if (!Double.IsNaN(jikaku))//時角がNaNでない { hinode_keido = SunAndMoon.reviseAngle(-jikaku + sun.getRightAscension() - phai0); hinoiri_keido = SunAndMoon.reviseAngle(jikaku + sun.getRightAscension() - phai0); // hinodeX =(int)getXfromLongitude(hinode_keido); // hinoiriX = (int)getXfromLongitude(hinoiri_keido);//昼側か調べる drawShadowTexture(hinode_keido, latitude, Color.white); drawShadowTexture(hinoiri_keido, latitude, Color.white); } } //輪郭の描画 VesselElements ve = new VesselElements(sun, moon, utc); SolarEclipse.getCrossPoint(ve, result, result2); double maxQ = SolarEclipse.getPenumbralQ(ve, result); double minQ = SolarEclipse.getPenumbralQ(ve, result2); //Debug.Log("MaxQ = " + maxQ + " minQ = " + minQ); //月位置計算(orbiterと同じコード) { double Theta = phai0 - moonasc; if (Theta < 0) { Theta += 360.0; } double DegToRad = Math.PI / 180; double denominator = (Math.Sin(moondec * DegToRad) * Math.Cos(90.0 * DegToRad) - Math.Cos(moondec * DegToRad) * Math.Sin(90.0 * DegToRad) * Math.Cos(Theta * DegToRad)); double A = Math.Atan((-Math.Cos(moondec * DegToRad) * Math.Sin(Theta * DegToRad)) / denominator); double h = Math.Asin(Math.Sin(moondec * DegToRad) * Math.Sin(90.0 * DegToRad) + Math.Cos(moondec * DegToRad) * Math.Cos(90.0 * DegToRad) * Math.Cos(Theta * DegToRad)); A = A / DegToRad; h = h / DegToRad; //Arctanの象限を検討せよ if (denominator > 0) { //何故か解説書とは逆だが、分母が正の時に180度加算して象限を変える必要がある A += 180.0; } Vector3 sunvector = new Vector3(1.0f, 0.0f, 0.0f); sunvector = Quaternion.Euler(0.0f, 0.0f, (float)h) * sunvector; sunvector = Quaternion.Euler(0.0f, (float)A, 0.0f) * sunvector; float ratio = (float)(moon.getDistance() * Constants.AUde * 3.16f) / sunvector.magnitude; sunvector *= ratio; // // Debug.Log("moondist = " + moon.getDistance()); GameObject game = GameObject.Find("Moon"); if (game != null) { game.transform.position = sunvector; } } /* Vector3 moonPos = new Vector3((float)ve.getX0(), (float)ve.getY0(), (float)ve.getZ0()); * moonPos.Normalize(); * moonPos *= 20; * GameObject moonobj = GameObject.Find("Moon"); * * if (moonobj!= null) * { * moonobj.transform.position = moonPos; * } */ //半影の描画 if (Double.IsNaN(maxQ) && Double.IsNaN(minQ)) { double first_longitude = Double.NaN; double first_latitude = Double.NaN; double last_longitude = Double.NaN; double last_latitude = Double.NaN; for (double i = 0.0; i <= 360.0; i += 0.2) { SolarEclipse.getPenumbralOutline(ve, i, result); if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2])) { continue; //NaNが含まれていたらスキップする } if (first_longitude == double.NaN | first_latitude == double.NaN) { first_longitude = result[0]; first_latitude = result[1]; } last_longitude = result[0]; last_latitude = result[1]; Coordinate.transformICRStoGCS(ve, result, location); drawShadowTexture(location[0], location[1], Color.red); } //Debug.Log(first_longitude + ":" + first_latitude + "::" + last_longitude + ":" + last_latitude); } else if (!Double.IsNaN(maxQ) && !Double.IsNaN(minQ)) { double first_x = double.NaN; double first_y = double.NaN; double first_z = double.NaN; double last_x = double.NaN; double last_y = double.NaN; double last_z = double.NaN; if ((maxQ - minQ) >= 0.0) { maxQ -= 360.0; } SolarEclipse.getPenumbralOutline(ve, maxQ, result); Coordinate.transformICRStoGCS(ve, result, location); //Debug.Log("MaxQ :" + location[0] + ":" + location[1]+ ":" + maxQ); SolarEclipse.getPenumbralOutline(ve, minQ, result); Coordinate.transformICRStoGCS(ve, result, location); //Debug.Log("MinQ :" + location[0] + ":" + location[1] + ":" + minQ); /* * //maxQが通常の計算でNaNとなる場合に備えて、強制的に描画する。 * SolarEclipse.getPenumbralOutline(ve, maxQ, result); * result[2] = -0.01;//強制的に基準面に設定する * Coordinate.transformICRStoGCS(ve, result, location); * drawShadowTexture(location[0], location[1], Color.black); */ for (double i = maxQ /*Math.Ceiling(maxQ)*/; i < minQ; i += 0.2) { SolarEclipse.getPenumbralOutline(ve, i, result); if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2])) { continue; //NaNが含まれていたらスキップする } if (Double.IsNaN(first_x) | Double.IsNaN(first_y) | Double.IsNaN(first_z)) { first_x = result[0]; first_y = result[1]; first_z = result[2]; } last_x = result[0]; last_y = result[1]; last_z = result[2]; Coordinate.transformICRStoGCS(ve, result, location); drawShadowTexture(location[0], location[1], Color.red); } { SolarEclipse.getPenumbralOutline(ve, minQ, result); if (!Double.IsNaN(result[0]) & !Double.IsNaN(result[1]) & !Double.IsNaN(result[2])) { Coordinate.transformICRStoGCS(ve, result, location); last_x = result[0]; last_y = result[2]; last_z = result[1]; drawShadowTexture(location[0], location[1], Color.red); } } //drawClosingLine2(ve, first_x, first_y, first_z, last_x, last_y, last_z); //Debug.Log(first_longitude + ":" + first_latitude + "::" + last_longitude + ":" + last_latitude); /* * //minQが通常の計算でNaNとなる場合に備えて、強制的に描画する。 * SolarEclipse.getPenumbralOutline(ve, minQ, result); * result[2] = -0.01;//強制的に基準面に設定する * Coordinate.transformICRStoGCS(ve, result, location); * drawShadowTexture(location[0], location[1], Color.red); */ } //本影の描画 for (int i = 0; i <= 360; i += 5) { SolarEclipse.getUmbralOutline(ve, (double)i, result); if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2])) { continue; //NaNが含まれていたらスキップする } Coordinate.transformICRStoGCS(ve, result, location); drawShadowTexture(location[0], location[1], Color.black); } GameObject earthobj = GameObject.Find("perfectsphere"); Material[] mats = earthobj.GetComponent <Renderer>().materials; Debug.Log("elements =" + mats.Length); mats[0].SetTexture("_MainTex", (Texture)shadow); //mats[1].SetTexture("_EmissionMap", shadow); //repaint(); }
public void drawLines() { //テクスチャ初期化 Color opaque = new Color(0, 0, 0, 0); for (int i = 0; i < shadow.width; i++) { for (int j = 0; j < shadow.height; j++) { shadow.SetPixel(i, j, opaque); } } EquatorialCoordinate sun = new EquatorialCoordinate(); EquatorialCoordinate moon = new EquatorialCoordinate(); double[] result = new double[3]; double[] result2 = new double[3]; double[] location = new double[2]; double asc = 0.0; double dec = 0.0; double moonasc = 0.0; double moondec = 0.0; try { SunAndMoon.getSunRightAscension(utc, result); sun.setRightAscension(result[0]); sun.setCelestialDeclination(result[1]); sun.setDistance(result[2]); asc = result[0]; //赤経 dec = result[1]; //赤緯 SunAndMoon.getMoonRightAscension(utc, result); moon.setRightAscension(result[0]); moon.setCelestialDeclination(result[1]); moon.setDistance(result[2]); moonasc = result[0]; moondec = result[1]; } catch (Exception) { Debug.Log("Exception1 "); return; } double phai0 = Almanac.getGreenidgeSiderealTime(utc);//グリニッジ恒星時 //太陽位置を計算してライトの位置と向きを変更する { //恒星時をもとに、背景の回転を行う(恒星時は春分点の時角) Material skybox = RenderSettings.skybox; skybox.SetFloat("_Rotation", (float)-phai0);//時角のマイナス方向に回転。skyboxのマテリアルは左右が逆 //赤緯・赤経は北極から見て時計回り。自覚、恒星時は反時計回り。時角に合わせて計算する //float ramda = -(float)((-asc + phai0) * DegToRad);これを書き換えて下の式になる float ramda = (float)((asc - phai0) * DegToRad); float psy = (float)(dec * DegToRad); float sundistance = 400; float x = Mathf.Cos(psy) * Mathf.Cos(ramda) * sundistance; float y = Mathf.Cos(psy) * Mathf.Sin(ramda) * sundistance; float z = Mathf.Sin(psy) * sundistance; GameObject light = GameObject.Find("Directional Light"); Vector3 sunpos = light.transform.position; sunpos.Set(x, z, y); light.transform.position = sunpos; sunpos.Normalize(); sunpos *= -1; light.transform.forward = sunpos; } /* * //日の出・日の入りの同時線を描く * { * double dist = sun.getDistance(); * double parallax = SunAndMoon.getSunParallax(dist);//太陽視差 * double k = SunAndMoon.getSunriseAltitude(SunAndMoon.getSunDiameter(dist), 0.0, SunAndMoon.refraction, parallax); * double celestialdeclination = sun.getCelestialDeclination(); * * for (int i = -90; i < 90; i++) * { * //緯度を取得 * double latitude = i;//getLatitudeFromY(Yequator - i); * * //緯度を元に時角を計算する * double jikaku = SunAndMoon.getTimeAngle(k, celestialdeclination, latitude); * * if (!Double.IsNaN(jikaku))//時角がNaNでない * { * double hinode_keido = SunAndMoon.reviseAngle(-jikaku + sun.getRightAscension() - phai0); * double hinoiri_keido = SunAndMoon.reviseAngle(jikaku + sun.getRightAscension() - phai0); * // hinodeX =(int)getXfromLongitude(hinode_keido); * // hinoiriX = (int)getXfromLongitude(hinoiri_keido);//昼側か調べる * drawShadowTexture(hinode_keido, latitude, Color.white); * drawShadowTexture(hinoiri_keido, latitude, Color.white); * } * } * } */ //輪郭の描画 //ベッセル数 VesselElements ve = new VesselElements(sun, moon, utc); SolarEclipse.getCrossPoint(ve, result, result2); //月影と地球外円との交点を調べる double maxQ = SolarEclipse.getPenumbralQ(ve, result); double minQ = SolarEclipse.getPenumbralQ(ve, result2); //Debug.Log("MaxQ = " + maxQ + " minQ = " + minQ); //半影の描画 if (Double.IsNaN(maxQ) && Double.IsNaN(minQ)) { //交点が存在しない場合。月影がすべて地球上に投射されている。 double first_longitude = Double.NaN; double first_latitude = Double.NaN; double last_longitude; double last_latitude; Color gray = new Color(0, 0, 0, 0.4f); //初期の点 SolarEclipse.getPenumbralOutline(ve, 0.0, result); Coordinate.transformICRStoGCS(ve, result, location); last_longitude = location[0]; last_latitude = location[1]; bool fill = true; for (double i = 1.0; i <= 360.0; i += 1.0) { SolarEclipse.getPenumbralOutline(ve, i, result2); if (Double.IsNaN(result2[0]) | Double.IsNaN(result2[1]) | Double.IsNaN(result2[2])) { fill = false; continue;//NaNが含まれていたらスキップする } Coordinate.transformICRStoGCS(ve, result2, location); // drawShadowTexture(location[0], location[1], gray); //Debug.Log("i=" + i + ":" +location[0] + ":" + location[1]); drawOutline(last_longitude, last_latitude, location[0], location[1], Color.red); last_longitude = location[0]; last_latitude = location[1]; } if (fill) { fillShadow(last_longitude - 2, last_latitude, shadow, gray); } /* * byte[] pngData = shadow.EncodeToPNG(); // pngのバイト情報を取得. * * // ファイルダイアログの表示. * string filePath = EditorUtility.SaveFilePanel("Save Texture", "", shadow.name + ".png", "png"); * * if (filePath.Length > 0) * { * // pngファイル保存. * File.WriteAllBytes(filePath, pngData); * } */ //Debug.Log(first_longitude + ":" + first_latitude + "::" + last_longitude + ":" + last_latitude); } else if (!Double.IsNaN(maxQ) && !Double.IsNaN(minQ))//交点が存在する { double first_x = double.NaN; double first_y = double.NaN; double first_z = double.NaN; double last_x = double.NaN; double last_y = double.NaN; double last_z = double.NaN; Color gray = new Color(0, 0, 0, 0.4f); if ((maxQ - minQ) >= 0.0) { maxQ -= 360.0; } SolarEclipse.getPenumbralOutline(ve, maxQ, result); Coordinate.transformICRStoGCS(ve, result, location); //Debug.Log("MaxQ :" + location[0] + ":" + location[1]+ ":" + maxQ); SolarEclipse.getPenumbralOutline(ve, minQ, result); Coordinate.transformICRStoGCS(ve, result, location); //Debug.Log("MinQ :" + location[0] + ":" + location[1] + ":" + minQ); /* * //maxQが通常の計算でNaNとなる場合に備えて、強制的に描画する。 * SolarEclipse.getPenumbralOutline(ve, maxQ, result); * result[2] = -0.01;//強制的に基準面に設定する * Coordinate.transformICRStoGCS(ve, result, location); * drawShadowTexture(location[0], location[1], Color.black); */ for (double i = maxQ /*Math.Ceiling(maxQ)*/; i < minQ; i += 0.2) { SolarEclipse.getPenumbralOutline(ve, i, result); if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2])) { continue; //NaNが含まれていたらスキップする } if (Double.IsNaN(first_x) | Double.IsNaN(first_y) | Double.IsNaN(first_z)) { first_x = result[0]; first_y = result[1]; first_z = result[2]; } last_x = result[0]; last_y = result[1]; last_z = result[2]; Coordinate.transformICRStoGCS(ve, result, location); drawShadowTexture(location[0], location[1], gray); } { SolarEclipse.getPenumbralOutline(ve, minQ, result); if (!Double.IsNaN(result[0]) & !Double.IsNaN(result[1]) & !Double.IsNaN(result[2])) { Coordinate.transformICRStoGCS(ve, result, location); last_x = result[0]; last_y = result[2]; last_z = result[1]; drawShadowTexture(location[0], location[1], gray); } } } //本影の描画 for (int i = 0; i <= 360; i += 5) { SolarEclipse.getUmbralOutline(ve, (double)i, result); if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2])) { continue; //NaNが含まれていたらスキップする } Coordinate.transformICRStoGCS(ve, result, location); drawShadowTexture(location[0], location[1], Color.black); } // shadow.Apply(); }
/* * //球体版のカメラの変換行列を設定する。 * private void initCameraVector(double longitude, double latitude) * { * viewpoint = new double[3]; * double[] xaxis = new double[3]; * double[] position = new double[3]; * * double phai = longitude / 180.0 * Math.PI; * double rho = latitude / 180.0 * Math.PI; * * //緯度に基づいて回転させる * position[0] = Altitude * Math.Cos(rho); * position[1] = 0.0; * position[2] = Altitude * Math.Sin(rho); * * //Z軸に基づいて回転させる。 * double[][] Zrevolve = new double[][] { { Math.Cos(phai), Math.Sin(phai), 0.0 }, { -Math.Sin(phai), Math.Cos(phai), 0.0 }, { 0.0, 0.0, 1.0 } }; * Matrix.multiplication31type2(Zrevolve, position, viewpoint); * * //接線ベクトルを計算する * position[0] = 0.0; * position[1] = 1.0; * position[2] = 0.0; * * // double[][] Xrevolve = new double[][]{{1.0, 0.0, 0.0 }, { 0.0, Math.cos(rho), -Math.sin(rho) }, {0.0 Math.sin(rho), Math. cos(rho) }}; * * Matrix.multiplication31type2(Zrevolve, position, xaxis); * * double norm = Math.Sqrt(viewpoint[0] * viewpoint[0] + viewpoint[1] * viewpoint[1] + viewpoint[2] * viewpoint[2]); * double[] yaxis = new double[] { -(viewpoint[0] / norm), -(viewpoint[1] / norm), -(viewpoint[2] / norm) }; * * double[] zaxis = new double[3]; * Matrix.getOuterProduct(xaxis, yaxis, zaxis); * * norm = Math.Sqrt(zaxis[0] * zaxis[0] + zaxis[1] * zaxis[1] + zaxis[2] * zaxis[2]); * zaxis[0] /= norm; * zaxis[1] /= norm; * zaxis[2] /= norm; * * * camvec = new double[][] { xaxis, yaxis, zaxis }; * InverseCam = new double[3][3]; * Matrix.getInverseMatrixType2(camvec, InverseCam); * } */ //画面を更新する(球体版) /* * private void createScreen2() * { * double hinode_keido, hinoiri_keido, asayake, higure; * int hinoiriX = 0, hinodeX = 0; * int asayakeX = 0, higureX = 0; * * // if (screen2 == null | earth == null) return; * * //イメージを初期化 * Color opaque = new Color(0, 0, 0, 0); * for (int i = 0; i < shadow.width; i++) * { * for (int j = 0; j < shadow.height; j++) * { * shadow.SetPixel(i, j, opaque); * } * } * * double scrDist = (scrWidth / 2.0) / Math.Tan(scrAngle / 180.0 * Math.PI); * double[] vector = new double[3]; * double[] result = new double[3]; * * double[] center = new double[] { viewpoint[0], viewpoint[1], viewpoint[2] }; //地球中心へ向かうベクトル * double norm = Math.Sqrt(center[0] * center[0] + center[1] * center[1] + center[2] * center[2]); * center[0] /= norm; * center[1] /= norm; * center[2] /= norm; * * double altitude = Math.Sqrt(viewpoint[0] * viewpoint[0] + viewpoint[1] * viewpoint[1] + viewpoint[2] * viewpoint[2]); * * for (int i = 0; i < scrWidth; i++) * { * double x = i - (scrWidth / 2); * double y = scrDist; * for (int j = 0; j < scrHeight; j++) * { * vector[0] = x; * vector[1] = y; * vector[2] = -(j - (scrHeight / 2)); * norm = Math.Sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]); * vector[0] /= norm; * vector[1] /= norm; * vector[2] /= norm; * Matrix.multiplication31type2(camvec, vector, result); * * double theta = Math.Acos(-center[0] * result[0] - center[1] * result[1] - center[2] * result[2]); * * double b2 = 2.0 * altitude * Math.Cos(theta); //コサインを変換する必要ないのでは? * double D = b2 * b2 - 4.0 * (altitude * altitude - Constants.de * Constants.de); * * if (D >= 0) * { * double root = 0.5 * Math.Sqrt(D); * * double distance = altitude * Math.Cos(theta) - root; * if (distance < 0) { System.out.println("負の実数解"); return; } * * //x1は交点までの距離。方向ベクトルに距離を掛けると位置が出る * double pointX = viewpoint[0] + result[0] * distance; * double pointY = viewpoint[1] + result[1] * distance; * double pointZ = viewpoint[2] + result[2] * distance; * * double latitude = Math.Asin(pointZ / Constants.de) / Math.PI * 180.0; * double longitude = Math.Acos(pointX / Math.Sqrt(pointX * pointX + pointY * pointY)) / Math.PI * 180.0; * if (pointY < 0) longitude = -longitude; //象限を考慮する * * double xOnMap = longitude - longitudeleft; * if (xOnMap < 0.0) xOnMap += 360.0; * int x1 = (int)(xOnMap * (imageWidth / 360.0)); * * double yOnMap = (imageHeight / 180.0) * latitude; * int y1 = Yequator - (int)yOnMap; * if (x1 < earth.getWidth() & y1 < earth.getHeight()) screen2.setRGB(i, j, earth.getRGB(x1, y1)); * } * } * } * } */ //3D空間内の地用と月のモデルの位置を変更する private void updateSunAndMoonPosition() { EquatorialCoordinate sun = new EquatorialCoordinate(); EquatorialCoordinate moon = new EquatorialCoordinate(); double asc = 0.0; double dec = 0.0; double moonasc = 0.0; double moondec = 0.0; try { double[] result = new double[2]; SunAndMoon.getSunRightAscension(utc, result); asc = result[0]; //赤経 dec = result[1]; //赤緯 SunAndMoon.getMoonRightAscension(utc, result); moonasc = result[0]; moondec = result[1]; } catch (Exception) { Debug.Log("Exception1 "); return; } double phai0 = Almanac.getGreenidgeSiderealTime(utc); //グリニッジ恒星時 //恒星時をもとに、背景の回転を行う(恒星時は春分点の時角) Material skybox = RenderSettings.skybox; skybox.SetFloat("_Rotation", (float)-phai0);//時角のマイナス方向に回転。skyboxのマテリアルは左右が逆 //太陽位置 { //赤緯・赤経は北極から見て時計回り。自覚、恒星時は反時計回り。時角に合わせて計算する //float ramda = -(float)((-asc + phai0) * DegToRad);これを書き換えて下の式になる float ramda = (float)((asc - phai0) * DegToRad); float psy = (float)(dec * DegToRad); float sundistance = 400; float x = Mathf.Cos(psy) * Mathf.Cos(ramda) * sundistance; float y = Mathf.Cos(psy) * Mathf.Sin(ramda) * sundistance; float z = Mathf.Sin(psy) * sundistance; GameObject light = GameObject.Find("Directional Light"); Vector3 sunpos = light.transform.position; sunpos.Set(x, z, y); light.transform.position = sunpos; sunpos.Normalize(); sunpos *= -1; light.transform.forward = sunpos; } //月位置 { float ramda = (float)((moonasc - phai0) * DegToRad); float psy = (float)(moondec * DegToRad); float x = Mathf.Cos(psy) * Mathf.Cos(ramda) * distanceToMoon; float y = Mathf.Cos(psy) * Mathf.Sin(ramda) * distanceToMoon; float z = Mathf.Sin(psy) * distanceToMoon; GameObject light = GameObject.Find("Moon"); Vector3 moonpos = light.transform.position; moonpos.Set(x, z, y); light.transform.position = moonpos; } }
//地球に写る月の影の輪郭を描く public void drawLines(DateTime utc) { EquatorialCoordinate sun = new EquatorialCoordinate(); EquatorialCoordinate moon = new EquatorialCoordinate(); double[] result = new double[3]; double[] result2 = new double[3]; double[] dataset = new double[7]; double[] location = new double[2]; double asc = 0.0; double dec = 0.0; double moonasc = 0.0; double moondec = 0.0; double phai0; if (mode == PLAYMODE) { dataholder.getPositions(utc, dataset); asc = dataset[0]; dec = dataset[1]; sun.setRightAscension(dataset[0]); sun.setCelestialDeclination(dataset[1]); sun.setDistance(dataset[2]); moon.setRightAscension(dataset[3]); moon.setCelestialDeclination(dataset[4]); moon.setDistance(dataset[5]); moonasc = dataset[3]; moondec = dataset[4]; phai0 = dataset[6]; } else if (mode == RECORDMODE) { try { SunAndMoon.getSunRightAscension(utc, result); asc = result[0]; dec = result[1]; sun.setRightAscension(result[0]); sun.setCelestialDeclination(result[1]); sun.setDistance(result[2]); SunAndMoon.getMoonRightAscension(utc, result); moon.setRightAscension(result[0]); moon.setCelestialDeclination(result[1]); moon.setDistance(result[2]); moonasc = result[0]; moondec = result[1]; } catch (Exception) { /* Debug.Log("Exception1 ");*/ return; } phai0 = Almanac.getGreenidgeSiderealTime(utc);//グリニッジ恒星時 //記録する dataholder.setPositions(asc, dec, sun.getDistance(), moonasc, moondec, moon.getDistance(), phai0, utc); } else { return; } //輪郭の描画 //ベッセル数 VesselElements ve = new VesselElements(sun, moon, utc); // SolarEclipse.getD(ve, 143.009267, 42.7396185, 0); SolarEclipse.getCrossPoint(ve, result, result2); //月影と地球外円との交点を調べる double maxQ = SolarEclipse.getPenumbralQ(ve, result); double minQ = SolarEclipse.getPenumbralQ(ve, result2); //Debug.Log("MaxQ = " + maxQ + " minQ = " + minQ); //半影の描画 if (Double.IsNaN(maxQ) && Double.IsNaN(minQ)) { clearTexture(); //交点が存在しない場合。月影がすべて地球上に投射されている。 double last_longitude; double last_latitude; Color gray = new Color(0, 0, 0, 0.4f); //初期の点 SolarEclipse.getPenumbralOutline(ve, 0.0, result); Coordinate.transformICRStoGCS(ve, result, location); last_longitude = location[0]; last_latitude = location[1]; double max_lat = -90, min_lat = 90; double east_lon = location[0]; double west_lon = double.NaN; //bool for (double i = 1.0; i <= 360.0; i += 1.0) { SolarEclipse.getPenumbralOutline(ve, i, result2); if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2])) { continue;//NaNが含まれていたらスキップする } Coordinate.transformICRStoGCS(ve, result2, location); if (double.IsNaN(location[0]) | double.IsNaN(location[1])) { continue; } //値の取得で例外が発生したら、処理をスキップする try { drawOutline(last_longitude, last_latitude, location[0], location[1], shadow, sunoutline); } catch (Exception ex) { continue; } last_longitude = location[0]; last_latitude = location[1]; if (i == 180.0) { west_lon = location[0]; } if (max_lat < last_latitude) { max_lat = last_latitude; } if (min_lat > last_latitude) { min_lat = last_latitude; } } if (!double.IsNaN(west_lon) & !double.IsNaN(east_lon)) { if (west_lon > east_lon) { east_lon += 360.0; } Point paintpoint = getScreenPoint((east_lon + west_lon) / 2, (max_lat + min_lat) / 2); fillShadowEx(paintpoint.x, paintpoint.y, shadow, shadowcolor); // Debug.Log("west= " + west_lon + " east=" +east_lon) ; } } else if (!Double.IsNaN(maxQ) && !Double.IsNaN(minQ))//交点が存在する { double first_longitude; double first_latitude; double last_longitude; double last_latitude; clearTexture(); Color gray = new Color(0, 0, 0, 0.4f); if ((maxQ - minQ) >= 0.0) { maxQ -= 360.0; } SolarEclipse.getPenumbralOutline(ve, maxQ, result); Coordinate.transformICRStoGCS(ve, result, location); //Debug.Log("MaxQ :" + location[0] + ":" + location[1]+ ":" + maxQ); SolarEclipse.getPenumbralOutline(ve, minQ, result); Coordinate.transformICRStoGCS(ve, result, location); //初期の点 double delta = 0.0; while (true) { SolarEclipse.getPenumbralOutline(ve, maxQ + delta, result); if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2])) { delta += 0.1; } else { break; } if (delta > 5.0) { break; } } Coordinate.transformICRStoGCS(ve, result, location); first_longitude = last_longitude = location[0]; first_latitude = last_latitude = location[1]; // double max_lon = 0, max_lat = -90, min_lon = 360, min_lat = 90; for (double i = maxQ + delta + 0.5; i < minQ; i += 0.5) { SolarEclipse.getPenumbralOutline(ve, i, result2); if (Double.IsNaN(result2[0]) | Double.IsNaN(result2[1]) | Double.IsNaN(result2[2])) { continue;//NaNが含まれていたらスキップする } Coordinate.transformICRStoGCS(ve, result2, location); //値の取得で例外が発生したら、処理をスキップする if (double.IsNaN(location[0]) | double.IsNaN(location[1])) { continue; } try { drawOutline(last_longitude, last_latitude, location[0], location[1], shadow, sunoutline); } catch (Exception e) { continue; } last_longitude = location[0]; last_latitude = location[1]; } SolarEclipse.getPenumbralOutline(ve, minQ, result); if (!Double.IsNaN(result[0]) & !Double.IsNaN(result[1]) & !Double.IsNaN(result[2])) { Coordinate.transformICRStoGCS(ve, result, location); if (!double.IsNaN(location[0]) & !double.IsNaN(location[1])) { drawOutline(last_longitude, last_latitude, location[0], location[1], shadow, sunoutline); last_longitude = location[0]; last_latitude = location[1]; } } //同時線を描く { //日の出・日の入りの同時線を描く int alllength = getSunLine(sun, phai0); //終点から同時線までの最短の線を描く Point pnt = getScreenPoint(last_longitude, last_latitude); double leastdistance = double.MaxValue; int finishindex = -1; //終点と最も近い点のインデックス if (pnt.x < 0) { pnt.x += shadow.width; } else if (pnt.x >= shadow.width) { pnt.x -= shadow.width; } if (pnt.y < 0) { pnt.y = 0; } else if (pnt.y >= shadow.width) { pnt.y = shadow.width; } for (int i = 0; i < alllength; i++) { double xdiff = Math.Abs(pnt.x - sunline[i * 2]); if (xdiff > shadow.width / 2) { xdiff = shadow.width - xdiff; } double ydiff = pnt.y - sunline[i * 2 + 1]; double length = Math.Sqrt(xdiff * xdiff + ydiff * ydiff); if (length < leastdistance) { leastdistance = length; finishindex = i; } } if (finishindex != -1 & leastdistance != double.MaxValue) { if (!double.IsNaN(last_longitude) & !double.IsNaN(last_latitude)) { drawScreenOutline(pnt.x, pnt.y, sunline[finishindex * 2], sunline[finishindex * 2 + 1], sunoutline); } } //開始点から同時線までの最短の線を描く pnt = getScreenPoint(first_longitude, first_latitude); leastdistance = double.MaxValue; int startindex = -1; //始点と最も近い点のインデックス if (pnt.x < 0) { pnt.x += shadow.width; } else if (pnt.x >= shadow.width) { pnt.x -= shadow.width; } if (pnt.y < 0) { pnt.y = 0; } else if (pnt.y >= shadow.width) { pnt.y = shadow.width; } for (int i = 0; i < alllength; i++) { double xdiff = Math.Abs(pnt.x - sunline[i * 2]); if (xdiff > shadow.width / 2) { xdiff = shadow.width - xdiff; } double ydiff = pnt.y - sunline[i * 2 + 1]; double length = Math.Sqrt(xdiff * xdiff + ydiff * ydiff); if (length < leastdistance) { leastdistance = length; startindex = i; } } if (startindex != -1 & leastdistance != double.MaxValue) { if (!double.IsNaN(last_longitude) & !double.IsNaN(last_latitude)) { drawScreenOutline(pnt.x, pnt.y, sunline[startindex * 2], sunline[startindex * 2 + 1], sunoutline); } } //判定を正確にするため、同時線は最後に描く。alllengthは要素数だから、マイナスしない for (int i = 0; i < alllength; i++) { drawScreenPixel(sunline[i * 2], sunline[i * 2 + 1], boundscolor); } //影の中を塗る int middlepoint = -1; if (Math.Abs(finishindex - startindex) > (alllength / 2)) { middlepoint = (finishindex + startindex + alllength) / 2; if (middlepoint >= alllength) { middlepoint -= alllength; } else if (middlepoint < 0) { middlepoint += alllength; } } else { middlepoint = (finishindex + startindex) / 2; } getInnerPoint(sunline[middlepoint * 2], sunline[middlepoint * 2 + 1], shadow);//塗の指示 }//同時線の描画の終わり } //半影の描画の終わり else if (!Double.IsNaN(maxQ) | !Double.IsNaN(minQ)) /*Debug.Log("minQ or maxQ is NaN");*/ } {
private double siderealtime; //グリニッジ恒星時。角度。 public VesselElements(EquatorialCoordinate possun, EquatorialCoordinate posmoon, DateTime cal) { //赤経をラジアン角に変換 double alphasun = possun.getRightAscension() / 180.0 * Math.PI; double alphamoon = posmoon.getRightAscension() / 180.0 * Math.PI; //赤緯をラジアン角に変換 double gammasun = possun.getCelestialDeclination() / 180.0 * Math.PI; double gammamoon = posmoon.getCelestialDeclination() / 180.0 * Math.PI; //Debug.Log("asc= " + alphasun + " dec =" + gammasun + " dist = " + possun.getDistance()); //地心赤道座標を計算する double Xs = possun.getDistance() * Math.Cos(alphasun) * Math.Cos(gammasun); double Ys = possun.getDistance() * Math.Sin(alphasun) * Math.Cos(gammasun); double Zs = possun.getDistance() * Math.Sin(gammasun); double Xm = posmoon.getDistance() * Math.Cos(alphamoon) * Math.Cos(gammamoon); double Ym = posmoon.getDistance() * Math.Sin(alphamoon) * Math.Cos(gammamoon); double Zm = posmoon.getDistance() * Math.Sin(gammamoon); //月から見た太陽の赤道直交座標 double Gx = Xs - Xm; double Gy = Ys - Ym; double Gz = Zs - Zm; double tana = Gy / Gx; double tand = Gz / Math.Sqrt(Gx * Gx + Gy * Gy); //月影軸方向の赤経・赤緯 ascension = Math.Atan2(Gy, Gx); declination = Math.Atan2(Gz, Math.Sqrt(Gx * Gx + Gy * Gy)); g = Math.Sqrt(Gx * Gx + Gy * Gy + Gz * Gz) * Constants.AUde; //地球半径単位への変換 Xm *= Constants.AUde; Ym *= Constants.AUde; Zm *= Constants.AUde; //変換行列を生成(縦配置) double[][] transmatrix = new double[][] { new double[3], new double[3], new double[3] }; double[] coordinate1 = new double[] { Xm, Ym, Zm }; double[] coordinate2 = new double[3]; double angle = ascension + (Math.PI / 2.0); transmatrix[0][0] = Math.Cos(angle); transmatrix[0][1] = -Math.Sin(angle); transmatrix[0][2] = 0.0; transmatrix[1][0] = Math.Sin(angle); transmatrix[1][1] = Math.Cos(angle); transmatrix[1][2] = 0.0; transmatrix[2][0] = 0.0; transmatrix[2][1] = 0.0; transmatrix[2][2] = 1.0; Matrix.multiplication31type2(transmatrix, coordinate1, coordinate2); angle = (Math.PI / 2.0) - declination; transmatrix[0][0] = 1.0; transmatrix[0][1] = 0.0; transmatrix[0][2] = 0.0; transmatrix[1][0] = 0.0; transmatrix[1][1] = Math.Cos(angle); transmatrix[1][2] = -Math.Sin(angle); transmatrix[2][0] = 0.0; transmatrix[2][1] = Math.Sin(angle); transmatrix[2][2] = Math.Cos(angle); Matrix.multiplication31type2(transmatrix, coordinate2, coordinate1); x0 = coordinate1[0]; y0 = coordinate1[1]; z0 = coordinate1[2]; double d = Constants.Dsun + Constants.Dmoon; tanf1 = d / Math.Sqrt(g * g - d * d); c1 = z0 + (g * Constants.Dmoon) / d; d = Constants.Dsun - Constants.Dmoon; tanf2 = d / Math.Sqrt(g * g - d * d); c2 = z0 - (g * Constants.Dmoon) / d; l1 = c1 * tanf1; l2 = c2 * tanf2; //グリニッジ恒星時を計算する siderealtime = Almanac.getGreenidgeSiderealTime(cal); }