地球と衛星のアニメーションをThree.jsとsatellite.jsで作成

![Three.jsとsatellite.jsでアニメーション](https://raw.githubusercontent.com/cheer4u-code/jeisakko/main/jeisakko.png)

# 地球と衛星のアニメーション

スカパーの芦田愛菜さんのCMを見て、スカパージェイサッ子さんが地球を回っているのってどんな感じなのかなと思ったのと、javascriptの勉強をかねて、Three.jsを使って、スカパージェイサッ子さんが地球を回っているのをアニメーションしてみました。

https://threejs.org/

作成したコードは、https://github.com/cheer4u-code/jeisakko にあります。この記事では、ソースコードの解説は書いていません。大まかな内容だけになっています。
今回作成した、アニメーションは以下で見られます(githubってありがたいです）。

https://cheer4u-code.github.io/jeisakko/

~~太陽の方向が計算できていないのや、~~ コードがきれいに書けなかったです。
太陽の方向の計算はWkipediaなどを見たりして入れてみましたが合っているのかが不明です。

# Three.jsとsatellite.js

## 座標

Three.jsの座標を衛星の座標系で使われるECI（地球中心慣性座標系）かECEF（地球中心・地球固定座標系）に割り当てる必要があります。
衛星の位置は、2行軌道要素（TLE）を読み込んで、位置を返してくれるsatellite.jsを使っています。

https://github.com/shashwatak/satellite-js

satellite.jsがECIを返してくれて、その後ECEFに変換していたため、あまり何も考えずに、ECIをThree.jsの座標に割り当てています。
また、satellite.jsは、kmが単位なので、それをそのままthree.jsの座標として使っています。

:::note info
地球を自転させるアニメーションには、ECIがよく、地球中心に衛星がどこを通るかみるには、ECEFがよいと思っています。いろいろ試していたら処理が重くなったので、もう少し考えたほうがよかったのかも。
:::

Three.jsを使う場合は、Z軸が上下でなくY軸になるためECI（地球中心慣性座標系）変換が必要です。
そのため下記のように変換することにしました。

|Three.js Axes|ECI/ECEF|
|:-:|:-:|
| x | x |
| y | z |
| z |-y |

## GUI

three.js には、GUIのパラメータを入力するのに便利なGUI(lil-gui)というのがあります。
それをつかって、パラメータの変更や、衛星の高度や緯度、経度を表示するようにしています。

## 時間

three.jsで衛星の位置計算するには、時間を管理する必要があります。
アニメーションをレンダリングするときに、javascript Date を使うと実時間でアニメーションすることになります。
今回は、衛星を数倍速で動かして、衛星の動きが見たかったので時間は内部で管理しました。
three.jsでは、アニメーションように Clock があります。今回は、タイムスケールが使える Timer を使いました。私は、Clock より Timer のほうが使いやすかったです。

https://threejs.org/docs/#api/en/core/Clock

https://threejs.org/docs/#examples/en/misc/Timer

タイムスケールをGUIから変更できるようにしたので、いろいろな速度で見ることができるようになりました。

# Three.jsで使う画像

スカパージェイサッ子さんをイメージにしたので、いらすとやさんの世界地図を編集したのをテクスチャとして使ってます。

https://www.irasutoya.com/2013/02/blog-post_8574.html

他に衛星やISSもいらすとやのイラストを使っています。
スカパージェイサッ子さんのイラストは、下記のページのを参考にして自作しています。

https://www.skyperfectjsat.co.jp/brand/michikachi/cm/

# カメラ

カメラの位置は、cameraのpositionでなく、カメラ制御（OrbitControls）の position0 に設定して、reset() を呼び出しカメラの初期位置を設定しています。
カメラの初期位置に戻したいとき、使えると思ってそうしています。

# 光源

太陽の代わりに、平行光源を使いました。また平行光源が当たらないところは、暗くなるため、環境光源も使っています。
太陽の方向が計算していないため、時間と太陽の方向があっていません。

Wikipedia に太陽の位置計算がありました。これを使えば光源の方向を計算できそう。

https://en.m.wikipedia.org/wiki/Position_of_the_Sun

赤道座標が計算できるので、それで太陽の方向がわかりそう。

suncalc も内部では赤道座標を計算しているように見えますが、関数が公開されてない？

https://github.com/mourner/suncalc/blob/master/suncalc.js#L67

# 星

地球と衛星だけでは、寂しいとおもったので、星をちりばめています。
地球が自転するため、地球の自転に合わせてカメラを動かすと、星が動きます。
早いと目が回りそうなので、星を表示する/しないをGUIに追加しました。
小さくてわからないかもしれませんが、星もいらすとやのイラストを使っています。

# 地球

東京の座標に、家のイラストを置いています。特に意味はありません。

# 軌道

軌道計算は、satellite.js を使っています。

2行軌道要素（TLE）は、CelesTrak から取得したのをソースコードに埋め込んでいます。

https://celestrak.org/

# 衛星

スカパージェイサッ子さんの衛星は、スカパーの衛星 JCSAT-17 のTLE を使っています。
JCSAT-17 って静止衛星なので、地球の自転一緒に動いているのがわかります。

スカパージェイサッ子さんの衛星は、地球の緯度・経度のどのあたりなのかわかるように、線をいれています。
あと、小さいのでわからないとおもいますが、カメラとの位置を確認して、テクスチャを入れ替えています。

# その他衛星

ISSや、だいち や みちびき を表示しています。
ISSは、低軌道を回っています。結構早いことがわかりました。
だいちは、常に日があたるところを回っています。今回作成したのは、太陽の位置が計算されていないので、日が当たらないところを通っていますが本来は日が当たるところを通っています。
みちびきは、準天頂軌道ですが、静止衛星や日本上空でないのもありました。

# ソースコードの量

index.htmlからmain.jsを呼んでいます。index.htmlは、javascriptのモジュールように importmap があるのと、モジュールに対応していない satellite.js を読み込んでいます。

main.js が今回作成した部分になります。500行未満になったので、three.js を使うと簡単に 3D が書けることがわかりました。

# スターリンクの衛星の表示も試し中

簡易ですが、スターリンクの衛星を表示するのも試しています。こちらは座標系をECEF（地球中心・地球固定座標系）にしています。

:::note warn
衛星の数が多いので、PCに負荷がかかります。注意してください。
:::

https://cheer4u-code.github.io/jeisakko/starlink.html


次書くときは、これらの経験を活かしたいと思う