本文へ移動

Wakusei Planets惑星

太陽・惑星・衛星を、線画、陰影つきの絵、表面の地図で描きます。実際の大きさ・傾き・自転つきで、任意の日時の衛星の位置も分かります。

「惑星」(わくせい) は、太陽のまわりを回る大きな星のことです。 名前について(英語)

目次

やり方

近くにあるもの、近づく時刻

ある日付に、ある天体にいちばん近い天体を、空の見かけの角度か宇宙での距離でさがします。2つの天体がいちばん近づく時刻も、JPL Horizons と秒の単位で比べて確かめています。

/nearest は、太陽・惑星・準惑星・衛星について、3つのことに答えます。「この日、この天体のとなりには何がある?」「この2つはいつ、いちばん近づく?」「この2つは今どれだけ離れていて、どこまで離れる?」です。ゲーム (「今夜、月はどの惑星のとなり?」)、合 (ごう) のカレンダー、星図のラベルに使えます。ブラウザなしでどこでも動き、このパッケージ自身の位置を使います。

import { closestApproach, conjunctions, distance, distanceRange, nearest, within } from "@johnmorrisdotca/wakusei-planets/nearest";

const date = Date.UTC(2026, 11, 27, 16);
console.log(nearest("moon", { kind: "planet", count: 2, date }).map((row) => `${row.id} ${row.angle.toFixed(2)} degrees`).join(", "));
console.log(within("jupiter", 1.5, { date }).map((row) => row.id).join(", "));
console.log(nearest("earth", { by: "space", kind: "planet", count: 1, date })[0]?.distanceAu.toFixed(2), "au");

const great = closestApproach("jupiter", "saturn", { from: Date.UTC(2020, 11, 1), to: Date.UTC(2021, 0, 1) });
console.log(great.time.toISOString(), great.angle?.toFixed(2), "degrees");
console.log(distance("earth", "mars", date).distanceAu.toFixed(2), "au now apart");
console.log(distanceRange("earth", "mars", { from: Date.UTC(1900, 0, 1), to: Date.UTC(2100, 0, 1) }).max.distanceAu.toFixed(2), "au at most");
console.log(conjunctions({ from: Date.UTC(2023, 0, 1), to: Date.UTC(2024, 0, 1), bodies: ["venus", "jupiter"], within: 2 }).length, "close approaches");
jupiter 1.41 degrees, mars 13.46 degrees
io, europa, ganymede, callisto, moon
0.62 au
2020-12-21T18:25:35.939Z 0.10 degrees
0.95 au now apart
2.68 au at most
1 close approaches

6つの関数

関数返すもの
nearest(target, options)ある日付に target にいちばん近い天体を、近い順に
within(target, radius, options)ある半径の中にあるすべての天体を、近い順に
closestApproach(a, b, { from, to })期間の中で2つの天体がいちばん近づく時刻と、そのときの近さ
conjunctions({ from, to, within, bodies })期間の中のすべての天体の組の近づきを、早い順に
distance(a, b, date)ある日付の2つの天体のあいだの直線距離を、kmとauで
distanceRange(a, b, { from, to })期間の中で2つの天体がいちばん近い距離といちばん遠い距離を、それぞれの時刻つきで

天体は "mars"、"moon"、"io" のような名前で、パッケージのほかの部分と同じ名前です。太陽、惑星、準惑星、衛星のすべてが対象です。恒星は /stars にあります。恒星はここでは target にできません。

オプション

どの関数でも同じオプションは同じ意味です。ファミリーのほかのパッケージが同じものに使う名前でもあります。

オプション意味
by"sky" (初期値): 観測者の空で、2つの天体のあいだの角度。"space": 2つの中心のあいだの距離
dateDate か、1970年からのミリ秒 (UTC)。初期値は今
countいくつ返すか。初期値は5。within があるときは、その中のすべて
withinこれより近いものだけ。by: "sky" では度、by: "space" ではキロメートル
kindこの種類だけ ("planet" 惑星、"dwarf-planet" 準惑星、"moon" 衛星、"star" は太陽)。種類の配列も可
bodiesこれらの天体だけをさがす
observer空を見る場所。初期値は地球の中心。{ latitude, longitude, heightM } で地球上の場所、天体の名前 ("mars") でその天体の空

恒星には /stars に magnitude (等級) の絞りこみがあります。このパッケージの天体には明るさのデータがないので、ここに magnitude オプションはありません。

空で

