FlatTable_P.swf の画像 ビリヤード配置図ソフト
FlatTable
Inside

目次

JavaScript のソース

SVG 版 FlatTabe は、SVG ファイル本体の他に、画面操作などの処理をする JavaScript ファイルで構成されています。それらファイルへのリンクを以下に張っておきます。 FlatTable をローカルに保存して使用する場合、 JavaScript ファイルは SVG 本体に対する相対位置が js/*.js になるようにしてください(ディレクトリ js の下に JavaScript ファイルを入れる)。なお、ダウンロードは、下記リンクを右クリックして「ファイルに保存」などのメニューを実行してください。

目次へ

クリックについて

(注意: この項目は Flash 版についてのみ適用されます)

FlatTableでは、配置図作成は主にマウスを使って行います。球の移動はドラッグ、経路描画の開始と終了はダブルクリック、経路の節点はシングルクリックといった具合です。ところで、ダブルクリックのつもりがシングルクリックと判定されることはないのでしょうか? これらは、どのように識別されているのでしょうか?

FlatTableでのマウス処理は次の2つの状態遷移図に基づいて行われています。
マウス操作の状態遷移図

マウス操作の状態遷移図
ここに、矢印球とは、経路の終端の矢印のことです。

太線の四角形はマウス操作の状態を表していて、中に記されているのはマウスが操作された時に実行する関数です。3つ有る関数は、上から順に、マウスボタンが押された時、放された時、マウスが移動した時に対応しています。矢印に付随している項目のうち、矢印の上(あるいは左)に有るのはマウス操作を表しています。矢印の下(あるいは右)に有るのは、マウス操作に応じて実行する関数です。

球に関するマウス操作を例に、状態遷移を見てみましょう。初期状態は マウス操作の状態遷移図の一部分 です。この状態で、球の上にマウスカーソルを置いてマウスボタンを押す(press)と、状態遷移図の
マウス操作の状態遷移図の一部分
に従って Press という関数が実行され(その関数の中で startDrag も実行されます)、その結果、状態は マウス操作の状態遷移図の一部分 に遷移します。これに続けてマウスボタンを放す(release)と、状態遷移図の
マウス操作の状態遷移図の一部分
に従って関数 Release が実行され、状態は マウス操作の状態遷移図の一部分 に遷移します。その後、マウスを移動(move)させると、関数 Accept が実行され、初期状態に戻ります。
マウス操作の状態遷移図の一部分
この一連の操作がシングルクリックです。マウス移動の代わりに再度クリックすれば、それがダブルクリックとなり、関数 MakeArw が実行されます(経路終端の矢印が表示されます)。

ところで、この状態遷移図には、時間についての記述が有りません。それは、FlatTableでは、マウス操作に関して、時間の監視をしていないからです。このため、1回目のクリックと2回目のクリックの間に1時間の経過が有ったとしても、その間、マウスの移動が無ければ、それはダブルクリックとみなされます。

目次へ

論理座標と物理座標

FlatTableが今後も同じ大きさであるとは限りません。大きさが変更になった時に、それまでの配置コードが使えなくなったのでは困ります。そこで、FlatTableの配置コードでは、球の位置はテーブルの大きさに依らない論理座標で表すことにしました。

FlatTableの論理座標では、センタースポットから短クッションまでを 1080 としています。それに相当する物理座標(実際の大きさに基づいたピクセル数)は 288 となっています。すなわち、配置図から配置コードを生成する時、物理座標に 1080/288 (=15/4) を掛けて論理座標に変換しています。当然、配置コードから配置図を再現する時は、288/1080 (=4/15) を掛けています。仮に、FlatTableの大きさが変更になった時は、それに応じた係数を掛けることになります。なお、「大きさが変更になる」とは、FlatTable作成時の画像の大きさが変更になることであり、ブラウザのウィンドウサイズの違いによる表示サイズの違いとは別のものです。

配置コードの中で、座標は単純な十進数で表されている訳ではありません。大文字・小文字のアルファベット2文字で ±1 ~ ±1080 を表しています。なお、座標 0 は特別に 00 と表しています。第1桁(2文字目)は、A=1, B=2,... z=52 に対応しています。第2桁(1文字目)は、大文字は+、小文字は-を表し、A=0, B=1,... Z=25(a=0, b=-1,... z=-25)に対応しています。そして、
第2桁×52 + 第1桁
が論理座標となります。x と y の2つの座標を表すには4文字が必要で、y, x の順に並べます。例えば、AAAB は y の論理座標が 1(=AA)、x の論理座標が 2(=AB) となります。

y 座標

論理座標コード4文字のうち、初めの2文字は y 座標を表しています。なぜ x ではないのでしょうか?

x 方向の論理座標は、台の端が XS(xS)となっています。一方、y 方向の論理座標は、台の端が My(my)となっています。y 座標を先に記述することにしていれば、その位置の文字が N ~ Z(n ~ z)の時、その文字に座標以外の意味を持たせることが出来ます。もし、x 座標を先に記述することにしていたなら、Y, Z(y,z)しか利用出来ません。 つまり、y 座標を先に記述した方が多くの物を扱える訳です。N ~ Z(n ~ z)には、球やコメントを当てています。実際には、台の外側にも座標を使えるように余裕を持たせているので、P ~ Z(p ~ z)になっています。例えば、P は手球を表します。

目次へ

球の速度の決定

FlatTable のアニメーションは配置図に基づいて実行されるのですが、その配置図には球の速度に関する直接の記述は有りません。アニメーションの為には、配置図から球の速度を導出しなければなりません。球の速度の決定には次の2つの力学要素を用います。

  1. 停止状態からの逆算
  2. 衝突からの逆算
これらについて説明します。

停止状態からの逆算

説明図

転がっている球にはラシャの抵抗が一定の力で働いています。その時の球の速度と移動距離は次のようになっています。
\[\left\{ \begin{array}{rcl} v & = & -\alpha t + v_{0} \\ l & = & -\frac{1}{2}\alpha t^{2} + v_{0}t \end{array} \right.\] ここに、\(\alpha\) はラシャの抵抗による加速度(減速度)、\(v_{0}\) は球の初速度、\(l\) は球の移動距離です。この式の中で配置図から設定できるのは、球の移動距離です。さらに終速度(\(v_{c}\))も既知として方程式を解くと、初速度
\[ v_{0} = \sqrt{v_{c}^{2} + 2\alpha l} \tag{1} \] が求まります。特に終速度が0即ち球が停止する場合の初速度は、 \[ v_{0} = \sqrt{2\alpha l} \] となり、\(v_{c}\) の仮定は必要有りません。

衝突からの逆算

球の衝突の説明図

図のように手球が \(v_{0}\) の速度で的球に当たり、手球の速度は \(v_{1}\) 、的球の速度は \(u_{1}\) になったとします。この時、運動量保存およびエネルギー保存より、次の関係が成り立っています(質量はどれも同じなので省略しています)。
\[\left\{ \begin{array}{rcl} v_{0} & = & u_{1}\cos \alpha + v_{1}\cos \beta \\ 0 & = & u_{1}\sin \alpha + v_{1}\sin \beta \\ v_{0}^{2} & = & u_{1}^{2} + v_{1}^{2} \end{array} \right.\] これらより、散乱角に
\[ \alpha - \beta = \pm 90° \] の関係が有ることが分かります。それを用いて衝突前の手球の速度
\[ v_{0} = u_{1}\sqrt{1+\tan^{2}\alpha} \] が求まります。ただし、これは弾性衝突の場合であって、実際は \(1\) より小さな反発係数 \(k\) を考慮する必要が有ります。従って、衝突前の速度は
\[ v_{0} = \frac{1}{k} u_{1}\sqrt{1+\tan^{2}\alpha} \tag{2} \] となります。これで、衝突された球の速度から衝突した球の速度が求まりました。

目次へ

曲線

FlatTable は Flash アプリケーションとして作られており、 Flash のスクリプト言語は ActionScript です。その ActionScript が標準で備えている曲線描画関数は、2次のベジェ曲線となっていて、これは放物線と同じものです。FlatTable は、この関数を用いて曲線を描画しています。この曲線は、曲線の入り口と出口、そして中間の制御点の合計3点を指定することで決定されます。

静止画の時点では、その関数を利用するだけで良いのですが、アニメーションにする時は、球の移動する速さを決定し、自分で球を移動させる必要があります。それは次のように行っています。

まず、2次のベジェ曲線は \[ P(t) = a(1-t)^{2} + 2bt(1-t) + ct^{2} \;\;\;\; (0 \leq t \leq 1) \tag{1} \] で与えられます。ここに、\( a, b, c \) はそれぞれ、曲線の入り口、制御点、出口の座標です。補助パラメータ \( t \) は \( 0 ~ 1 \) の範囲に規格化されています。したがって、この式をそのまま FlatTable に使用することは出来ません。

そこで、FlatTable での補助パラメータ(時間)を τ とおき、 \[ \tau = \alpha t \] の関係が成り立っているとします。具体的には、\( \alpha \) は曲線の入り口から出口までを球が移動するのに要するコマ数を表しています。\( \tau \) を \( (1) \) に代入して、FlatTable での曲線 \( Q(\tau) \) を得ます。 \[ Q(\tau) = P(\tau/\alpha) = \frac{(a-2b+c)\tau^{2}}{\alpha^{2}} + \frac{2(-a+b)\tau}{\alpha} + a \]

次に、\( Q(\tau) \) を \( \tau \) で微分して速度、加速度を求めます。 \begin{eqnarray} \dot{Q}(\tau) & = & \frac{2(a-2b+c)\tau}{\alpha^{2}} + \frac{2(-a+b)}{\alpha} \\ \ddot{Q}(\tau) & = & \frac{2(a-2b+c)}{\alpha^{2}} \end{eqnarray}

一方、ベジェ曲線 \( P(t) \) を \( t \) で微分して得られる速度、加速度は、 \begin{eqnarray} \dot{P}(t) & = & 2(a-2b+c)t + 2(-a+b) \\ \ddot{P}(t) & = & 2(a-2b+c) \end{eqnarray} となります。これで、曲線の入り口での \( \dot{P}(t), \ddot{P}(t) \) と \( \dot{Q}(\tau), \ddot{Q}(\tau) \) の比が求まります。 \begin{eqnarray} \frac{\dot{Q}(0)}{\dot{P}(0)} & = & \frac{1}{\alpha} \\ \frac{\ddot{Q}(0)}{\ddot{P}(0)} & = & \frac{1}{\alpha^{2}} \end{eqnarray} FlatTable での曲線の入り口の速度は別途求めることが出来るので、\( \alpha \) は計算可能です。曲線の途中の速度は、入り口の速度にコマ数の回数だけ加速度を足すことで求めることが出来ます。これにより、FlatTable で曲線状に運動する球の速度をベジェ曲線から求めることが出来ました。

ラシャ抵抗の効果

上記方法での運動は、球に働く力として、球の回転によってラシャから受ける力だけを考慮したものです。実際は、球の移動によるラシャの抵抗も働いているはずです。その効果を考えてみます。

ベジェ曲線例

ラシャ抵抗を、球の進行方向に対して逆向きで一定の大きさとします。先に求めた速度計算のアルゴリズム中でラシャ抵抗による加速度を考慮した場合と、しない場合の計算例を示します。この例では、球の回転による加速度が y 軸下向きに働いています。ラシャ抵抗を考慮したものは、x 軸方向に詰まって、ベジェ曲線(放物線)から大きく外れていることが分かります。

実は、FlatTable では、ラシャ抵抗を考慮するつもりでいたのですが、このようにベジェ曲線から外れて、配置図の経路を再現できなくなることが分かったので、曲線区間ではラシャ抵抗は無視することにしました。

しかし、曲線区間でラシャ抵抗を無視すると、曲線で終端する経路を作図した場合、その曲線上での速さが0になり、球は停止するという弊害が出て来ます。残念ながら、この問題は解決できていません。

目次へ