提供:Japanese Scratch-Wiki
ベクトルは、大きさだけでなく向きをもつ量であり (これに対し、大きさだけで向きをもたない量をスカラーと言う)、様々なものを表すのに使用される。物理シミュレーションやゲームなどでは、多くの場合、ベクトルが使われる。この記事では、Scratchでベクトルを使って、物理的な動きをシミュレーションする基礎を説明する。
ベクトルとは何か
ベクトルでは、リストのように複数の数値 (要素) をひとまとめにして扱う (ただし、リストと違って途中で項目を増やしたり減らしたりはできない)。この記事では、主に要素を2つ持つ2次元ベクトルについて取り上げるが、3次元、4次元といったベクトル (要素数を3、4のベクトル) も存在する。たとえば、レイトレーシングを行うには、3次元ベクトルが必須である。 ベクトルは、大きさと向きをもつ量であり、視覚的に表現するときは、矢印を使って表す。
2次元ベクトルは、デカルト平面 (いわゆるxy平面) 上のx軸方向の要素とy軸方向の要素で構成された点として表せる。したがって、Scratchにおけるスプライトの場所は、ベクトルで表現できる。
ベクトルは、位置、速度、力など、さまざまなものをグラフィックで表現するときにも使用される。たとえば、ベクトルを使えば、物体同士の衝突のような複雑な現象のシミュレーションを行うことができる。
表記
ここでは、次の表記を使うものとする。
- (x, y) は、x要素とy要素を持つベクトルを表す。
- a.x と a.y は、ベクトルaのx要素とベクトルaのy要素を指すものとする。
- a + b、a - b、a * b、a / b は、aとbに対する演算を表す。
- a • b はドット積 (内積) を表す。
- a × b はクロス積 (外積) を表す。
- a! はベクトルaの単位ベクトルを表す。
- |a| はベクトルaの大きさを表す。
ベクトル演算
自然数に適用できる標準的な演算の多くは、そのままベクトルにも適用できる。ベクトルを加算するときは、2つのベクトルの対応する要素どうしを単純にたせばよい。
(1, 2) + (3, 4) = (4, 6)
イメージとしては、1つめのベクトルの先頭に、2つめのベクトルを付け足していると考えてほしい。
ベクトルの減算も加算同様である。対応する要素どうしを引けばよい。
(5, 4) - (3, 2) = (2, 2)
乗算については、まずは、ベクトルとスカラーのかけ算を考える。この場合、1つのスカラー値をベクトルの各要素にかけたものが結果になる (結果もベクトルになる)。
5 * (2, 3) = (10, 6)
除算においては、ベクトルをスカラーでわることはできるが、スカラーをベクトルでわることはできない:
- (15, 25) / 5 = (3, 5)
- 4 / (16, 24) = NaN
ベクトルの大きさは、ピタゴラスの定理を使って計算できる。
|a| = √[(a.x)2+(a.y)2]
N次元のベクトルの向きは、n-1個の角度で定義される。したがって、2次元ベクトルの場合は、向きとして角度を1つだけ持つ。
その他、よく使われるのが「単位ベクトル」である。あるベクトルに対する単位ベクトルとは、向きが同じで、ベクトルの大きさ (長さ) が1のもののことである。これを求めるときは、ベクトルの各要素をベクトルの大きさで割ればよい。
v! = (v.x/|v|, v.y/|v|).
ドット積とクロス積は、2つのベクトルをかけあわせるときに使われる代表的な手法である。
- 2つのベクターのドット積 (内積) a • b は、次の式で定義される (この2つの式は同じ値を返す)
- a • b = (a.x * b.x) + (a.y * b.y) :一般化すると、ドット積は、2つのベクトルの対応する要素どうしの積を合計したものと言える。
- a • b = |a|*|b|*cos(θ).θ (シータ) は2つのベクトルからなる角度を指す。
- 2つのベクトルのクロス積a × bは、3次元と7次元空間でのみ定義されており、結果としてベクトルを返す。クロス積では交換法則は成立しないため、 a × b ≠ b × a である。
それでは、 a × b = c の計算方法を見てみよう。
- 3次元クロス積は、次の式で定義される。
- c = |a|*|b|*sin(θ)*n。 θ は、2つのベクトルからなる角度、n はベクトルaとbに直交する単位ベクトルである
- ベクトルcの個々の要素は、次の3つの式で定義されている。
- c.x = (a.y * b.z) - (a.z * b.y)
- c.y = (a.z * b.x) - (a.x * b.z)
- c.z = (a.x * b.y) - (a.y * b.x)
スクリプト例
Scratchでベクトルを表すため、ここでは2つの 変数 <ベクトル名>.x と <ベクトル名>.yをペアにして使う。こうしておけば、各要素に対する演算をもう一方と切り離して行えるからだ。
まず、変数「位置.x」と「位置.y」を作成して、スプライトが常に位置ベクトルが示す座標 (位置.x, 位置.y) に移動するスクリプトを作る (これらの変数をステージモニターでスライダー表示しておけば、自由に変数の値 (ベクトルの要素) を変更して動作を確認できるので便利だ )。
@greenFlag が押されたとき::events hat ずっと x座標を (位置.x) にする y座標を (位置.y) にする
次に、新たなベクトル「速度」(「速度.x」「(速度.y」の2つの変数で構成) を作って、位置ベクトルの2つの要素を速度ベクトルの対応する要素で変更するスクリプトを追加する。この状態で、速度ベクトルの値を上手にコントロールすると、スプライトをスムーズに動かすことができる。
@greenFlag が押されたとき::events hat ずっと [位置.x v] を (速度.x) ずつ変える [位置.y v] を (速度.y) ずつ変える x座標を (位置.x) にする y座標を (位置.y) にする
最後に、速度ベクトルに手を加えて、重力による効果を追加してみよう。
@greenFlag が押されたとき::events hat [位置.x v] を (0) にする [位置.y v] を (0) にする [速度.x v] を (10) にする [速度.y v] を (10) にする ずっと [速度.y v] を (-1) ずつ変える [位置.x v] を (速度.x) ずつ変える [位置.y v] を (速度.y) ずつ変える x座標を (位置.x) にする y座標を (位置.y) にする
よくある応用例:はねかえり表現
ベクトルが使われる場面としてよくあるのは、デコボコした壁に物体がはねかえる様子のシミュレーションである。物体がはねかえるスクリプトを作るときは、壁の表面に対して直交するベクトルを計算し、これに対し、物体の速度ベクトルの各要素の射影を求めれば良い。
2次元平面で直行するベクトルを求めるには、x要素とy要素を入れ替えて、どちらかの符号を反転すればよい。射影を調べるのはもう少し複雑で、ドット積 (a • b)を使う。