by: "sky" は、観測者から見た2つの天体の方向のあいだの角度で、0度から180度です。外積と内積のアークタンジェントで求めるので、0度 (合) や180度 (衝) の近くでも、90度のときと同じ精度です。方向は天文測位 (astrometric) で、JPL Horizons の赤経・赤緯と同じ考え方です。それぞれの天体は光が出たときの場所にあり (月は1秒あまり前、海王星は何時間も前)、観測者は今の場所にいます。光行差と光の曲がりは足していません。近くにある2つの天体は、ほとんど同じだけずれるからです。

月は近いので、立っている場所で答えが最大で1度ほど変わります。月には場所を渡してください。2026年12月27日、ガニメデは地球の中心から見ると月から1.4度、バンクーバーから見ると2.3度です。

import { nearest } from "@johnmorrisdotca/wakusei-planets/nearest";

const date = Date.UTC(2026, 11, 27, 16);
const centre = nearest("moon", { bodies: ["ganymede"], date })[0];
const vancouver = nearest("moon", { bodies: ["ganymede"], date, observer: { latitude: 49.28, longitude: -123.12 } })[0];
console.log(centre?.angle.toFixed(2), vancouver?.angle.toFixed(2));
console.log(nearest("earth", { observer: "mars", count: 1, date })[0]?.id, "is next to the Earth in the sky of Mars");
1.40 2.30
moon is next to the Earth in the sky of Mars

天体は自分の空には出てきません。target 自身と、空を見ている天体 (地球上の観測者なら地球) は結果に入りません。空の target が観測者自身の天体だと RangeError を投げます。

宇宙で

by: "space" は、その日付の2つの中心を結ぶ直線の距離で、キロメートル (distanceKm) と天文単位 (distanceAu) で返します。光の到着時間は入っていません。ある一瞬の形です。観測者は関係ないので、無視されます。

いちばん近づく時刻と合

closestApproach と conjunctions は、2つの天体のあいだの近さが時間でどう変わるかを見ます。期間をあらい刻みで調べます。刻みは、いちばん速い天体の公転周期の40分の1で、2日を超えません (イオは1.8日で1周するので、イオを入れると約1時間刻みです。火星や木星は2日刻みです)。近さが下がってから上がるところを見つけたら、黄金分割探索で最小の時刻を約1秒の単位まで絞ります (範囲が0.5秒より小さくなったら止めます)。

closestApproach(a, b, { from, to }) は、期間の中でいちばん小さい近さを返します。期間を通して近さが下がるだけ、または上がるだけのときは、小さいほうの端を返し、atEdge が true になります。conjunctions は、bodies のすべての組の最小のうち、within の中にあるものを早い順に返します (空では初期値が5度、宇宙ではすべて)。bodies の初期値は太陽と水星から海王星で、空を見ている天体は除きます。最小になるのは2つの中心の近さなので、一方がもう一方の前を横切る場合 (通過や掩蔽) も、0にはならず、小数点以下の度になります。

import { conjunctions } from "@johnmorrisdotca/wakusei-planets/nearest";

const found = conjunctions({ from: Date.UTC(2026, 0, 1), to: Date.UTC(2027, 0, 1), within: 1 });
for (const one of found.slice(0, 5)) console.log(one.a, one.b, one.time.toISOString().slice(0, 16), one.angle?.toFixed(2));
sun venus 2026-01-06T06:24 0.70
venus mars 2026-01-08T03:12 0.17
sun mars 2026-01-09T09:36 0.94
mercury mars 2026-01-18T06:33 0.96
mercury venus 2026-01-29T13:55 0.68

距離と、2つの天体が離れる範囲

distance(a, b, date) は、どの2つの天体でも使える by: "space" を1回の呼び出しにしたもので、{ a, b, time, distanceKm, distanceAu, uncertaintyKm } を返します。日付は Date かミリ秒で、省略すると今です。distanceRange(a, b, { from, to }) は closestApproach と同じように期間を調べ、{ a, b, min, max } を返します。それぞれ { time, distanceKm, distanceAu, uncertaintyKm, atEdge } です。どちらの折り返し点も、同じ黄金分割探索で約1秒の単位まで絞ります。最大は、距離にマイナスをつけたものの最小です。期間を通して距離が下がるだけ、または上がるだけのときは、その極値になる端を atEdge: true で返します。

import { distance, distanceRange } from "@johnmorrisdotca/wakusei-planets/nearest";

const { min, max } = distanceRange("earth", "mars", { from: Date.UTC(1900, 0, 1), to: Date.UTC(2100, 0, 1) });
console.log(min.time.toISOString().slice(0, 10), min.distanceAu.toFixed(3), "au;", max.time.toISOString().slice(0, 10), max.distanceAu.toFixed(3), "au");
console.log(Math.round(distance("jupiter", "io", Date.UTC(2026, 10, 8)).distanceKm), "km from Jupiter to Io");
2003-08-27 0.373 au; 2066-08-25 2.676 au
422312 km from Jupiter to Io

