見出し画像

Cinderellaで3D

Cinderella で空間図形を扱うには次の方法があります。

(1) CindyScript で透視変換のプログラムを書く
 3次元から2次元への変換プログラムを書いて利用します。
(2) Cindy3D を使う
 プラグインのCindy3Dを使います。Cindy3Dではレイトレーシングを用いた描画を行います。ただし,HTMLに書き出してもCindyJSでは使えません。(2024年4月現在)
(3) SpaceCindy を使う
 空間図形を扱う関数群をいれたCinderella のファイルです。
(3) KetCindy を使う
 KetCindy は Cinderella を用いてTeXの挿入図形を描くものです。これを使って3D図形を描くことができます。

それでは順に説明しましょう。

(1) 透視変換のプログラムを書く

座標空間と透視変換

 空間内の点は、x,y,zの3つの座標で表します。各軸の方向の取り方は、親指をx軸、人さし指をy軸、中指をz軸としてそれぞれが直交するようしたとき、次の2通りがあり、右手系、左手系と呼んでいます。

右手系と左手系

 3Dコンピュータグラフィクスでは左手系がよく使われるようですが、学校の教科書は右手系なので,以下は右手系で考えることにします。
 次に、平面上に描いた図が空間図形に見えるようにする方法です。中学や高校の数学の教科書で扱う空間図形は、遠近法を取り入れないで書いてある場合がほとんどです。これを平行投影といい、遠近法を使ったものを透視投影といいます。次の図が平行投影と透視投影です。教科書の図に見慣れていると左の立方体になじみがあるでしょうが,いろいろな図を描いてみると透視投影の方が自然に見えます。

平行投影と透視投影

透視投影では,視点の位置によって見え方が変わります。上の方か下の方か,原点に近いか遠いかです。そこで,次の2つの変数を設定します。
  viewpoint :視点のz座標
  zoom :拡大率
次のスクリプトをInitializationスロットに書きます。点pを透視変換をする関数の定義です。引数のpは、空間座標です。

--- Initialization スロット --------------------------------------
map3d(p):= (
  viewpoint = 8.001;
  zoom = 15;
  mp = p/(viewpoint - p_3);
  [mp.x, mp.y]*zoom;
);
----------------------------------------------------------------

 viewpoint を 8.001としているのは、分母の viewpoint-p_3 が0になることへの備えです。もちろん、これでもviewpoint-p_3が0になることはあり得ますが、その確率はかなり低くなります。透視変換により、x,y座標を小さくしますので、zoomで拡大します。
 p_3は,アンダーバーに続く数がベクトルの何番目の要素かを示しているので p の z 座標です。
 mpが変換した座標です。
 最後の式は戻り値です。平面座標の [mp.x, mp.y] にzoomをかけています。
map3d[2, 2, 2]) のようにすれば空間座標の$${(2,2,2)}$$ が平面座標に変換されます。

軸を回転する

 次の図で、黒の軸はCinderellaの描画面の座標軸です。ここで、z軸が画面の奥から手前に来ている3次元の座標系を考えます。赤の軸がそれで,z軸は原点と重なって見えているとします。この赤の座標系を回転して右図のようにします。

座標系の回転

各軸まわりの回転を表す行列は次のようになります。
z軸まわりの回転 (x → y)
 $${X=(\cos \theta)x+(-\sin \theta)y+0 \cdot z}$$
 $${Y=(\sin \theta)x+(\cos \theta)y+0 \cdot z}$$
 $${Z=0 \cdot x+0 \cdot y+z}$$
これを行列で表します。
 $${\begin{pmatrix} X \\ Y \\ Z \end{pmatrix} = \begin{pmatrix} \cos \theta & -\sin \theta & 0 \\ \sin \theta & \cos \theta & 0 \\ 0 & 0 & 1  \end{pmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix} }$$
同様にして,x軸まわりの回転は
$${\begin{pmatrix} X \\ Y \\ Z \end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos \theta & -\sin \theta \\ 0 & \sin \theta & \cos \theta  \end{pmatrix}
\begin{pmatrix} x \\ y \\ z \end{pmatrix} }$$
y軸まわりの回転は
$${\begin{pmatrix} X \\ Y \\ Z \end{pmatrix} \begin{pmatrix} \cos \theta & 0 & \sin \theta \\ 0 & 1 & 0 \\ -\sin \theta & 0 & \cos \theta \end{pmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix} }$$
となります。

 CindyScriptで、それぞれの行列を用意します。x軸まわりは rtx(θ)というように名前を付けましょう。 Initialization スロットに追加します。
--- Initialization スロットに追加 --------------------------------
   rtx(θ) := [[1, 0, 0], [0, cos(θ), -sin(θ)], [0, sin(θ), cos(θ)]];
   rty(θ) := [[cos(θ), 0, sin(θ)], [0, 1, 0], [-sin(θ), 0, cos(θ)]];
   rtz(θ) := [[cos(θ), -sin(θ), 0], [sin(θ), cos(θ), 0], [0, 0, 1]];
-----------------------------------------------------------------
作図して動作を確かめます。
Cinderellaの描画面の適当なところにに3本の矢印を描きます。線分を加えるツールで線分を描き,インスペクタで矢線にします。
これをx,y,z軸の各軸に乗せます。
 点A,Bの座標を A(-4,0,0) , B(4,0,0) とする。
 点C,Dの座標を C(0,-4,0) , D(0,4,0) とする。
 点A,Bの座標を E(0,0,-4) , F(0,0,4) とする。
