Location : Home > Languages > Perl > Package
Title : Math::VectorReal
Toolbox Logo

名称

 Math::VectorReal - 3次元ベクトル計算


概要

#!/usr/bin/perl
use Math::VectorReal;

$a = vector( 1, 2, .5 );
print "Vector as string (MatrixReal default format)\n\$a => ", $a;

print  $a->stringify("Formated Output   \$a => { %g, %g, %g }\n");

# デフォルトの出力で新しい行にするのは大嫌いだ(が MatrixRealで定義されている)
$Math::VectorReal::FORMAT = "[ %.5f %.5f %.5f ]";
print "Modified default output format   \$a => $a\n";

print 'length     => ', $a->length, "\n";
print 'normalised => ', $a->norm, "\n";

use Math::VectorReal qw(:all);  # Include O X Y Z axis constant vectors
print 'string concat   $a."**" = ', $a."**", "\n";
print 'vector constant    X    = ',   X,    "\n";
print 'subtraction     $a - Z  = ', $a - Z, "\n";
print 'scalar divide   $a / 3  = ', $a / 3, "\n";
print 'dot product     $a . Y  = ', $a . Y, "\n";
print 'cross product   $a x Y  = ', $a x Y, "\n";

print "Plane containing points X, \$a, Z (in anti-clockwise order)\n";
($n,$d) = plane( X, $a, Z ); # return normal and disance from O
print '      normal      =    $n     = ', $n, "\n";
print '  disance from O  =    $d     = ', $d, "\n";
print ' Y axis intersect = $d/($n.Y) = ', $d/($n.Y), "\n";

print "VectorReal and MatrixReal interaction\n\n";
use Math::MatrixReal;  # Not required for pure vector math as above

$r = $a->vector2matrix_row;  # convert to MatrixReal Row Vector
$c = $a->vector2matrix_col;  # convert to MatrixReal Column Vector
print 'Vector as a MatrixReal Row $r (vector -> matrix) => ', "\n", $r;
print 'Vector as a MatrixReal Col $c (vector -> matrix) => ', "\n", $c;

$nx = $a->norm;   $ny = $nx x Z;  $nz = $nx x $ny; # orthogonal vectors
$R = vector_matrix( $nx, $ny, $nz );   # make the rotation matrix
print 'Rotation Matrix from 3 Vectors   $R   => ',"\n", $R, "\n";

print "Extract the Y row from the matrix as a VectorReal..\n";
print '$R->matrix_row2vector(1) => ', $R->matrix_row2vector(1), "\n";

print "Rotate a vector with above rotation matrix\n";
print '$a * $R (vector -> vector)',"\n", $a * $R, "\n";

print "Rotate a MatrixReal column (post multiply)...\n";
print "(NB: matrix must be transposed (~) to match column format)\n";
print '~$R * $c (col_matrix -> col_matrix) =>',"\n", ~$R * $c, "\n";

説明

 Math::VectorReal パッケージは3次元ベクトルを過去の CPAN モジュール Math::MatrixReal と互換を保ちながら定義する。MatrixReal パッケージに比べ、多くのベクトル向け関数やオーバーロード演算子などを提供している。たとえば通常の Perl の文字列関数 "x" 及び "." はベクトルの外積および内積としてオーバーロードされる。本パッケージではベクトル演算式は数学での式に似せて作成している。

 本パッケージは Math::MatrixReal と互換ではあるけれども、純粋なベクトル向け安全のためいこのパッケージを用いる必要はない。それはベクトルを用いて行列演算を行いたいときに必要になる。本パッケージのインタフェースは柔軟に作成されている。

 ベクトルは、ベクトル演算における列定義を選択する代わりに Math::MatrixReal における行と同様に定義することもできる。そのようなベクトルは行列に左から乗じることができる。例: v * M -> 'v

 これはベクトルを処理する方法として気に入っているだけでなく、ほとんどのグラフィックの本でベクトルを扱う際に用いられている方法である。特典としては、本パッケージと Math::MatrixReal との間でオーバーロードのコンフリクトが起こらないことである(左のオブジェクトのオーバーロード演算子は計算を行うために呼び出される)。これは3次元幾何処理用に設計されている MatrixReal の列ベクトルメソッドよりもかなり単純である。

 vector_matrix() 関数は3つの(通常はそれぞれ直交している)ベクトルからの MatrixReal オブジェクトを生成を簡略化する。これは数学演算志向のベクトルが Math::VectorReal オブジェクトからの直交回転行列の生成を容易にしているからである。簡単な例は上記の概要またはソースの matrix_test を見よ。

 Math::MatrixReal 配列オブジェクトの6つ目の要素には必要時に再計算しなくてもよいようにベクトルの長さを保持していることに注意すること。これは贅沢な sqrt() 関数を必要もないのに呼び出さなくてもよいようにである。この使用は Math::MatrixReal 関数のこれらのオブジェクトの直接利用には影響を与えない。


