WP QuickLaTex – 数式の記述

概要

WordPressで整った数式を表示したいとき、MS-Officeの数式エディタの表示を画像として張り付けることを考えたが、探してみると”MathJax-LaTeX”というプラグインがよく紹介されていた。LaTexの書式で書いた数式が整形されて画像として張り付けられるらしい。

MathJax-LaTexはプラグインをインストール後、記事の冒頭にショートコード[mathjax]を書き、そのページ内でLaTexの記述が可能になという手軽なものなので、一度導入して試してみた。

ところが、ショートコードを入れたると$$マークや$マークが数式整形のための記号として認識されてしまう。たとえばjQueryに関する記事中やスクリプトコードで$マークを使うとややこしいことになる。また数式をインラインで書けないとか、テキストモードで複数行にわたる数式を書けないとか、いろいろ制約があるようだ。

そこでほかにもプラグインはないかと探して、以下のサイトに辿り着いた。

WordPress の数式整形プラグイン

WP QuickLaTex“というプラグインがあるそうで、試しにインストールしてみたところ悪くない。

導入手順

  1. プラグイン”WP QuickLaTex”をインストールし、有効化
  2. QuickLaTexの設定でインライン記述の$…$を無効化
  3. 数式を表示したい記事に以下のショートコードを書く(これにより、latexの$$記号が有効化される)

    あるいは、ショートコードなしで記事中でのショートコードで囲んだ部分はQuickLaTexの認識対象になる。
  4. LaTex形式で数式を記述

インラインスタイル

インラインスタイル(a=1のような書き方)の場合は、以下のようにショートコードで囲む。

この機能は、冒頭にショートコードを書かなくても使える。

ディスプレイスタイル

式を別段落で表示させるディスプレイスタイルの書き方には、以下の2つの方法がある。

latexpageショートコードを書く場合

この場合、ショートコード以前の$$マークは無視されるが、ショートコードを書くと記事中の$$マークはQuickLaTexが数式解釈に使う。

latexpageショートコードを書かない場合

ディスプレイスタイルでは、上記いずれの書き方でも、テキストモードで改行して複数行にわたって記述可能。

結局現在は、ディスプレイスタイルも単に[latex]...[/latex]記号のみで書いている。

 

注意点

  • $マークを設定で無効化した場合ショートコード以降の記事の中に直接$マークは書ける
  • latexpageショートコード書くと記事中のの$$マークが数式解釈に使われる
  • 改行文字(\\)は機能しないが、\begin{align}~\end{align}\begin{array}{...}\end[array]で括ると改行される
  • 以下のケースではうまく表示されない
    • ドルマーク2つで数式を書いた直後の行が<pre></pre>の場合、表示されない

記述例

WP QuickLaTexでLaTex形式の記述がどのように表示されるか列挙する。

記号

文字

{\rm }で斜体を通常書体に、{bf }と\mathbf{}は同じで太字、{\boldmath }は機能しない。いずれもギリシャ文字(小文字)には効かない。

     \begin{align*} &abcABC \alpha \beta \gamma \\ &{\rm abcABC \alpha \beta \gamma} \\ &{\bf abcABC \alpha \beta \gamma} \\ &\mathbf{abcABC \alpha \beta \gamma} \\ &{\boldmath abcABC \alpha$ \beta \gamma} \end{align*}

その後、\boldsymbolでアルファベットの大文字・小文字、ギリシャ文字を斜体太字にできることがわかった。

     \begin{gather*} \boldsymbol{abcABC \alpha \beta \gamma} \end{gather}

等号・不等号

    $$ \begin{align} &a = 1 \\ &a \neq 2 \\ &a \leq 2 , \: a \leqq 2 \\ &a \geq 0 . \: a \geqq 0 \\ &a \sim 1.1 , \: a \simeq 1.1 , \: a \approx 1.1 , \:a \fallingdotseq 1.1 \end{align} $$

加減乗除

普通の記号

    $$a + b \times c \div d$$

分数