CindyScriptのDrawスロットに次のように書いて、Shift+Enterで実行しましょう。

--- Draw スロット ---------------------------------------------  
A.xy = map3d([-4, 0, 0]);
B.xy = map3d([4, 0, 0]);
C.xy = map3d([0, -4, 0]);
D.xy = map3d([0, 4, 0]);
E.xy = map3d([0, 0, -4]);
F.xy = map3d([0, 0, 4]);
-----------------------------------------------------------------

次に座標軸を回転します。ここでは,スライダを作って回転しましょう。
適当なところに線分GH,KL を作図し,その上に点M,Nを乗せます。このスライダでx軸回りの回転角とz軸回りの回転角を取得します。y軸回りは設定しません。そうすれば,z軸が斜めにならずにすみます。後述のCindy3Dではマウスドラッグで自由に回転するのでz軸も斜めになります。
Initializaiton スロットの map3d(p)を次のように書き換え(コマンドを追加)ます。

--- Initialization スロット ---------------------------------------
map3d(p):=(
   viewpoint = 8.001;
   zoom = 15;
   th1 = (2*|M,G|/|G,H| - 1)*pi;
   th2 = (2*|N,L|/|K,L| - 1)*pi - pi/2;
   mat = rtx(th1)*rtz(th2);
   p = mat*p;
   mp = p/(viewpoint - p_3);
   [mp.x, mp.y]*zoom;
);
------------------------------------------------------------------

実行すると次のようになります。

スライダを動かして回転してみましょう。
うまくいったならば,背景の方眼を非表示にし,背景色も変えたり,点の大きさやラベルを変えたり(Bをx,Dをy,Fをz),軸の色を黒にしたりして画面を整えましょう。

正四面体を描く

 では,簡単な図形として,1辺の長さが4の正四面体を描いてみましょう。頂点の座標をmap()で変換し,drawで結びます。

--- Draw スロット ---------------------------------------------
 p1 = map3d([0, 0, 4sqrt(6)/3]);
p2 = map3d([4/3sqrt(3), 0, 0]);
p3 = map3d([-2sqrt(3)/3, 2, 0]);
p4 = map3d([-2sqrt(3)/3, -2, 0]);
draw([p1, p2], size->2);
draw([p1, p2], size->2);
draw([p1, p3], size->2);
draw([p1, p4], size->2);
draw([p2, p3], size->2);
draw([p2, p4], size->2);
draw([p3, p4], size->2);
-------------------------------------------------------------------

さらに詳しいことは,「CinderellaCookBook」をごらんください。

(2) SpaceCindy を使う

 SpaceCindy は,空間図形を扱うための関数群を定義して Initializaion に書き込んである Cinderella のファイルです。Draw スロットにコマンドを書いていけば簡単に空間図形を描くことができます。
 たとえば,次の図(xy平面の方眼と球面)は,Drawスロットに次の5行を書くだけで描かれます。

setview3d(1, 15, 30);
setaxis3d([-3, 3], [-3, 3], [-2, 3]);
grid();
drawsphere([0, 0, 1], 1);
axisdisp();

左側にあるのは円形スライダで,視点を移動することができます。

HTMLに書き出せばWeb上でも動かすことができます。

SpaceCindy はこちらで提供しています。リンク先に行くと,テキストファイルやPDFではないので「プレビューできません」と表示されますが,そのままダウンロードしてください。
マニュアルはこちらです。こちらは PDF です。

(3) Cindy3Dを使う

Cindy3D は Cinderella のプラグインです。
Initailiazarion スロットの先頭に次の1行を書くと使えるようになります。

   use("Cindy3D");

Cindy3Dの図は,Cinderella の描画面とは別のウィンドウに描かれます。

次の例は,水分子を描いたものです。
Initialization スロットには初期設定も書いておきます。

use("Cindy3D");
background3d([0.9, 0.9, 1]);
renderhints3d(quality -> 4);
lookat3d([4, 4, 4],[0, 0, 0], [-1, -1, 0]);

Drawスロットには次のコードを書きます。

//共有結合半径
rh = 0.37;
oh = 0.73;
// 原子間距離
R = 0.957;
th = 104.45°;
begin3d();
// 酸素:赤
  draw3d([0, 0, 1], color->[0, 0, 1], size->0.7);
  drawsphere3d([0, 0, 1], oh, color->[1, 0, 0], alpha->0.6);
// 水素:白
  draw3d([1, 0, 1], color->[0, 0, 1], size->0.7);
  drawsphere3d([R, 0, 1], rh, color->[1, 1, 1], alpha->0.6);
  draw3d([Rcos(th), Rsin(th),1],color->[0, 0, 1], size->0.7);
  drawsphere3d([cos(th), sin(th), 1], rh, color->[1, 1, 1], alpha->0.6);
end3d()

描画面をマウスでドラッグすると回転することができます。
次図,左が実行直後,右が回転したものです。

詳しくは,Cindyscript と CindyJSについてのマニュアルをごらんください。
マニュアルはこちらにあります

(3) KetCindy を使う

 KetCindy はCinderella を使って TeX の挿入図を作成するものです。できたファイルは画像ファイルではなく,TeXのファイルです。(プレビューをスクリーンショットで取れば画像ファイルにできます)
陰線処理などがきれいにおこなわれた空間図形を描くことができます。
しかし,TeXの処理系が必要であるなど,事前の準備にすこし手間取るかもしれません。
KetCindyについては,こちらに公式ページがあります。

TeXを使っている人には便利でしょう。
ここでは詳しくは言及しません。