4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

天体の位置を計算してみた

4
Posted at

天体の位置を計算するパラメーターは、海上保安庁の海洋情報部から提供されている。
世界が世界ならブルマーが提供してくれるはず

海上保安庁が出している情報だけあって、目視観測が目的になっている。そのため、太陽、月、金星、火星、木星、土星、といった、観測しやすい天体が記載されている。

天文・暦情報

下の方の"コンピュータによる天体の位置計算式 (天測暦/天測略暦付録)"に計算方法のPDFや数値が書かれたTXTのリンクが有る。
平成21年から31年までの範囲のデータが有る。年末が近くなると翌年分のデータが提供される。

とりあえず手っ取り早く動作確認したかったので、値をソースコードに埋め込んでいる。
データのコピペが面倒だったので太陽と金星と火星のみ扱っている。

2019-01-04_19-25.png

エクセルでグラフ化してみた。
各軸の符号は気にしないように。。。

計算結果は地球を中心とした極座標系で得られるので、直交座標系に変換し、惑星の位置は太陽との差を取る。
また、この図では$x = \sin(ra \div 12 \times \pi) \cos(dec \div 180 \times \pi) dist$のように計算しているが、これは地球の極軸の延長線上から見た形なので、公転面に対する自転軸の傾斜分、つぶれた形になっている。

C#
static void Main(string[] args)
{
    string[] names = new[] { "Sun", "Venus", "Mars", };

    DateTimeOffset start = new DateTimeOffset(2019, 1, 1, 0, 0, 0, new TimeSpan());
    DateTimeOffset end = new DateTimeOffset(2020, 1, 1, 0, 0, 0, new TimeSpan());

    StringBuilder sb = new StringBuilder();

    foreach (string name in names)
    {
        sb.Append("," + name + " ra");
        sb.Append("," + name + " dec");
        sb.Append("," + name + " dist");
    }
    sb.AppendLine();

    for (int days = 0; start.AddDays(days) < end; days++)
    {
        DateTimeOffset date = start.AddDays(days);

        sb.Append(date);

        foreach (string name in names)
        {
            double ra, dec, dist;
            if (!tryCalcCelestialPosition(name, date, out ra, out dec, out dist))
            {
                ra = dec = dist = double.NaN;
            }

            sb.Append("," + ra);
            sb.Append("," + dec);
            sb.Append("," + dist);
        }

        sb.AppendLine();
    }

    using (StreamWriter sw = new StreamWriter("./log.txt"))
    {
        sw.Write(sb.ToString().Replace(',', '\t'));
    }
}

struct DataSet
{
    public int a { get; private set; }
    public int b { get; private set; }
    public double[] RA { get; private set; }
    public double[] Dec { get; private set; }
    public double[] Dist { get; private set; }

    public DataSet(int a, int b, double[] RA, double[] Dec, double[] Dist)
    {
        if (a >= b ||
            RA.Length != Dec.Length ||
            RA.Length != Dist.Length)
        {
            throw new ArgumentException();
        }

        this.a = a;
        this.b = b;
        this.RA = RA;
        this.Dec = Dec;
        this.Dist = Dist;
    }
}

static bool tryCalcCelestialPosition(string name, DateTimeOffset date, out double RaHour, out double DecDeg, out double DistAu)
{
    RaHour = DecDeg = DistAu = 0;

    string key = name + date.UtcDateTime.Year;

    if (!dict1.ContainsKey(key))
    {
        return (false);
    }

    double t = (date.UtcDateTime - new DateTime(date.UtcDateTime.Year, 1, 1)).TotalDays + 1
        + dict2[date.UtcDateTime.Year] / 86400.0;

    foreach (DataSet set in dict1[key])
    {
        if (set.a > t || t > set.b)
        {
            continue;
        }

        double theta = Math.Acos((2 * t - (set.b + set.a)) / (set.b - set.a));

        for (int i = 0; i < set.RA.Length; i++)
        {
            double cosNtheta = Math.Cos(theta * i);

            RaHour += set.RA[i] * cosNtheta;
            DecDeg += set.Dec[i] * cosNtheta;
            DistAu += set.Dist[i] * cosNtheta;
        }

        return (true);
    }

    return (false);
}

static readonly Dictionary<int, int> dict2 = new Dictionary<int, int>()
{
    { 2019, 70 },
};

