2017年4月30日日曜日

2次元の外積と内積

 2次元でも外積とか言うのか知らないけど。


 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 件のコメント:

コメントを投稿