ベクトル
vector v0 = set(0, 2, 3);
vector v1 = set(2, 2, -5);
// 正規化
v0 = normalize(v0);
printf('v0:' + sprintf('%g', v0) + '\n');
// v0:{0,0.5547,0.83205}
// 内積
float d = dot(v0, v1);
printf('d:' + sprintf('%g', d) + '\n');
// d:-3.05085
// 外積
vector cross = cross(v0, v1);
printf('cross:' + sprintf('%g', cross) + '\n');
// cross:{-4.4376,1.6641,-1.1094}
行列
行列をつくる
空のマトリックスをつくる
matrix world = ident();
軸からつくる
vector pos = set(2, 4, 1);
vector normal = set(0, 0, 1);
vector up = set(0, 1, 0);
matrix world = maketransform(normal, up, pos);
printf('world:' + sprintf('%g', world) + '\n');
// world:{1,0,0,0 0,1,0,0 0,0,1,0 2,4,1,1}
maketransform関数で行列を作ることが出来る。必要なベクトルはフォワードとアップと座標。
行列からベクトルを抜きだす
// 行列worldからアップベクトルを取得する
vector up = set(world.yx, world.yy, world.yz);
printf('up:' + sprintf('%g', up) + '\n');
// up:{0,1,0}
xx, xy, xz等でアクセスできる。
行列を回転させる
// 行列を回転させる(worldには回転後の値が格納される)
float angle = radians(60);
vector axis = set(0, 1, 0);
rotate(world, angle, axis);
printf('world:' + sprintf('%g', world) + '\n');
// world:{0.5,0,-0.866025,0 0,1,0,0 0.866025,0,0.5,0 1.86603,4,-1.23205,1}
rotate関数で任意の軸で回転できる。
逆行列をつくる
逆行列は、ある座標が別の空間ではどの位置にいるか知るために使う。
// 座標
vector pos = point(1, "P", 0);
vector normal = point(1, "N", 0);
vector up = point(1, "up", 0);
matrix world = maketransform(normal, up, pos);
matrix inverseWorld = invert(world);
@P *= inverseWorld;
// 回転だけさせる場合は座標を原点にしておく
matrix orient = maketransform(normal, up, set(0,0,0));
matrix inverseOrient = invert(orient);
@N *= inverseOrient;
@up *= inverseOrient;
matrix型の行列にinvert関数を使うことで逆行列を作ることが出来る。ベクトルに適用するには逆行列をそのまま掛ける。
クォータニオン
軸回転
アップベクトルを軸に5°回転させる例。
float angle = 5;
vector up = set(0, 1, 0);
vector4 q = quaternion(radians(angle), up);
@N = qrotate(q, @N);