惑星、1900年から2100年

200年のあいだの、惑星の各組のいちばん近い距離といちばん遠い距離と、それぞれの年です (node scripts/distance-table.ts が表を出力します)。単位は天文単位です。年のあとの星印は、期間の中の折り返し点ではなく、期間の端が極値だという意味です。地球と火星は、2003年8月27日に0.373 auまで近づき、2066年に2.676 auまで離れます。

組最小 (au)年最大 (au)年
水星と金星0.26120851.1872059
水星と地球0.54920611.4522034
水星と火星0.96619182.0801908
水星と木星4.59520105.8102075
水星と土星8.705191510.3791900
水星と天王星17.897205120.4862010
水星と海王星29.483204130.6561958
金星と地球0.26420931.7361960
金星と火星0.65420522.3942002
金星と木星4.22320706.1822005
金星と土星8.295191410.7881900
金星と天王星17.564205020.8182092
金星と海王星29.083204231.0551959
地球と火星0.37320032.6762066
地球と木星3.94919516.4561945
地球と土星8.030191411.0511900
地球と天王星17.290205121.0932093
地球と海王星28.814204131.3241958
火星と木星3.51620006.8871994
火星と土星7.418191511.6632019
火星と天王星16.621204921.7592093
火星と海王星28.304190031.8381983
木星と土星4.033192115.2411990
木星と天王星12.849205225.4541920
木星と海王星24.745190735.3931990
土星と天王星9.234198829.6332100*
土星と海王星20.178198940.0072079
天王星と海王星10.570199449.8792084

どの距離も、結果の不確かさの範囲で正しいと考えてください。内惑星で数千km、木星より外で数万kmです。JPL Horizons との比較は3つの組 (地球と火星、金星と地球、木星と土星) で行います。test/nearest.test.ts は、1900年から2100年のそれぞれの組の最小と最大の距離について、Horizons の表 (一方の惑星の中心からもう一方の中心への幾何学的なベクトルで、折り返し点の前後10日を6時間刻み。scripts/fetch-horizons-distance.py が問い合わせを test/data/horizons-distance.json に記録します) を使い、放物線を当てはめて極値を求めます。

組Horizonsこのパッケージ距離の差時刻の差
地球と火星、最小2003-08-27 09:41、0.37272 au09:51、0.37271 au1,410 km10分
地球と火星、最大2066-08-25 00:36、2.67633 au00:28、2.67631 au2,145 km8分
金星と地球、最小2093-12-17 10:40、0.26433 au10:40、0.26432 au1,020 km1秒
金星と地球、最大1960-06-21 23:15、1.73598 au23:27、1.73599 au1,095 km12分
木星と土星、最小1921-07-26 20:13、4.03311 au21:21、4.03309 au3,950 km69分
木星と土星、最大1990-10-01 07:59、15.24084 au09:44、15.24086 au2,025 km105分

距離の差は、毎回、示した不確かさの中に入っています (その3分の1から10分の1)。時刻の差は、数分から1、2時間です。折り返し点では距離がほとんど変わらない (1時間に数km) ので、位置のわずかな差で、頂点が少し早くなったり遅くなったりします。

結果に入っているもの

空の結果は { id, kind, angle, uncertaintyArcseconds }、宇宙の結果は { id, kind, distanceKm, distanceAu, uncertaintyKm } です。近づきは { a, b, time, atEdge, uncertaintySeconds } に、角度と uncertaintyArcseconds、または距離と uncertaintyKm がつきます。time は Date です。

不確かさ (uncertainty) は上限ではなく、理論から期待できる大きさです。精度テストが天体ごとに守らせている限度 (惑星は太陽から見た方向、衛星は惑星から見た方向) を、その天体の距離でキロメートルにして、合わせたものです。2つの天体が共有する誤差は打ち消されます。衛星とその惑星は惑星の誤差を共有するので、木星とイオは、木星自身の位置が3.6秒角の精度でも、1秒角に満たない精度になります。地球から見るときの地球自身の誤差も、空で近くにある2つの天体のあいだでは打ち消されます。uncertaintySeconds は、角度の不確かさを、2つが横を通りすぎる速さで割ったものです。そのため、ゆっくりすれちがう木星と土星 (1秒に0.01秒角) は数分、月と惑星は数秒になります。tables を読み込まないと、木星と土星の衛星は当てはめた軌道なので、不確かさにもそれが出ます。