定数

 以下の4つの定数ベクトルがエクスポート可能である。( are available for export (using an ":all" tag). these are

0 = [ 0 0 0 ]   零ベクトルまたは原点
X = [ 1 0 0 ]   |
Y = [ 0 1 0 ]    > 単位軸ベクトル
Z = [ 0 0 1 ]   |

コンストラクタ

new(x,y,z)

 x, y, z を用いて新しいベクトルを生成し、適切なオブジェクトを返す。

vector(x,y,z)

 new と同様であるが、Math::VectorReal オブジェクトを生成するためにパッケージの参照を要求しないエキスポート関数である。

clone()

 参照される Math::VectorReal オブジェクトの完全なコピーを返す。


メソッド

array()

 参照されるベクトルの x, y, z 要素を配列で返す。

x()

 参照されるベクトルの x 要素を返す。

y()

 参照されるベクトルの y 要素を返す。

z()

 参照されるベクトルの z 要素を返す。

stringify( [ FORMAT ] )

 参照されるベクトルを文字列で返す。ベクトルを sprintf フォーマットで指定する場合は FORMAT に指定する。これはすべての VectorReal オブジェクトを文字列化する際にも用いられる。デフォルトではこのフォーマットは Math::MatrixReal オブジェクトに対し [ %#19.12E %#19.12E %#19.12E ]\n を指定することと同じである。これにか改行コードも含まれることに注意すること。
 しかしながら Math::MatrixReal と異なり、パッケージの $FORMAT 変数に新しいデフォルトの sprintf フォーマットを指定することもできる。たとえば

$Math::VectorReal::FORMAT = "{ %g, %g, %g }"

これは POVray(Persistance of Vision Raytracer)プログラムで用いるような出力ベクトルにはよいフォーマットである。

length()

 所与のベクトルの長さを返す。贅沢な sqrt() 関数を利用しなくても済むようにベクトルオブジェクトに長さを格納している。

norm()

 ベクトルを正規化する。すなわち長さが1になるようにベクトルを長さで割ったものである。正規ベクトルはスケールなしで方向を定義する際に用いるか、3次元平面の向きを決める際に用いられる。

plane( v1, v2, v3 )

 所与の3点が反時計回りに存在するように平面を定める。最初の要素が平面の単位法線ベクトルで、2つ目の要素が法線ベクトルに沿った原点からの距離であるような配列を返す。
NOTE: 距離は負でもよいが、その場合は原点が平面より上にあるものとする。

vector_matrix( nx, ny, nz )

 X, Y, Z ベクトルに対し新たな場所を与えられたとき、これらを連結して(行ベクトルとして)Math::MatrixReal 変換行列を生成する。たとえば3つのベクトルが互いに直行していれば行列は X, Y, Z 軸に対して所与のベクトルを回転させる行列を生成する。上記の例を見ること。


ベクトル/行列変換

 以下の関数は provide links between Math::VectorReal パッケージと Math::MatrixReal パッケージの間のリンクを提供する。
 本パッケージは Math::MatrixReal と密接に関係しているけれども、実際に行列演算を行うのでなければそのパッケージがインストールされている必要はないことに注意すること。またオーバーロード関数は自動的にベクトル/行列演算を行う。

ベクトルから行列への変換

vector2matrix_row( [CLASS] )
vector2matrix_col( [CLASS] )

 Math::VectorReal オブジェクトを Math::MatrixReal オブジェクトに変換する。オプションの引数は返されるオブジェクトクラスを定義する。(デフォルトは Math::MatrixReal である)
 Math::VectorReal は内部的には Math::MatrixReal の行ベクトルと同等であり、vector2matrix_row は Math::MatrixReal 関数を用いることを要求しない演算であることに注意すること。vector2matrix_col は Math::VectorReal オブジェクトをベクトルの Math::MatrixReal バージョン(列ベクトル)に転置することを要求する。

行列からベクトルへの変換

matrix_row2vector( [ROW] )
matrix_col2vector( [COLUMN] )

 Math::MatrixReal オブジェクトにより参照されれば、行列からベクトルを抽出する。オプションの引数は Math::VectorReal ベクトルとして取り出すベクトルが行ベクトルか列ベクトルかを指定する。


オーバーロードする演算子

 オーバーロード演算子は文字列変換・加算・減算・乗算・除算・単項マイナス・スカラ乗算・スカラ除算を行う。MatrixReal 乗算を探索し実行するために拡張されたものである。
 しかしながら本パッケージの主な目的は特別なベクトル乗算演算である内積 "." 及び外積 "x" を提供することであった。Perl ではこれらの演算子は通常文字列演算に用いられるものであるが、いずれかの引数が VectorReal オブジェクトであれば、演算は適切なベクトル演算を行う。
 しかしながら . 演算子のどちらか一方が文字列であった場合、ベクトルは文字列化され、文字列の連結が行われることに注意すること。外積演算子 x はベクトルの文字列変換を繰り返すか文字列・ベクトルを繰り返すかのどちらかを croak() するだけである。

 オーバーロードされる演算子は以下の通り。

neg     単項マイナス - ベクトルに -1 を乗じる
 ""     stringify() 関数を用いて文字列に変換する
  +     ベクトル和
  -     ベクトル差
  /     スカラで除する(左の引数はベクトルでなければならない)
  *     スカラを乗じるまたは行列を乗じる
  x     2つのベクトルの外積
  .     2つのベクトルの内積またはベクトル・文字列の連結

 VectorReal を MatrixReal の列ベクトルに転置するために '~' を将来的に追加するかもしれない(MatrixReal オブジェクトに対して)。必要だと思わなかったので追加されなかった。


参考資料

 Steffen Beyer による CPAN モジュール Math::MatrixReal 及び Mike South による CPAN 拡張 Math::MatrixReal-Ext1


著者

 Anthony Thyssen, <anthony@cit.gu.edu.au>


著作権

 Copyright (c) 2001 Anthony Thyssen. All rights reserved.

 本プログラムはフリーソフトウェアであり、Perl 本体と同等の条件で修正/再配布してもよい。いかなる示唆にも感謝する。

Toolbox Logo
Updated : 2007/10/08