球面らせんへの好奇心から作られたビジュアライゼーション
(visualrambling.space)- 3D空間でのオブジェクト移動をパラメトリック関数で表現する方法の概念紹介
- 円、らせん、そして 球面らせん経路 へと、徐々に複雑な経路を数学的に作っていく過程の説明
- 各座標軸(x, y, z)を時間の関数として定義することで、多様な動きを実装可能
- 特に 球面らせん の場合、半径変化を与える三角関数の積によって3次元のらせん経路を生成
- この方法により、任意の経路でオブジェクトを移動できることを示す創造的な例
3D空間でのオブジェクト移動の探究
この文章は、3D空間でオブジェクトを移動させるさまざまな方法と、特に 球面らせん(spherical helix) の経路をどのように数学的に定義し実装するかについての個人的な探究の記録です。
ヘリックスと3次元移動の基礎
-
ヘリックス は、ばねのように回転しながら巻かれていく3次元構造を意味します
-
球面らせん は、球の表面に沿ってらせん状に回るという概念です
-
3D空間でのオブジェクトの位置は x, y, zの3軸の座標 で決まります
- x軸: 左右方向の移動を担当
- y軸: 上下方向の移動に対応
- z軸: 前後(奥行き)方向の変化
-
オブジェクトの位置を 時間(t) に応じた数学関数で定義すれば、移動経路を作ることができます
パラメトリック関数と単純な経路の例
-
例: x位置を
10 * cos(πt/2)と定義すると、2秒ごとに-10から10まで往復する コサイン波状の移動 になります -
同じ方法でy位置を
10 * cos(πt/2)と指定すれば、垂直方向の往復運動も可能です -
x, yに異なる関数(例: x =
10 * cos(πt/2), y =10 * sin(πt/2))を使うと位相の異なる運動になり、これらを組み合わせると 円形経路 が生成されます -
関数に時間に比例する項(例: x =
0.03 * t * cos(πt/2))を掛けると、半径が徐々に大きくなるパターン、つまり らせん(spiral) 経路を作れます
球面らせん(spherical helix)経路を作る
-
従来の平面のらせんと異なり、球面らせん には3次元の経路が必要です
- zの値に
10 * cos(0.02 * πt)などを使うことで、前後位置を段階的に変化させられます
- zの値に
-
x, yには
sin(0.02 * πt)のような 三角関数の積の活用 によって、半径が中央で最も大きく両端で小さくなる効果を演出 -
xとyの両方にこの積を適用することで、円運動をしながら球の表面、すなわち3次元的ならせんに沿って移動する経路を生成できます
-
このような関数の組み合わせにより、球面らせん経路 の数学的実装が完成します
要約と活用
- すべての3D経路は、x, y, zをそれぞれ 時間のパラメトリック関数 として定義することで作れます
- これは、単純な円やらせんから複雑な経路まで数学的に指定できることを意味します
- このアプローチにより、複雑な運動も 実際には混沌ではなく明確に定義された数学的経路である と視覚的に理解できます
visualrambling.spaceは、Damarがさまざまなテーマを学び、視覚的に語る個人プロジェクトです
1件のコメント
Hacker Newsの意見
昔の海上航海では、このような曲線(ラムライン、loxodrome)が非常に重要だった
航海中に同じ方位を保つほうがはるかに簡単だからである
そのため船乗りたちは、できるだけこうした経路をたどろうとしていた
こうしてラムラインという概念が生まれた
Rhumb line ウィキペディア を参照
Mercator地図は、このような方位の計算をより容易にしてくれた
Mercator projection ウィキペディア を参照
この設定自体が、今なお新しい数学的発見を生み続けている
たとえば極座標投影(polar projection)で見ると対数螺旋になる
横から見ると波束(wave packet)になる
その数学的なおもしろさゆえに、Paul Erdös までもが挑戦することになった
参考論文: Spiraling the Earth with C. G. J. Jacobi. Paul Erdös
余談だが、今日は Hacker News で球面幾何学(spherical geometry)の話題が多く上がる日らしい
関連する議論へのリンク:
1番
2番
3番
この曲線は表面上で一定間隔を持つ形になっているが、ラムラインは定義上つねに同じ角度で子午線を横切るため、極地方に近づくほど線がより密になる性質がある
式で書くと、
x = 10 · cos(π·t/2) · sin(0.02·π·t)
y = 10 · sin(π·t/2) · sin(0.02·π·t)
z = 10 · cos(0.02·π·t)
これを球面座標(R=10)に変換すると、
λ(t) = π/2 · t (longitude)
φ(t) = π/2 - 0.02·π·t (latitude)
微分すると d(λ)/d(φ) = -25(定数値)
本物のラムラインでは d(λ)/d(φ) は tan(α) · sec(φ) の形になり、緯度によって変化する
つまり、この曲線はラムラインではない
交差角が変化する曲線に興味があるなら、この可視化リンクを見ることを勧める
これに刺激を受けて、2022年に作った楽しい球面関連プロジェクトを紹介してみる
spheredisksample プロジェクト
今日のようなトレンドにぴったりのプロジェクトだと思う
人が気に入りそうな sphere-resample プロジェクト もあわせて勧めたい
Rhumb line などに関する議論が付いた この投稿 も、あわせて忘れずに参照するとよい
可視化が本当に素晴らしいと思う
もう一つ期待していたのは、「一定の速度で動けるのか?」という点だった
経路に沿って点を配置するのが目的なら問題ないが、実際に動かしてみると、始点と終点でずっと遅く動く現象が見て取れる(ほとんど半径によって決まる)
もし一定速度で動かしたい、あるいは減速・加速するイージング(easing)関数まで適用したいなら、どんな方法があるのか気になる
たぶん数学的にきれいなトリックがあるのだろう
式を微分して速度関数を作り、ピタゴラスの公式で dx, dy, dz を処理し、速度関数の逆関数を使って t' で再パラメータ化(reparameterization)するのだろうと、ぼんやり考えてみただけだ
ただ、このあたりは数学にあまり慣れていないので、ただ口で言っているだけのようにも思える
一定速度で動かすには「ユークリッド・パラメータ化(Euclidean parameterization)」が必要だ
つまり t の値が移動したユークリッド距離に比例するよう調整されなければならない
アニメーションで経路に沿って動かすときには、いつでも必要になる概念だ
ただし普通は閉形式解(closed-form solution)がない場合がほとんどなので、数値的に(計算で)解く必要がある
実際には、各 t ごとに望む距離(ds)に対応する dt を二分探索や補間探索(interpolation search)などで求める
そうして得た結果を保存し、等間隔の点からなるポリラインを作るのが実用的なアプローチである(曲線が時間とともに変化し続けない限り)
質問で触れられている数学的トリックは、まさに「弧長パラメータ化(arc length parameterization)」のことだ
曲線の弧長(arc length)関数の逆関数と合成する作業である
いくつかの特別な曲線族を除けば、たいていは閉形式を持たないので、計算的に扱うことになる
t をゆっくり動かそうという直感は正しい
t に応じて角速度は保たれるが、半径もまた t によって変化するからだ
一種の Archimedean spiral の発想である
速度の大きさを定数にしてパラメータ化すれば、より一定した移動が可能になる
ただし半径が 0 から始まるため、何らかの形で極限値(limit)を扱わなければならない
ゲームなどで経路をたどらせるなら、Z軸基準で経路と接線をターゲットにし、繰り返し速度に制約をかけながらドラッグして bead toy のように動かす単純化も実用的だ
「…実際には chaotic なものではない。単に数学関数で定義された経路だ」という部分について、
提示された関数が実際にカオス現象を示すかどうかは分からないが、カオスという概念自体は本質的に決定論的な数学関数から現れる現象(初期条件に極端に敏感に反応すること)である
おそらく投稿者は "random" や "non-deterministic" の代わりに "chaotic" という語を選んだのだろう
こうした技術的な指摘は非常に重要だと思う
Hacker News の読者なら(あるいはそうあるべきなら)、この区別は興味深いはずだ
数学においてカオスとは、初期条件に極端に敏感な決定論的システムのことである
結果はランダムに見えるが、実際にはランダム性(randomness)とは概念的にまったく異なる
カオスという用語自体が決定論的な数学関数で発生する性質だという点には同意する
ただ、日常的な辞書の定義では、「完全な無秩序と混乱」「偶然に支配された状態」「複雑な自然システムの予測不可能性」などを意味する
普段こうした文章を読む人々の期待や言語習慣に合わせるため、数学的厳密さよりも分かりやすい言葉で説明するやり方にも十分意味があると思う
フィードバックを一つ挙げるなら、モバイルでのナビゲーション方式が予想と違っていた
どう操作するのか分からず、スクロールしようとした
画面タップで次のページに進むのを見て、「ああ、そういうことか」と思った
右側を押すと次のページへ進んだので、あとでさらに一度クリックしたとき左側を押して戻ろうとしたのだが、かえって二ページ飛ばしてしまった
そのせいで一部の画面を見逃してしまい、少し残念だった
大きな問題ではないが、少し案内があれば混乱が減って、もっと集中できただろう
それでも補助的に swipe 操作を追加してもよいと思う(個人的には tap 操作のほうが好きだが)
ソーシャルメディアアプリの「カードスタック」インターフェースに似せるなら、swipe も自然だろう
内容が基本的な入門レベルなので、子どもが数学を学ぶときの参考としてよさそうだ
円(circle)の公式(x = r cos t, y = r sin t)のような数学概念にも途中で触れていれば、なおよかったと思う
さらに発展させやすい話題としては、極座標(polar coordinate)や線形代数(ベクトル、変換、3D空間での変換など)がある
著者自身がこうした話題に慣れていないなら、3blue1brown の YouTube 動画を勧めたい
プログラマの立場からすると、コーディングやライブラリ、実際の 3D オブジェクト(頂点、変形など)を扱う部分が欠けているので、そこまで扱ってくれればさらによかった
球面ヘリックスにおける Z 軸方向の移動の「正確さ」が気になった
z = c * t のようにいろいろな関数で単純に動かせるが、その場合「皮(peels)」の厚み、一貫性、均一性などが変わってくる
ここで使われている関数は見た目には美しいが、螺旋間の距離の一定性(あるいは均一な面積分割など)という観点で、目標をどう定めるのがよいのか気になる
この関数がどんな過程で選ばれたのか、それとも単に見た目が良いから選ばれただけなのか気になる
おそらくこの関数は、実装しやすく見た目も良いから単純に選ばれたのだと思う
本当に「正確な」やり方は、3D空間で点が一定速度を保って移動すること(たとえば実際の地球上で船が動くときのように)だろう
その場合の式は(コード例を参照)
const degrees = Math.PI / 180
const bearing = 5 * degrees
const k = Math.tan(bearing)
const v = 0.001
const phi = (t) => vt/Math.sqrt(1 + kk)
const theta = (t) => k*Math.ln(Math.tan(phi(t)/2))
x, y, z 座標に変換
const x = (t) => Math.sin(phi(t)) * Math.cos(theta(t))
const y = (t) => Math.sin(phi(t)) * Math.sin(theta(t))
const z = (t) => Math.cos(phi(t))
実際には tan(phi/2) の対数関数まで使う必要があり、これは微分方程式を解いて出てくる形だ
おそらく著者は、この程度に複雑な方法(ln(tan(phi/2)))までは使っていないのだろうと思う
経路の速度を一定にすること(velocity constant)が核心だ
導関数を設定して速度を定数にし、そのうえで z について解くか、t’ で再パラメータ化(reparameterization)する方法でアプローチできる
z = c * t を選ぶことは、経路のパラメータ化と実際の軌跡の両方を同時に決める影響を持つ
アニメーションがとても滑らかで印象的だった
最近、球面上に N 個の点を分散させる問題を扱うことがあり、その過程で "fibonacci-sphere" というシンプルなアルゴリズムを見つけた
この方式も球面上に螺旋を生成して点を配置するのに使われる
関連論文: fibonacci-sphere 論文 PDF
Acko.net がまだ言及されていないことに驚いた
似たような道具を使って複素数やフラクタル、とくに Julia fractal を視覚的に説明する素晴らしいブログ記事がある
関心のある人ならぜひ読むべきだ
How to fold a julia fractal - Acko.net ブログ
3D Desmos でこの曲線の式を直接いじってみることができる Desmos 3D 可視化リンク
この螺旋のパラメトリック方程式が球面座標系で線形になっているのも興味深い
座標変換ウィキペディア を参照
共有してくれてありがとう。本当に興味深く見た