JPL Horizons との比較

test/nearest.test.ts は、すべての出来事を Horizons 自身の表と比べます。表は一度だけ取得してあり (scripts/fetch-horizons-approach.py が、それぞれの問い合わせを test/data/horizons-approach.json に記録します)、テストにネットワークは使いません。Horizons の赤経・赤緯は天文測位で、地球の中心から、1分刻み (金星と木星は5分刻み) です。2つの近さの最小は、表の最小のまわりで、近さの2乗に当てはめた放物線の頂点です。2026年11月8日の測定です。

出来事Horizonsこのパッケージ時刻の差角度の差
木星と土星、大合2020-12-21 18:21:06、0.10176度18:25:36、0.10184度270秒0.27秒角
金星と木星2023-03-02 05:05:18、0.48915度05:05:41、0.48900度23秒0.54秒角
月と水星、2026年12月12-07 19:49:59、5.70071度19:50:00、5.70086度1秒0.55秒角
月と金星12-05 05:04:49、6.59375度05:04:48、6.59392度1秒0.61秒角
月と火星12-28 13:29:22、4.73649度13:29:29、4.73689度7秒1.45秒角
月と木星12-27 16:26:11、1.38067度16:26:11、1.38056度0.2秒0.40秒角
月と土星12-18 04:37:58、6.17202度04:37:50、6.17212度7秒0.33秒角
月と天王星12-22 02:49:30、5.16230度02:49:24、5.16253度7秒0.80秒角
月と海王星12-17 16:59:52、4.62811度16:59:51、4.62788度1秒0.85秒角

角度の差はどれも1.5秒角以内で、これは惑星自身の精度です。時刻の差は、1時間に0.5度動く月では数秒、大合では270秒です。木星と土星は1秒に0.01秒角しか近づかないので、0.27秒角が270秒になります。テストは、これらより少しだけ大きい限度を守らせ、示した不確かさが差をおおっているかも確かめます。地球上の場所も確かめています。バンクーバーから見た月と金星を30分刻みの25点で比べると、Horizons の地上観測者の表との差は0.9秒角以内で、地球の中心から見たものだと0.85度ずれます。距離は、1800年から2200年の60の日付で Horizons のベクトルと比べています。地球から各惑星までの距離は、すべての日付で示した不確かさの中に入り、いちばん悪い日でもその3分の2です。

探索そのものは、同じ近さを1分刻みでしらみつぶしに調べた結果と比べています (最小の時刻は1分以内、角度は10万分の1度以内)。conjunctions の一覧は、6時間刻みの調べ直しと同じものを見つけます。

かかる時間

node scripts/bench-nearest.ts が、それぞれの探索の時間を測ります。1台のマシン (Node 24、Apple のノートパソコン) で5回の中央値です。

探索時間
nearest、1つの天体と、ほかの46個すべて、ある日付1 ms
closestApproach、金星と木星、1年2 ms
conjunctions、太陽と惑星 (28組)、1年18 ms
conjunctions、月・金星・火星・木星、1年46 ms
conjunctions、木星と4つの衛星、1年1.1 s

どの天体も、1刻みにつき1回だけ計算します。いくつの組に入っていても同じです。なので、天体の数が増えると、時間はその数に比例して増え、2乗では増えません。時間がかかるのは刻みの細かさです。イオの刻みのせいで、ガリレオ衛星の1年の探索は、惑星の探索の100倍ほどかかります。質問に合った within、短い bodies、衛星なら数年までの期間を使ってください。

限界

  • 精度はパッケージの精度です。惑星は数秒角、衛星は軌道の上で1度か2度なので、2つの衛星のあいだの角度は、それより良くはなりません (精度を見てください)。
  • 1つの組の2つの最小が刻みより近いと、見落とすことがありますが、これらの天体にそういう組はありません。逆行のある組 (火星と木星) は、2日以下の刻みで調べます。
  • 距離には光の到着時間がなく、空の角度には光行差と光の曲がりがありません。
  • 1800年から2200年の外では位置が悪くなります。準惑星は、表の年の外では1つの時点の接触軌道要素になります。不確かさにそれが出ます (秒角ではなく度)。
  • target はこのパッケージの天体でなければなりません。惑星にいちばん近い恒星や、惑星がいる星座は、/stars や星座を持つパッケージの仕事です。

ソースを見るGitHub で編集@johnmorrisdotca/wakusei-planets 0.24.0 のソースから作成しました。

この日本語は、まだ日本語を母語とする方の確認を受けていません。訂正を歓迎します。