シンタックス
public function crossProduct(secondVector:Vector3D):Vector3D
引数
secondVector:Vector3D ― 外積を計算するためのもうひとつのベクトルとなるVector3Dインスタンス。
戻り値
Vector3D ― 外積として計算されたベクトルを示す新たなVector3Dインスタンス[*1]。ふたつのベクトル、つまり参照したVector3Dインスタンスとメソッドの引数に渡したもうひとつのVector3Dインスタンスとが互いに平行な場合、外積としてVector3Dインスタンス(0, 0, 0)が返ります[*2]。
説明
参照したVector3Dインスタンスと引数のVector3Dインスタンスとの外積を計算して、その結果となる新たなVector3Dインスタンスを返します。外積はクロス積(cross product)とも呼ばれます。ふたつのVector3DインスタンスmyVectorとsecondVectorの外積crossProductは、Vector3D.crossProduct()メソッドをつぎのように呼出して求めます。
var crossProduct:Vector3D = myVector.crossProduct(secondVector)
|
外積とは、次表001のようなベクトルです(図001)。
表001■外積で求められるベクトル
外積の要素
|
外積のベクトルとふたつのベクトルの関係
|
角度
|
ふたつのベクトルmyVectorとsecondVectorを含む平面に垂直です。つまり、ベクトルcrossProductは、ベクトルmyVectorとsecondVectorのどちらとも直角を成します(図001左図)。
|
方向
|
ベクトルmyVectorからsecondVectorに向かう回転を考えたとき、その回し方で右ネジの進む方向がベクトルcrossProductの向きになります(図001左図)。
|
大きさ
|
ベクトルmyVectorからsecondVectorを平行四辺形の隣り合う2辺としたとき、ベクトルcrossProductの大きさはこの平行四辺形の面積と等しくなります(図001右図)。
|
図001■ベクトルの外積
ベクトルの内積(ドット積)は、Vector3D.dotProduct()メソッドで求められます。ふたつのベクトルが互いに直角を成す(前掲表001の「角度」の項参照)とき、その内積は0です。したがって、外積として求められたベクトルともとのふたつのベクトルとの内積は、いずれも0となります。
var dotProduct0:Number = crossProduct.dotProduct(myVector);
var dotProduct1:Number = crossProduct.dotProduct(secondVector);
trace(dotProduct0, dotProduct1); // 出力: 0 0
|
前掲図001の右の図で、平行四辺形の高さは|secondVector|×sinθで表されます。ふたつのベクトルが成す角度θは、静的メソッドVector3D.angleBetween()で調べられます。そして、絶対値で表されるベクトルの大きさは、Vector3D.lengthプロパティの値です。したがって、平行四辺形の面積つまり外積の大きさ(前掲表001の「大きさ」の項参照)は、以下の計算で求めることもできます。ただし、外積として得られたベクトルの大きさとは、実際にはわずかな誤差が生じることもあります。
var theta:Number = Vector3D.angleBetween(myVector,secondVector);
var area:Number = myVector.length * secondVector.length * Math.sin(theta);
trace(crossProduct.length, area); // ふたつの値にはわずかな誤差が生じることもある
|
3次元座標空間で外積を使う場合としては、平面の向きを調べることが考えられます。三角形ポリゴンの3頂点のうちの2点を結ぶふたつのベクトルから外積を求めれば、その外積の方向を面の向きと定義できるからです[*3][*4]。
[*1] [ヘルプ]には記載がないものの、戻り値のVector3Dインスタンスには、Vector3D.wプロパティの値として1が設定されるようです。
[*2] [ヘルプ]の[Vector3D]の「crossProduct()メソッド」の項には、「返されたVector3Dオブジェクトの座標が(0, 0, 0)の場合、2つのVector3Dオブジェクトは互いに垂直です」と説明されています。しかし、「垂直」ではなく「平行」の誤りです。
[*3] 厳密には、三角形の3頂点からふたつのベクトルを決める方法が予め定められていないと、右ネジの回転方向は一定せず、外積の角度が正しくても、向きは正反対に定義されてしまうおそれがあります。
[*4] [ヘルプ]の[Vector3D]の「crossProduct()メソッド」の項の以下の説明は、本文に述べた面の向きについての記述と思われます。
カメラまたは視点の正規化されたベクトルを持つ多角形表面の 2 つの頂点の正規化されたクロス積を使用して、ドット積を取得できます。ドット積の値により、3 次元オブジェクトの表面が視点から隠れているかどうかを識別できます。
しかし、英文の翻訳で意味を取違えているようです。おそらく、前段の文は以下のように訳すのが正しいでしょう。
ポリゴン面の2頂点(ベクトル)のクロス積(外積)を正規化し、それとカメラまたは視点の正規化されたベクトルとを使って、(2つの正規化べクトルの)ドット積(内積)が求められます。
内積の値により、ふたつのベクトルが直交するかどうかを調べることができます。ふたつのベクトルが直角を成すとき、内積は0になります。また、内積の値が正であれば鋭角、負の場合は鈍角を成します。
ふたつのベクトルのドット積(内積)と角度については、後述注釈[*7]をお読みください。なお、ActionScript 3.0では、ドット積(内積)を計算しなくても、前述のとおり、Vector3D.angleBetween()メソッドを使って直ちにふたつのベクトルの成す角度が求められます。
|
数学解説[*5]
ふたつのベクトルをAとBとすると、その外積はつぎのように表されます。
A×B
外積は前掲表001で表されるベクトルです。外積の大きさ|A×B|は、AとBの成す角をθとすると、つぎの式で与えられます。
|A×B| = |A||B|sinθ
他方、内積はA・Bで表され、つぎの式で定義されます。
A・B = |A||B|cosθ
外積がベクトルであるのに対して、内積は大きさのみの値(スカラー)であることにご注意ください[*6]。
sinθは角度θが0のとき0となり、cosθは角度がπ/2(90度)のとき0になります。したがって、ベクトルAとBは互いに、外積の大きさが0のとき平行、内積が0のときに垂直となります。
3次元空間のベクトルAとBを、それぞれ(ax, ay, az)および(bx, by, bz)とすると、外積と内積はつぎの式で求められます[*7]。
A×B = (aybz - azby, azbx - axbz, axby - aybx)
A・B = axbx + ayby + azbz
[*5] ベクトルやその外積および内積については、つぎのサイトが参考になります。平面幾何におけるベクトル演算「内積と外積」、基礎の基礎編その1「内積と外積の使い方」、「外積」、高校の数学「ベクトル」、「ベクトル其の参」。
[*6] ベクトルには、行列と異なり、ベクトル同士の乗算は定義されていません。なお、演算を表す記号として外積が「×」内積は「・」を使うために、前者を「クロス積」(cross product)、後者を「ドット積」(dot product)と呼ぶことがあります。
[*7] この座標(成分)値から求めた内積を使って、ふたつのベクトルの成す角が求められます。前述の内積の定義より、以下のようにcosθが導けます。すると、逆三角関数cos-1により角度θが得られるからです。
A・B = |A||B|cosθ
cosθ = A・B/(|A||B|)
θ = cos-1(A・B/(|A||B|))
とくにふたつのベクトルの大きさがともに1の場合には、角度θは以下の式で求められます。なお、ベクトルの方向は変えず、大きさを1にすることは、ベクトルの「正規化」と呼ばれます。
θ = cos-1(A・B)
|
例
外積を用いたスクリプトの例としては、以下をご参照ください。
- F-site「3次元回転の軸をベクトルの外積で求める」
- 「3次元空間における面の向きを調べる」
- 「2次元平面で座標が三角形の内側にあるかを調べる」
- 「インスタンスをドラッグで回して動かす」
Player
ActionScript 3.0/Flash Player 10/AIR 1.5以降。
参考
[ActionScript 3.0言語およびコンポーネントリファレンス] > [Vector3D] > [crossProduct()メソッド]
[Flash CS4 Professional ActionScript 3.0 Language Reference] > [Vector3D] > [crossProduct() method]
作成者: 野中文雄
更新日: 2011年1月22日 「例」を追加。
更新日: 2009年5月7日 注釈[*1]を追加。
作成日: 2009年4月14日