2次元で3個の頂点を決めて三角形を作った場合の外積と内積のサンプル。乱数で頂点を生成してるので見苦しいのはご容赦を。
おおよその考え方として、内積(ドット積)は2本の線がどれくらい開いているか(閉じているか)を示している。原点を基準として、2本の線が同じ方向に伸びていれば+1となり、逆方向に伸びていれば-1となる(ただし正規化(2本のベクトルの長さの積で割る)をしない場合はややこしい数字になる)。同じ方向で+1、逆方向で-1なので、acosに入れれば同じ方向で0、逆方向で180となり、どれくらい線が開いているかという値になる。
外積(クロス積)は、基本的に3次元で使われて、頂点で示される面の向きを計算するのに使うのだが、2次元に当てはめると面がどっちを向いているかが得られる。他に、面の面積も得られるのだが。
今回の計算方法では、頂点が時計回りなら外積は正の値、頂点が左回りなら外積は負の値、という風になっている。
最近になって、いろいろ数字をいじくり回す必要に迫られて、いろいろ苦労してるので、ちゃんと勉強しておけばよかったなぁとか思ったり。いや、お前の場合はそれ以前だろ、というツッコミはさておき。
static double Cross(Vector2 vertex1, Vector2 vertex2, Vector2 vertex3)
{
double x2 = vertex2.X - vertex1.X;
double y2 = vertex2.Y - vertex1.Y;
double x3 = vertex3.X - vertex1.X;
double y3 = vertex3.Y - vertex1.Y;
double result = x2 * y3 - y2 * x3;
return (result);
}
static double Dot(Vector2 vertex1, Vector2 vertex2, Vector2 vertex3)
{
double x2 = vertex2.X - vertex1.X;
double y2 = vertex2.Y - vertex1.Y;
double x3 = vertex3.X - vertex1.X;
double y3 = vertex3.Y - vertex1.Y;
double result = x2 * x3 + y2 * y3;
result /= Math.Sqrt(x2 * x2 + y2 * y2) * Math.Sqrt(x3 * x3 + y3 * y3);
// -1 - +1に正規化した内積をAcosに入れると0 - πの角度になる
// 0 - πラジアンを度に直すと0 - 180の値を取る
// result = Math.Acos(result) * 180 / Math.PI;
return (result);
}

0 件のコメント:
コメントを投稿