static readonly Dictionary<string, DataSet[]> dict1 = new Dictionary<string, DataSet[]>()
{
    { "Sun2019", new DataSet[] {
            new DataSet(0, 121,
                #region
                new [] {
                    22.6964,
                    3.896948, -0.103656, 0.034727, 0.006648, -0.002283,
                    0.000073, 0.000064, -0.000002, 0.000012, 0.000053,
                    -0.000038, -0.000053, 0.000023, 0.000021, -0.000007,
                    -0.000003, 0.000002,
                },
                new []
                {
                    -5.85509,
                    19.99447, 1.75027, -0.98562, 0.01226, 0.008,
                    -0.00368, 0.00067, 0.00016, 0.00014, 0.00022,
                    -0.00011, -0.00028, 0.00002, 0.00014, 0,
                    -0.00003, -0.00001,
                },
                new []
                {
                    0.993121,
                    0.012666, 0.00229, -0.000646, -0.000043, 0.000016,
                    0.000005, 0.000013, -0.000004, 0.000005, -0.000008,
                    -0.000015, 0.000007, 0.000009, -0.000003, -0.000003,
                    0.000001, 0.000001,
                }),
                #endregion
            new DataSet(120, 244,
                #region
                new []
                {
                    6.599667,
                    4.13595, -0.040841, -0.040829, 0.005193, 0.003291,
                    -0.000422, -0.000118, 0.000049, 0.000017, 0.000012,
                    -0.000071, -0.000019, 0.00005, 0.00001, -0.000018,
                    -0.000007, 0.000006,
                },
                new []
                {
                    17.17705,
                    -3.27497, -5.7942, 0.2083, 0.1602, -0.01044,
                    -0.00503, 0.00073, 0.00012, -0.00019, 0.00016,
                    0.00002, 0.00004, 0.00006, -0.00007, -0.00004,
                    0.00002, 0.00003,
                },
                new []
                {
                    1.012388,
                    0.001199, -0.004187, -0.000056, 0.000106, 0.000004,
                    0.000004, 0.000005, -0.00001, 0.000001, -0.000012,
                    -0.000006, 0.000016, 0.000004, -0.000008, -0.000001,
                    0.000002, 0,
                }),
                #endregion
            new DataSet(243, 366,
                #region
                new []
                {
                    14.525213,
                    4.050617, 0.151517, 0.013548, -0.013395, -0.002113,
                    0.000297, 0.000215, 0.000008, 0.000002, -0.00004,
                    -0.000056, 0.000037, 0.000037, -0.000016, -0.000012,
                    0.000004, 0.000004,
                },
                new []
                {
                    -10.58204,
                    -16.89248, 3.49425, 0.97511, -0.02577, -0.02312,
                    -0.00523, -0.00008, 0.00042, -0.00005, 0.00004,
                    0.00029, -0.00017, -0.00022, 0.00011, 0.00009,
                    -0.00003, -0.00002,
                },
                new []
                {
                    0.994695,
                    -0.013897, 0.001825, 0.000724, -0.000027, -0.000017,
                    0.000005, -0.000009, -0.000007, -0.000002, -0.000011,
                    0.000011, 0.000013, -0.000007, -0.000006, 0.000003,
                    0.000001, -0.000001,
                }),
        #endregion
        }
    },
    { "Venus2019", new DataSet[] {
            new DataSet(0, 121,
                #region
                new []
                {
                    20.0894,
                    4.770818, -0.004287, -0.070212, 0.021819, 0.004282,
                    -0.001415, -0.000295, 0.000167, 0.000029, 0.000015,
                    -0.000067, -0.000014, 0.000039, 0.000002, -0.000012,
                    0.000002, 0.000004,
                },
                new []
                {
                    -12.22805,
                    9.61427, 6.78204, -0.4148, -0.39134, 0.05256,
                    0.00901, -0.00365, -0.00038, 0.00048, -0.00006,
                    -0.00008, -0.00013, 0.00001, 0.0001, -0.00001,
                    -0.00002, 0.00001,
                },
                new []
                {
                    1.054744,
                    0.411713, -0.018687, -0.002435, 0.000187, -0.0001,
                    0.000025, 0.000004, -0.000004, 0.000002, -0.000016,
                    -0.000006, 0.000015, 0.000003, -0.000006, -0.000001,
                    0.000001, 0.000001,
                }),
                #endregion
            new DataSet(120, 244,
                #region
                new []
                {
                    5.827986,
                    5.202986, 0.049994, -0.078962, -0.010601, 0.009797,
                    0.001418, -0.000796, -0.000175, 0.000089, 0.000027,
                    -0.000053, -0.000006, 0.000028, 0.000002, -0.000009,
                    -0.000003, 0.000003,
                },
                new []
                {
                    13.89664,
                    2.88981, -8.86463, -0.43301, 0.42723, 0.03293,
                    -0.02073, -0.00349, 0.00152, 0.00036, -0.00001,
                    -0.00009, 0.00005, 0.00006, -0.00006, -0.00002,
                    0.00001, 0.00002,
                },
                new []
                {
                    1.630704,
                    0.141151, -0.051406, -0.001594, 0.000519, 0.000048,
                    -0.000002, 0, -0.000008, 0.000001, -0.000015,
                    -0.000002, 0.000016, 0.000001, -0.000007, 0,
                    0.000002, 0,

                }),
                #endregion
            new DataSet(243, 366,
                #region
                new []
                {
                    15.923639,
                    5.14974, 0.151701, -0.031983, -0.034715, 0.000704,
                    0.003079, 0.000513, -0.000191, -0.000079, -0.000014,
                    -0.000036, 0.000012, 0.000026, -0.000003, -0.000008,
                    0, 0.000003,
                },
                new []
                {
                    -12.22232,
                    -14.72841, 7.56495, 1.4717, -0.27205, -0.08298,
                    -0.00353, 0.00611, 0.00149, -0.00039, -0.00024,
                    0.00013, -0.00005, -0.0001, 0.00005, 0.00005,
                    -0.00001, -0.00001,
                },
                new []
                {
                    1.533443,
                    -0.223213, -0.033985, 0.001937, -0.000248, -0.000017,
                    0.000017, -0.000005, -0.000006, -0.000002, -0.000015,
                    0.000006, 0.000015, -0.000003, -0.000006, 0.000001,
                    0.000001, 0,
                }),
                #endregion
        }
    },
    { "Mars2019", new DataSet[] {
            new DataSet(0, 121,
                #region
                new []
                {
                    2.564142,
                    2.658989, 0.06083, 0.000734, -0.002224, -0.000314,
                    0.000041, -0.00001, 0.000022, -0.000005, 0.000024,
                    0.000016, -0.000032, -0.000011, 0.000016, 0.000004,
                    -0.000003, -0.000001,
                },
                new []
                {
                    13.61414,
                    12.62843, -1.85287, -0.26484, 0.01618, 0.00222,
                    0.00026, -0.00013, 0.0001, -0.00006, 0.00006,
                    0.00013, -0.00013, -0.00008, 0.00008, 0.00002,
                    -0.00003, -0.00001,
                },
                new []
                {
                    1.75839,
                    0.497599, -0.012599, -0.004394, 0.000046, 0.000033,
                    -0.000005, 0.000012, 0.000005, 0.000001, 0.000007,
                    -0.000015, -0.000009, 0.000011, 0.000004, -0.000004,
                    -0.000001, 0.000001,
                }),
                #endregion
            new DataSet(120, 244,
                #region
                new []
                {
                    8.045234,
                    2.747163, -0.071382, -0.004923, 0.003287, 0.000004,
                    -0.000082, 0.000024, 0.000016, -0.000005, 0.000011,
                    -0.000023, -0.000017, 0.000018, 0.000009, -0.000007,
                    -0.000005, 0.000003,
                },
                new []
                {
                    19.04418,
                    -7.60969, -2.37057, 0.21373, 0.01609, -0.00385,
                    0.00021, 0.00003, -0.00004, -0.00005, 0.00002,
                    0.00007, 0.00004, -0.00001, -0.00003, 0,
                    0.00001, 0,
                },
                new []
                {
                    2.508586,
                    0.223481, -0.055137, -0.002149, 0.000199, 0.000011,
                    0.000001, 0.000008, -0.00001, -0.000001, -0.000007,
                    -0.000011, 0.000014, 0.000009, -0.000008, -0.000004,
                    0.000002, 0.000001,
                }),
                #endregion
            new DataSet(243, 366,
                #region
                new []
                {
                    13.162022,
                    2.519937, 0.052854, 0.014762, -0.000897, -0.000253,
                    -0.000019, 0.000007, -0.000014, -0.000002, -0.000015,
                    -0.000015, 0.000022, 0.000011, -0.000011, -0.000003,
                    0.000002, 0.000002,
                },
                new []
                {
                    -5.57105,
                    -14.76437, 0.60721, 0.27608, 0.0074, 0.00011,
                    -0.00031, -0.00011, 0.00006, 0.00001, 0.00007,
                    0.00011, -0.00013, -0.00008, 0.00006, 0.00004,
                    -0.00001, -0.00001,
                },
                new []
                {
                    2.485056,
                    -0.247831, -0.055639, 0.002496, 0.000414, -0.000007,
                    -0.000002, -0.000012, -0.000006, 0.000001, -0.000006,
                    0.000015, 0.00001, -0.000012, -0.000005, 0.000005,
                    0.000001, -0.000001,

                }),
                #endregion
        }
    },
};

プログラムを簡単にするために、1月0日からの経過日数をDateTimeOffsetの差、TimeSpan.TotalDaysで得ているが、うるう年やうるう秒の処理について問題があるかもしれない。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?