省略すると言いましたが、何か雰囲気として述べておいた方が良いような気がしました。空中の垂線から円筒とドーナツ型、つまりトーラス(円環)が出てくる、との記述の箇所の説明です。
背景説明は必要でしょう。出来上がりはパソコン画面上の1024×1024ドットの絵です。仮想の奥行きも1024ドットあって、このz方向は完全に重なります(正射影)。
ですから、原理的には各ドットをzの手前側(大きい方)から奥に向かって計算を進めて行き、符号反転、つまり正値から負値、または負値から正値に逆転したところに面がありますから、ドットを打ちます。
実際にはこれでは計算量が膨大すぎるし、ほとんどの計算値は無駄なので、8×8×8ドットの立方体を積み上げた感じとして、つまり8ドット毎に計算し、近づいたら1ドットずつの探索に切り替えます。
円筒の場合は探索点から直線への距離を計算し、円筒の半径の位置を通過したところでプロットします。計算もそこで終了。簡単でしょう?。
つまり、この時に探索点から直線への垂線が距離の線分になっているので、その交点の座標が分かれば直線からの距離が計算できる、ということ。これが少し前の項目にあった計算式です。ついでに、その垂線が法線方向を示しているので、光源を設定すれば明るさが計算できます。
この直線をxy平面に射影すると、円筒は幅のある直線になります。これは簡単に計算できますから、探索範囲は非常によく絞ることが出来ます。この際、公式集ではsin/cosの三角関数が出てきます。これは立体時の単位ベクトルが平面への射影時に縮んでしまうので、座標計算のために平面内で単位ベクトルに伸ばす必要があり、この時に実質的に回転になってしまうから三角関数です。しかし、単位ベクトルに伸ばすだけなので、実際に必要なのはピタゴラスの定理の平方根だけです。現在のCPUでは平方根は極めて高速で、割り算程度に気軽に使って構いません。
複数のオブジェクトの前後関係はどうするのだ、と思った方は筋が良いです。律儀に全オブジェクトを同時に前面から後面に向けて計算しても良いと思いますが、多分計算はオブジェクト毎にしてZバッファと呼ばれるドット毎の奥行き情報を使うと思います。
トーラスの方は自明では無いです。なので、この記事を書いています。
トーラスをどう表すかですが、3次元座標x, y, zで説明します。まず原点を(0, 0, 0)とし、xy平面に半径rの円を描きます。xz平面とは(r, 0, 0)と(-r, 0, 0)の2カ所で交わっています。この2点からそれぞれ半径dの(rよりは小さい)円を描きます。
z軸を中心軸としてxz平面に乗っていた平面を回転させると、その半径dの円はトーラスになります。ここは何とか想像してください。
空間上のある点からz軸に垂線を下ろし、その点をQ、元の探索点をPとします。探索点Pからの距離を知りたいトーラス上の点(S)は、三角形POQの平面内にあり、原点Oからの方向はベクトルQ→Pにある距離rの点(R)を中心として描いた半径dの円上にあり、直線PR上に位置してます。この図が描ければ、点Sの座標が分かり、距離SPが算出でき、その点のトーラスの面の法線の方向はベクトルR→Sです。
本稿では図を示しませんので、かなりの想像力、あるいは幾何学力が必要と思います。ここが前の記事で退屈と言った箇所です。
この操作はトーラスが傾いていても有効なので、任意の位置で大きさで傾きのトーラスが描けます。
とはいっても、まだ私の頭の中でできる、と思っているだけですから、実際にプログラムを組んで確かめてみようと思っている段階です。座標軸と赤道を表すつもりなのでかなり細く(5ドット幅とか)、特に傾きが視線方向に近い場合は工夫が必要な気がします。
トーラスの表面は2次曲面とか4次曲面とかでは無く、関数としてはかなり特殊な形状です。ですからおそらく円筒みたいな便利な探索範囲の絞りはできません。円の直径(2r)+幅(2d)の球内にあるのと、ドーナツの穴と外側の二重円筒の中かどうかは比較的にすぐ分かりますが、この情報が役立つかどうかは試してみないと分かりません。それ以外は一般の陰関数として扱います。
ちなみに、肝心の表示したい陰関数の方はメッシュ(8×8×8)に比べて十分になめらかと想定しています。