HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う

第21回 水平に回す立方体の面を塗る

この記事を読むのに必要な時間:およそ 3 分

前回の第20回立方体のワイヤーフレームを水平に回すでつくった立方体の四方の面を塗りたい。ただしその場合は,面をどの順序で塗るか,考えておかなければならない。そうしないと,面の重ね順が崩れる図1)。今回は,「ベクトルの外積」を使って解決することにしよう。

図1 順序を考えずに塗ると面の重ね順が崩れる

図1 順序を考えずに塗ると面の重ね順が崩れる 図1 順序を考えずに塗ると面の重ね順が崩れる

面の塗り順をどう扱うか

3次元空間でオブジェクトを描く順序については,第19回3次元空間で弾むオブジェクトとz座標による重ね順の並べ替えで学んだ。このときは,Array.sort()メソッドにより,「オブジェクトの重なりをz座標値の順に並べ替えることにしたのだった。今回も,配列の並べ替えで塗り順を決める手は使える。だが,Array.sort()メソッドの処理の負荷は決して軽くない。第19回※1をつぎに改めて引用した。この動画を見れば,JavaScriptの手間もうかがい知れよう。

第19回※1

並べ替えの仕方には,さまざまなロジックがある。いずれにしても,順に取出すふたつの値から並び方を決める。クイックソートを表すつぎの映像からイメージがつかめるかもしれない。

実は,今回扱う立方体は,閉じた凸の多面体という扱いやすいかたちだ。まず,面の裏側は外から決して見えない。つまり,裏返った面は描かなければ済む。つぎに,表向きの面は,互いに重なることはない。したがって,表の面を描く順序は考えなくて構わないのだ。

閉じた凸の多面体
  • 面の裏は決して見えない
  • 表向きの面は重ならない

2次元ベクトルの外積で面の裏表を調べる

そこで,面の裏表をどうやって調べるかだ。ベクトルには「外積」という計算がある。この外積をうまくつかえば,面が裏か表か,たやすくわかる。外積は,3次元ベクトルで用いられることが多い。けれども,今回は透視投影した後の2次元平面のベクトルで考える。

ベクトルは大きさと向きをもつ。けれど,どこを始点とするかは問わない。つまり,始点が違っても,向きが等しく平行で,長さの等しいベクトルは,互いに等しい図2左)。そして,始点を原点に揃えると,ベクトルは終点の座標のみで表せる図2右)。原点を始点とするベクトルは位置ベクトルという。

図2 等しいベクトルと位置ベクトル

図2左 等しいベクトルと位置ベクトル 図2右 等しいベクトルと位置ベクトル

2次元平面の位置ベクトルA(ax, ay)とB(bx, by)の外積はA×Bで表し※1),つぎの簡単な四則演算の式で定められる。この式の数学的な意味については,興味をもたれた読者向けに後で解説する。計算そのものは,ただの掛け算と引き算だ。

2次元ベクトルA(ax, ay)とB(bx, by)の外積
A×B =axby - aybx

ここで覚えていただきたいのは,上記の外積の式はふたつの項の引き算なので,A×BとB×Aは正負が逆になるということだ。つまり,外積には交換法則が成立たない。外積A×Bについて幾何学的に説明すると,ベクトルBがAに対して右ネジの位置にあると正,左ネジの位置にあれば負になる図3)。

図3 2次元ベクトルの外積の正負は位置が右ネジか左ネジかで決まる

図3左 2次元ベクトルの外積の正負は位置が右ネジか左ネジかで決まる 図3右 2次元ベクトルの外積の正負は位置が右ネジか左ネジかで決まる

では,2次元ベクトルの外積で面の裏表を確かめよう。あらかじめ表向きの面の3頂点からふたつのベクトルを定め,位置関係を(たとえば右ネジに)決めておく図4)。すると,面がどう回転しようが,表向きであるかぎり,ふたつのベクトルの間の位置は(右ネジのまま)変わらない。

図4 3頂点から定めたふたつのベクトルの位置関係を予め決める

図4 3頂点から定めたふたつのベクトルの位置関係を予め決める

実はこのために,前回立方体の4面の頂点座標はすべて,つぎのようにそれぞれの面ごとに時計回りのインデックスを与えておいた第20回図3再掲)。したがって,各面の第1頂点から第2頂点へのベクトルと第1頂点から第3頂点へのベクトルの位置は,みな右ネジに揃う。

function getFacesVertices() {
  var vertices = [
    new Face(0, 1, 2, 3),
    new Face(1, 5, 6, 2),
    new Face(4, 0, 3, 7),
    new Face(5, 4, 7, 6)
  ];
  return vertices;
}

図3 立方体の8頂点にインデックスを与える(再掲)

図3 立方体の8頂点にインデックスを与える(再掲)

表向きの面のふたつのベクトルの位置関係を右ネジに定めれば,外積が正なら表のままで,負になったら裏返ったことがわかる図5)。そして,立方体の面のうち,ふたつのベクトルの外積が正の場合だけ描けば,それですべて丸く治まる。

図5 外積の正負から面の向きを調べて裏返った面は描かない

図5左 外積の正負から面の向きを調べて裏返った面は描かない 図5右 外積の正負から面の向きを調べて裏返った面は描かない

※1
ベクトルの外積は乗算ではない。そこで,掛け算と区別するため,記号「×」「クロス」(cross)と読む。

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入