分数の記述は\fracで(分子・分母で\fracを使うと小さくなるので、元のままのサイズにしたいときは\dfracを使う

\frac{\frac{1}{2} + \frac{1}{2}}{\dfrac{1}{3} + \dfrac{1}{3}}

括弧

分数などに対して背の高い括弧を使うときは、\left(、\right)などを使う。

    $$ \left( \frac{1}{2} + \frac{1}{3} \right) \times 6 = 5 $$

ドット表記

    $$z = x \cdot y$$

プラス/マイナス

    $$ \begin{align} a \pm b \\ a \mp b \end{align} $$

多項省略・ドット表記

    $$ \begin{align} S &= 1 + 2 + \cdots + 100 \\ S &= 1 + 2 + \ldots + 100 \\ &\vdots \\ &\ddots \end{align} $$

矢印

    $$ \begin{align} &\leftarrow \: \Leftarrow \: \longleftarrow \: \Longleftarrow \\ &\rightarrow\ \: \Rightarrow \: \longrightarrow \: \Longrightarrow \\ &\leftrightarrow \: \Leftrightarrow \: \longleftrightarrow \: \Longleftrightarrow \\ &\uparrow \: \Uparrow \: \downarrow \: \Downarrow \\ &\nearrow \; \searrow \; \swarrow \: \nwarrow \end{align} $$

    $$\angle R = 90^\circ$$

基本形

latexショートコードだけで囲むと、数式が左詰めになり、式番号なしで数式が表示される。

     \begin{equation*} z = x + y \end{equation*}

equation環境では、数式がセンタリングされ、式番号が付けられる。

     \begin{equation*} z = x + y \end{equation}

複数行の数式

eqnarray環境では、複数式を一つにまとめて扱える。

     \begin{eqnarray*} (a + b)^2 &=& a(a + b) + b(a + b) \\ &=& a^2 + b^2 + 2ab \\ (a + b)(a - b) &=& a(a - b) + b(a - b) \\ &=& a^2 - b^2 \end{eqnarray}

  • 改行位置に”\\”を記述
  • 等号などで縦位置を揃えたいときは、’&’で囲む

方程式の左を中括弧で囲いたい場合、\left\{とするが、eqnarray環境ではうまくいかない。array環境を使えばよいが、若干の注意点がある。

  • 全体をequation環境で囲う(行番号が不要の場合にはequation*)
  • 中括弧の場合は\{とエスケープする
  • 右側の括弧を省略する場合は\right.

     \begin{equation*} \left\{ \begin{array}{lll} x + y & = & c \\ x ^2 + y^2 & = & r^2 \right. \end{array} \end{equation}

単に中央ぞろえで複数行の式を書きたい場合はgather環境が手軽。式番号は自動でつけてくれる(以下の例ではgather*として式番号を抑止している)。

     \begin{gather*} a x^2 + bx + c = 0 \\ a \left( x + \frac{b}{2a} \right) ^2 - \frac{b^2}{4a} + c = 0\\ x + \frac{b}{2a} = \pm \sqrt{\frac{1}{a} \frac{b^2 - 4ac}{4a}} \\ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} \end{gather}

式中の任意の位置でそろえるにはalign環境と&記号を使う。たとえば全体をセンタリングしながらその中で式を左揃えにしたい場合、全ての式の先頭に&記号を置けばけばよい(もちろん、式ごとの揃える位置を変えることもできる)。

     \begin{align*} & x^2 + y^2 = r^2 \\ & x = r \cos \theta , y = r \sin \theta \\ & r^2 \cos ^2 \theta + r^2 \sin ^2 \theta = r^2 \end{align}

スペース

1文字、2文字分のスペース(quad, qquad)

\quad x \quad y
\qquad x \qquad y

任意長のスペース(hspace)

\hspace{12pt} x \hspace{12pt} y
\hspace{1pc} x \hspace{1pc} y
\hspace{12mm} x \hspace{12mm} y
\hspace{1.2cm} x \hspace{1.2cm} y

短いスペース

\! x \! y
\, x \, y
\: x \: y
\; x \; y

\!は負のスペースで、後ろの文字を前へ詰める。

A \! \! \! B(AとBの間に\!が4つ)

任意の文字分のスペース

\phantom{} 1+1\phantom{-}1

分数・括弧

    $$ \left| \frac{c+d}{a+b} \right| ^2 = \left( \frac{c+d}{a+d} \right) ^2 = \left\{ \frac{c+d}{a+d} \right\} ^2 $$

平方根・n乗根

    $$ \begin{align} &l = \sqrt{x^2 + y^2} \\ &\sqrt[n]{x} \end{align} $$

\sqrtのn乗根のnは”[n]”と大括弧で、数値xは”{x}”と中括弧で書いている点に注意。

指数表現・添字表現

    $$z_i^n = x_i^n + y_i^n$$

関数

三角関数

    $$ \begin{align} &\sin x , \cos x , \tan x \\ &\sec x , \csc x , \cot x \\ &\arcsin x , \arccos x , \arctan x \end{align} $$

対数

    $$\log_2 x ,\: \log x ,\: \ln x$$

総和・総積

    $$ \begin{align} &S = \sum_{n=1}^{10} n \\ &P = \prod_{m=1}^{10} m \end{align} $$

順列・組み合わせ

順列・組み合わせのように、記号の前にプレフィックスが付く場合は、ダミーに対してサフィックスを付ける。

     \begin{align*} {}_n P_k \quad {}_n C_k \end{align}

組み合わせを二項係数の形で書く場合は\binomを使う。使い方は\fracと同じで、分数などの中で小さくなるのを避ける場合には\dbinomを使う。

     \begin{align*} \binom nk \quad \binom {n-k}k \quad \frac{\binom{n-k}k}{\dbinom k{k-r}} \end{align}

ベクトル・行列

ベクトル

列ベクトルはarray環境でn行1列とする。{c}は各要素を中央ぞろえで、左揃えならl、右揃えならr。

    $$\vec{a} =  (a_1, \cdots , a_n)$$

    $${\bf a} = \left( \begin{array}{c} a_1\\ \vdots\\ a_n \end{array} \right)$$

行列

行列はarray環境で

    $$ {\bf A} = \left[ \begin{array}{cccc} a_{11} & a_{12} & \cdots & a_{1n}\\ a_{21} & a_{22} & \cdots & a_{2n}\\ \vdots & \vdots & \ddots & \vdots\\ a_{n1} & a_{n2} & \cdots & a_{nn} \end{array} \right]$$

ベクトル・行列の太字表記

QuickLatexでベクトル・行列を太字で表記する方法。

    $$ \boldsymbol{Ax} = \lambda \boldsymbol{x} $$

ノルム・垂直・平行

     \begin{gather*} \| \boldsymbol{a} \| \\ \boldsymbol{a} \perp \boldsymbol{b} \\ \boldsymbol{a} \parallel \boldsymbol{b} \end{gather}

行列の転置

二通りの転置行列の記述方法。

 

     \begin{gather*} {}^t \boldsymbol{A} \\ \boldsymbol{A} ^{\rm T} \end{gather}

微分・積分

    $$ \frac{dy}{dx} = f'(x) $$

 

    $$ \Delta f = \nabla^2 f = \frac{\partial^2 f}{\partial x^2} + \frac{\partial^2 f}{\partial y^2} $$

    $$ \int_a^b f(x) dx $$

上括弧・下括弧

    $$ \overbrace{1, 2, 3, 4,}^{\rm over} \underbrace{5, 6, 7, 8}_{\rm under} $$

筆算

簡単な筆算は、arrayブロックで\hlineを使う。

    $$ \begin{array}{rr} & 12345 \\ + & 678 \\ \hline & 13023 \end{array} $$

多項式の和になるとちょっとややこしい。

    $$ \begin{array}{rcccccc} A_n &= &a_1 &+ &\cdots &+ &a_n \\ B_n &= &b_1 &+ &\cdots &+ &b_n \\ \hline A_n + B_n &= &(a_1 + b_1) &+ &\cdots &+ &(a_n + b_n) \end{array} $$

 

CS/JS – Mathクラスメソッドの実行速度

概要

2点間の距離を比較するときに、sqrtといった関数で距離を求める汎用メソッド/関数を使うのに対して、距離の2乗のままで比較して計算スピードを上げることが考えられる。

昔の大型計算機で大きな規模の方程式を解くときなどは、計算スピードを上げるために距離の2乗のままで比較をしていたりしたが、簡単なシミュレーションやアニメーションなどで、それがどれくらい効いてくるのかがよくわからなかった。

そこで、他の関数も含めて、Mathクラスのクラスメソッドとして定義されている浮動小数点系の関数群の実行時間を計ってみた。

結果概要

加減乗除算の間では実行時間にあまり差はなく、これらを1としたときの各関数の実行時間程度は以下のようになった。

+-*/ 1
abs、sqrt、exp、log、random 1
sin、cos 2~3
tan、atan 4~5
atan2 5~6
asin、acos 6~7
pow(**) 7~8

一般的な方針

先の結果から、浮動小数点の計算を含むコードに関して、以下のようにまとめられる。

  • 距離の計算などにsqrtを気軽に使ってもよい(足し算を一つ増やす程度)
  • exp、logも気軽に使ってよい
  • 累乗計算はコストが高い
    • 距離計算などで自乗項が出てくる場合、乗算に変更した方がよい
  • 三角関数は、加減乗除の2~5倍のコスト
  • 逆三角関数は、加減乗除の5~7倍のコスト

参考

実行環境1

  • mouse製ノートPC
  • Celeron-325U/1.70GHz
  • RAM 8GB
  • Windows 10 Home(64bit)

コンソールからテストコードを実行。

ここでa = 1.1、b = -2.2で、各関数の繰り返し回数は100万回。時間の単位はミリ秒。

a+b 17 17 17
a-b 26 26 28
a*b 20 18 20
a/b 16 17 18
a**b 156 157 157
abs(a) 29 27 30
abs(b) 30 29 30
sqrt(a) 29 30 31
sin(a) 71 71 71
cos(a) 59 61 61
tan(a) 83 84 84
asin(a) 125 128 128
acos(a) 124 127 125
atan(a) 85 84 87
atan2(a) 138 140 146
exp(a) 15 17 17
log(a) 15 17 18
random(a) 26 27 27

実行環境2

  • 自作PC
  • Intel Core i5-4670/3.40GHz
  • RAM 4.00GB
a+b  9  10  9
a-b 12 11 12
a*b 7 9 7
a/b 7 7 7
a**b 72 71 72
abs(a) 11 12 17
abs(b) 12 17 12
sqrt(a) 13 13 13
sin(a) 27 25 23
cos(a) 24 25 25
tan(a) 43 43 42
asin(a) 53 53 54
acos(a) 53 50 51
atan(a) 41 41 41
atan2(a) 61 62 58
exp(a) 7 7 8
log(a) 6 7 7
random(a) 12 13 12

テストコード

 

CS/JS – Math.signが使えない話

CoffeeScriptで書いたコードが、ローカルでもネット上のWordPressでも動くことを確認したが、Android端末で動かないという事象が発生した。

同じ症状がWindowsマシンのExplorerでも起こったので、開発ツールで確認したところ、”Math.signはサポートされていない”とのこと。

調べてみると、JavaScript | MDN(Mozilla Developer Network)のMath.sign()のところでブラウザ実装状況を見ると、

  • デスクトップでは、Chrome38、FireFox(Gecko)25、Opera25はサポート、IEとSafariは未サポート
  • モバイルでは、Firefox Mobile(Gecko)25のみサポートで、あとは全滅

当分、この関数は利用できそうにないので、以下のように値を絶対値で割って取り出すのが手っ取り早い(可読性は悪くなるが)。

 

Boids 1.x – コード説明

Boids 0.5

全体構成

Boidsを構築していくために、以下のような全体構成とした。

HTML
WordPressのテキストエディタで、入力やボタン、canvasなどの必要な要素を書き込む。
外部スクリプトファイル
各バージョンのBoidsを実行するための外部スクリプトファイルを用意する。バージョンごとにパッケージ化する。

HTML

個体数をセットするためのinput要素のタイプは”number”とした。こうすることにより、ボックスの右側に値をコントロールする矢印が出たり、最小値の指定などができる。

ボタンはWordPressでonclickを使うと問題が生じるので、HTMLでは単にボタンを表示させるだけとし、リスナについてはコード側で対応する。

canvas要素は書き方によってWordPressで勝手に変更されてしまうので注意。

input要素とcanvasについては、コード側から参照するためのidを付与している。

スクリプトについては、jQueryはWordPress側で読み込まれるとのこと。外部スクリプトファイルは、</body>タグの直前あたりを想定して、WordPressのテキストモードで最後尾にscript要素を書いた。<script type="..." src="..."></script>とテキストモードで書いても、ビジュアルモードを経由すると以下のように書き換えられてしまう。

  1. 勝手にCDATAのパターンが挿入され、間に改行が入ってしまう
  2. srcとtypeの指定順序が逆になってしまう

クラス構成

クラスは以下の4つを準備

  • Boidsの活動領域となるFieldクラス
  • 個々の個体を表現するCreatureクラス
  • 複数のCreatureが集まった群を表現するClusterクラス
  • 各オブジェクトを生成し、ボタン操作に対応してアニメーションをコントロールするControlerクラス

パッケージ

異なるバージョンのBoidsを同じページで動かすため、バージョンごとのパッケージに上記4つのクラスを入れることとした。

初めのバージョンに対応したパッケージ名はboids05で、グローバルにアクセスするのはControlerオブジェクトだけとし、Boids05.Controlerを定義している。

そして最後に、このスクリプトファイルが読み込まれたときにボタンに対するリスナを登録するための処理を記述している。

各ブロックとクラスの説明

リスナ登録

jQueryの構文を用いている。WordPressでjQueryを用いる場合、”$”が別のエイリアスに定義されているらしいので、1行目のように書くとのこと。

1つ目のブロックではcanvas要素のDOMオブジェクトを取得し、controlerオブジェクトを生成して初期値をセットしている。

この段階では速度関係は必要ないが、次のステップの前にとりあえず実装したため、Controler.setVMax()メソッドを読んでいる。

2つ目のブロックでは、ボタンが押されたときの処理を記述しており、numberボックスから値を読み込み、それに基づいて個体生成の指令を出している。

Controlerクラス

ブラウザ側からの指令と、スクリプト内の各クラスとの仲立ちを一手に引き受けるクラスで、この段階では以下の機能を提供する。

constructor
canvasオブジェクトを渡してControlerオブジェクトを生成する。
constructor(canvas)
canvasオブジェクトを渡してConstructorオブジェクトを生成する。
setVMax(vMax)
ランダムに生成する速さの最大値をConstructorオブジェクトにセットする。
createCreature()
位置と速度(速さと方向)をランダムに与えて個体を生成する。
generate(population)
指定した数の個体を生成し、Clusterオブジェクトに格納する。

Fieldクラス

将来の拡張も考慮して、一つのクラスとした。現時点では単なる矩形で、上下左右の座標値をプロパティに持つ。

Clusterクラス

Creatureオブジェクトを1~複数保持する「群」のクラス。提供する機能は以下の通り。

constructor(canvas)
個体を描画するcanvasを渡してClusterオブジェクトを生成。
clearCreatures()
群の個体を空にする。
addCreature(creature)
Creatureオブジェクトを渡し、群に追加する。
draw()
群の全ての個体を描画する。実際には、保持している個体のdraw()メソッドを呼び出しているだけ。

Creatureクラス

個々のクラスを表現するクラス。このバージョンでは運動はさせないが、速度関係のプロパティや初期化は行っている。

constructor(canvas)
Fieldオブジェクトを指定してCreatureオブジェクトを生成。
setPosition(x, y)
個体が存在する座標を指定。
setVelocity(vx, vy)
速度の成分をセット。このバージョンでは必要ないが実装。
draw(context)
描画コンテキストを指定して、個体を描画する。このバージョンでは単純な円を描いている。

Boids 1.0

HTML

Boids 1.0用のボックスやボタンを用意し、外部スクリプトファイルを読み込んでいる。

このバージョンから個体の運動をさせるので、Start/Stopボタンを追加している。

パッケージとクラスの変更

パッケージ構成

パッケージについては、パッケージ名やエイリアスを変更。

また、個体の運動を追加するため、以下のメソッドを追加。

  • Creature.move(interval_sec)
  • Cluster.move()
  • Controler.setIntervalSec(interva._sec)
  • Controler.startAndStop()

Creature.move()

秒単位のフレームタイムを指定して呼び出される。

  • 各個体の速度で等速度運動
  • 壁に当たった場合は全反射

Cluster.move()

秒単位のフレームタイムを指定し、群の個体の数の分だけCreature.move()メソッドを呼び出す。

Controlerクラス

変更内容は以下の通り。

プロパティ追加
アニメーションをコントロールするプロパティとして以下を追加。

  1. 運動中かどうかを保持するisRunningフラグ
  2. 作動中のintervalタイマを保持するtimer
  3. 秒単位のフレームタイムを保持するinterval_sec
setIntervalSec(interval_sec)
アニメーションのフレームタイムをセット。
startAndStop()
Start/Stopボタンを押すごとに、作動状態と停止状態を切り替え。特にリスナにコールバック関数を無名関数で登録するときに、thisをバインドするためのファットアローを使っていることと、無名関数で引数を表示する記法に留意。

 

Boids 1.1

このバージョンでは、個体を壁にぶつかってから全反射させるのではなく、壁が近づくとともに斥力を感じるように壁を避けようとする動作を導入する。

HTML

Boids 1.0用のボックスやボタンを用意し、外部スクリプトファイルを読み込んでいる。

パッケージとクラスの変更

パッケージ構成

クラス構成は特に変わらず、パッケージ名とエイリアスを本バージョンにあったものとする。以下のバージョンでも同じ。

Creatureのクラスプロパティ

このバージョンから、速度の最大値をControlerからCreatureのクラスプロパティに変更(6行目)。

また、壁の接近を認識する距離(_detectionLength)と回避加速度計算時のパラメータ(_repulsionParam)を定義。

Creature.move

認識距離以内に壁に近づき始めると、壁からの斥力を想定した加速度を計算し、速度を変更。

加速度は重力加速度をイメージし、距離の2乗に反比例させた。

boids11_wall_avoidance

そもそもピクセル単位の計算では最小でも距離の値が”1″となるため、重力モデルでは大きな加速度が出ない。ここでは_detectionLengthを長さの基準としたが、壁との距離に応じて自然に避けるような運動をさせるためにパラメータ(_repulsionParam)を導入しなければならなかった。

なお、速度ベクトルの値のキャップを判定する際に速度成分の符号を用いているが、Math.sign()はほとんどのブラウザで使えないため、「値/絶対値」で符号を得ている。

Controlerクラス

vMaxの変更のみ。

Boids 1.2

このバージョンで、以下の点を変更している。

  1. 座標単位のプロパティ定義・計算を、独自クラスgeom2d.Vectorで書き換え
  2.  描画サイズなど各種パラメータをHTMLで設定できるようにする
    • 各種パラメータをstaticなクラス変数とする
    • HTMLでグローバルな変数としてパラメータ群を設定
    • 実行時にControlerオブジェクトのセッターでパラメータ群を設定
  3. Creatureオブジェクトの形状を自由に設定可能にする

HTML

独自クラスパッケージファイルの読み込み

本体のスクリプトファイルに先立って、独自クラスのパッケージファイル(taustation_geom2d.js)を読み込ませている。

パラメータ群の設定

HTMLのscript要素でパラメータ用のグローバル変数を定義する。これらはその後に読み込まれたスクリプトで利用される。

script要素内の変数定義はJavascriptで書くため、行末にコロン(;)をつけている。

script要素をWordPressのテキストモードで書くと、ビジュアルモードを経由したときに//<![CDATA[~改行~//]]>が挿入される。

また、Javascriptをscript要素に直接書くと、改行が除かれて一行になってしまう。

パッケージの準備とクラスの変更

Vectorクラスの利用

独自クラスgeom2d.Vectorを使って、位置・速度・加速度のコーディングを見やすくした。

各オブジェクトの生成と計算時にVectorオブジェクトを生成するnew演算子が介在するが、400個体程度の計算でもパフォーマンスの問題は見られなかった。

個体の形

これまではdraw()メソッドの中で直接円を描いていたが、今回はヘルパーメソッドdrawShape()を実装。

パラメータ設定

HTML内のスクリプト要素で定義されたグローバル変数を参照し、パラメータとしてクラス変数に格納。

この操作はControlerクラスに集約した。

変更に関係する箇所

Creatureクラスのクラス変数

@var: valの形式でクラス変数として定義。

Creatureの基本メソッド

これまでx, y, vx, vyのように個別の座標値で扱っていたプロパティを、Vectorクラスで置き換える。

 Creature.draw()

単純な円ではなく、方向を持った細長い三角形を描くように変更。

下図のように、基準点(x, y)から速度ベクトルの方向に頂点を、速度ベクトルと直角な報告に底辺を描く。ここで0 < p < 1で、これによって三角形の細長さが決まる。

boids12_shape1

ここでs_x = s(v_x / v) , \: s_y = s(v_y /v)と置くと下図のようになる。

boids12_shape3

コードは以下の通り。

Creature.move()

Vectorオブジェクトの導入に対応して書き直した。

斥力加速度計算のパラメータ(Creature._wallRepulsionParam)は()の外に出した。

Clusterクラス

変更箇所はない。

Controlerクラスのセッター

以下のメソッド群で整理。Creatureのクラス変数をセットしている。

実行部分

Controlerオブジェクトのセッター群を呼び出している。

 

CoffeeScript – Boids 1.x – 準備

Boids構築の準備

ここでは、以下のバージョンに沿って、Boidsの準備段階のコードを組み立てていく。

  1. Boids 0.5~ブラウザ上で指定した数の個体を表示させる
  2. Boids 1.0~個体を運動させる
  3. Boids 1.1~各個体が壁との衝突を避けるようにする
  4. Boids 1.2~個体の形をそれらしくする(内部的には独自クラスを導入)

Boids 0.5~個体の発生と表示

概要

まずスタートアップとして、指定された数の個体を発生・表示させるという簡単な枠組みを作る。

仕様は以下の通り。

  • numberボックスで個体数を指定
  • “GENERATE”ボタンを押すとcanvasに指定した数の個体が表示される
    • 個体の位置はその都度ランダムに設定される

デモンストレーション




コード詳細

Boids 0.5のコード説明へ

Boids 1.0~個体を動かす

概要

発生させた個体を表示させると同時に運動させる。

仕様は以下の通り

  • Numberボックスで個体数を指定
  • GENERATEボタンを押すとcanvasに指定した数の個体が表示される
    • 個体の位置はランダム
  • START/STOPボタンを押すたびに、各個体の運動と停止が切り替わる
    • 個体のスピードは一定の範囲内でランダムに設定され、スピードは変化しない
    • 壁に当たった場合は全反射する

デモンストレーション


 

コード詳細

Boids 1.0のコード説明へ

Boids 1.1~壁を避ける

概要

各個体が壁をよける動作を導入。壁からの距離に応じた斥力を想定し、それに応じた加速度を計算している。

操作方法はこれまでのものと同じ。

デモンストレーション


 

コード詳細

Boids 1.1のコード説明へ

Boids 1.2~Vectorの利用と個体の形

概要

このバージョンでは2つのことを導入している。

  • 一つは独自クラスのgeom2d.Vectorを利用していること
  • 今一つは個体の形を単純な円から任意の形とできるよう変更したこと

操作方法はこれまでのものと同じ。

デモンストレーション


 

コード詳細

Boids 1.2のコード説明へ






CoffeeScript – Boids

Boidsとは

Boidsは鳥や魚が群をなして移動する様をシミュレートするもので、概要はこちらにまとめている

一つ一つの個体は、一定の行動規範に従って「自律的に」動いていながら、全体が群として整然と運動することを再現する。

CoffeeScriptによるBoidsの開発

以下のステップで開発を進める。

  1. Boids 1.xのシリーズで、個体の生成・表示、運動、壁の回避などを実装
  2. Boids 2.xのシリーズで、最もシンプルな運動ルールを個体に与える
  3. Boids 3.xのシリーズで、「敵」を導入する
  4. アプリケーション版

 

スクリプトへの引数渡し

たとえば以下のような場合。

  • CoffeeScript、Javascriptの外部スクリプトに引数を渡したい
  • 外部スクリプトの定数定義を柔軟に変更可能なようにしたい

定数となる変数定義をスクリプト内に書くと、定数の値を変更したいときに再コンパイルやアップロードなどが必要になって煩雑。

以下の方法が考えられる。

  • HTMLの外部スクリプト呼び出しより前に、変数定義のscript要素を書く(変数のスコープはグローバルになる)
    • その際、行の末尾にセミコロン(;)をつけること
  • 外部スクリプト内で上で定義した変数を利用する

HTML

外部スクリプト

CoffeeScriptも実行時にはJSにコンパイルしたものを読み込むので、変数定義もJavascriptの文法で末尾にセミコロン(;)をつけなければならない。

上の例では、定数を意識して変数名を大文字のスネークケースとしたが、通常の変数名でも実行に問題はない。

 

CoffeeScript – geom2dパッケージ

パッケージ名

taustation_geom2d

クラス

taustation_geom2d.Vector
2次元ベクトルを保持し、各種演算を行うメソッドを提供する。
taustation_geom2d.MovingAgent
位置と速度を保持し、互いの位置関係を判定するメソッドを提供する。

コードの骨組み

 

CoffeeScript – geom2d.Vectorクラス

パッケージ

taustation_geom2d

クラス名

taustation_geom2d.Vector

クラス仕様

概要

x、y二つの成分を持ち、絶対値の計算や加減乗算など2次元ベクトルの代数演算を行うメソッドを提供する。

クラス変数

なし

クラス・メソッド

distance(pos1, pos2)
2つのVectorオブジェクトpos1、pos2を点を表す位置ベクトルとして、2点間の距離を返す。

インスタンス・プロパティ

x
ベクトルのx成分
y
ベクトルのy成分

コンストラクタ

constructor(x, y)
x成分とY成分を指定してVectorのインスタンスを生成する。

インスタンス・メソッド

基本メソッド

set(x, y)
Vectorのx成分とy成分をセットする。
toString()
Vectorの文字列形式の表現を返す。
getClone()
元のVectorオブジェクトと同じ内容のクローンを生成して返す。

演算

abs
Vectorの絶対値(長さ)を返す。
times(coeff)
Vectorに定数coeffを乗じたベクトルを新たに生成して返す。
timesEq(coeff)
Vectorに定数coeffを乗じて変更する。新しいオブジェクトは生成しない。
div(coeff)
Vectorを定数coeffで除したベクトルを新たに生成して返す。
divEq(coeff)
Vectorを定数coeffで除して変更する。新しいオブジェクトは生成しない。
plus(other)
Vectorにotherベクトルを加えたベクトルを新たに生成して返す。
plusEq(other)
Vectorにotherベクトルを加えて変更する。新しいオブジェクトは生成しない。
minus(other)
Vectorからotherベクトルを減じたベクトルを新たに生成して返す。
minusEq(other)
Vectorからotherベクトルを減じて変更する。新しいオブジェクトは生成しない。
inprod(other)
Vectorとotherベクトルの内積値を返す。
ang(other)
Vectorとotherのなす角を計算する(0~π)。

新たなVectorの生成

getUnit()
Vectorと同じ向きの単位ベクトル(長さが1)を新たに生成して返す。
getInverse()
Vectorと逆向きのベクトルを新たに生成して返す。
getOrthogonalR()
Vectorから右に90度回転したベクトルを新たに生成して返す。
getOrthogonalL()
Vectorから左に90度回転したベクトルを新たに生成して返す。
getUnitOrthogonalR()
Vectorから右に90度回転した単位ベクトルを新たに生成して返す。
getUnitOrthogonalL()
Vectorから左に90度回転した単位ベクトルを新たに生成して返す。

判定

isHeadingToRightOf(other)
このVectorオブジェクトの進行方向が、引数のVectorオブジェクトotherの進行方向より右方を指しているときtrue、左方を指しているときfalseを返す。
isHeadingToLeftOf(other)
isHeadingToRightOf()と左右逆の判定結果を返す
isInFrontOf(movingAgent)
このVectorオブジェクトが位置ベクトルとして、その点が引数のMovingAgentオブジェクトの前方(左右180度より進行方向の側)にあるときtrue、後方にあるときfalseを返す。真横の時は前方と判定される。
isIntheRearOf(movingAgent)
isInFrontOf()と前後逆の判定結果を返す。
isOnTheRightOf(movingAgent)
このVectorオブジェクトが位置ベクトルとして、その点が引数のMovingAgentオブジェクトの右方にあるときtrue、左方にあるときfalseを返す。進行方向の延長線上にあるときは右方と判定される。
isOnTheLeftOf(movingAgent)
isOnTheRightOf()と左右逆の判定結果を返す。

コード

 

CoffeeScript – グローバル変数

グローバルにならない

CoffeeScriptでグローバル変数を期待して以下のように書いたとする。

一見すると問題なく動いているように見えるが、これを別ファイルのパッケージにして動かそうとすると問題が顕在化する。以下のように”globalVarが存在しないよ”というエラーが出るのである。

これら2つのファイルをjsにコンパイルしてブラウザのscript要素で読み込んだ場合、そのイメージは以下のようになる。

パッケージでグローバル定義したつもりだが、コンパイル時に無名関数でクロージングされるため、グローバルにならず、他のファイルから読み込むことができない。

解決策1

グローバル変数をwindowオブジェクトの要素にしてしまう。

解決策2

rootコンテキストで、以下のパターンを使う。