• 検索結果がありません。

変換の合成

ドキュメント内 GLFW による OpenGL 入門 (ページ 137-143)

第 7 章 座標変換

7.4 変換の合成

}

return t;

} };

for (int j = 0; j < 4; ++j) {

for (int i = 0; i < 4; ++i) {

const int ji(j * 4 + i);

t.matrix[ji] = 0.0f;

for (int k = 0; k < 4; ++k)

t.matrix[ji] += matrix[k * 4 + i] * m.matrix[j * 4 + k];

} }

return t;

}

ただし、これは三重のループになっているので、性能が少し気になります。たとえば次のよう に書けば、ループを一重にできます。

// 乗算

Matrix operator*(const Matrix &m) const {

Matrix t;

for (int i = 0; i < 16; ++i) {

const int j(i & 3), k(i & ~3);

t.matrix[i] =

matrix[ 0 + j] * m.matrix[k + 0] + matrix[ 4 + j] * m.matrix[k + 1] + matrix[ 8 + j] * m.matrix[k + 2] + matrix[12 + j] * m.matrix[k + 3];

}

return t;

}

7.4.2 剛体変換

平行移動と回転は、立体の形状に影響を与えません。そのため、この二つを組み合わせた変換 は剛体変換と呼ばれます。

(32)

したがって、この Mは回転の変換行列 𝐑" と平行移動のベクトル t で構成されます。

(33) M=T(t)R(l, m, n,✓) =

0 BB

@

r00 r10 r20 tx

r01 r11 r21 ty

r02 r12 r22 tz

0 0 0 1

1 CC A

R¯ = 0

@ r00 r10 r20

r01 r11 r21

r02 r12 r22

1 A, t=

0

@ tx

ty

tz

1

A ) M= 0

@ R¯ t 0T 1

1 A

7.4.3 任意の点を中心にした回転

7.3.6 で示した回転の変換は、いずれも原点を通る軸を中心としたものでした。任意の点を点を

通る軸を中心に回転するには、一旦その点を原点に移す平行移動を行い、回転した後に元の位置 に戻すという処理を行います。これは次の三つの変換の合成変換 M = T(p) Rz(q) T(-p) です。

81 任意の点を中心とする回転

7.4.4 任意の点を中心にした拡大縮小

7.3.4で示した拡大縮小は、原点を基準にしています。そのため、拡大縮小を行うとする図形が

原点から離れていると、図形全体の位置も変ってしまいます。

図 82 拡大縮小に伴う図形の移動

図形を、その図形の位置で拡大するためには、拡大縮小を行う際の基準点を図形の位置に移す 必要があります。これは基準点が原点になるように図形を平行移動し、その後に拡大縮小して、

元の位置に戻すことで実現します。これは次の三つの変換の合成変換 M = T(p) S(s) T(-p) です。

p

x y

x y

x y

p

T( p)

θ"

R

z

( θ ) T(p)

M = T(p) R

z

( θ ) T( p)

O O O

O x

y

(移動)

83 任意の基準点による拡大縮小

7.4.5 特定方向への拡大縮小

7.3.4 で示した拡大縮小は、また x、y、z のそれぞれの軸方向に対する拡大縮小しか行うこと

ができません。任意の方向に対して拡大縮小を行うためには、その方向を一旦 x、y、z 軸の方向 に合わせてから拡大縮小を行い、それから元の向きに戻します。いま、軸ベクトル (x y z) をそれ ぞれ (r s t) 方向に回転する変換行列を Fsrssst をそれぞれ x、y、z 軸方向の拡大率とする 拡大縮小の変換行列 S とするとき、この変換は M = FSFT となります。

(34)

(35)

図 84 特定方向への拡大縮小

x y

x y

p

T(-p) T(p)

M = T(p) S (s) T( p) S(s)

p

x y

O O O

F=

✓ r s t 0 0 0 0 1

S= 0 BB

@

sr 0 0 0 0 ss 0 0 0 0 st 0 0 0 0 1

1 CC A

F

T

S F

x s y

r O

s O r

s

O r x

s y

r O

M = F S F

T

7.4.6 オイラー変換

原点を中心とした任意の回転は、x, y, z の三つの軸中心の回転を合成して表すことができます。

この回転を表す各軸中心の回転角の組をオイラー角といい、それらによって表される回転の変換 をオイラー変換といいます。

85 オイラー角

合成変換は変換行列の積で表されますが、行列の積には交換法則が成り立たちません。したが ってオイラー変換の結果は、各軸中心の回転を合成する順序によって変化します。ここでは、z 軸 中心の回転 (roll, bank) → x 軸中心の回転 (pitch) → y 軸中心の回転 (heading, yaw) の順に変 換するものとします。また、それぞれの角度を r, p, h で表します。

• r: roll, bank (z 軸中心の回転角)

• p: pitch (x 軸中心の回転角)

• h: heading, yaw (y 軸中心の回転角)

このとき、オイラー変換 E(h, p, r) は次式で表されます。

(36) heading

pitch roll

z x

y

E(h, p, r) =Ry(h)Rx(p)Rz(r)

= 0 BB

@

cosh 0 sinh 0

0 1 0 0

sinh 0 cosh 0

0 0 0 1

1 CC A

0 BB

@

1 0 0 0

0 cosp sinp 0 0 sinp cosp 0

0 0 0 1

1 CC A

0 BB

@

cosr sinr 0 0 sinr cosr 0 0

0 0 1 0

0 0 0 1

1 CC A

= 0 BB

@

sinhsinpsinr+ coshcosr sinhsinpcosr coshsinr sinhcosp 0

cospsinr cospcosr sinp 0

coshsinpsinr sinhcosr coshsinpcosr+ sinhsinr coshcosp 0

0 0 0 1

1 CC A

l ジンバルロック

オイラー角のうち、p = π/ 2 の場合を考えます。このとき sin p = 1, cos p = 0 になるので、式

(36) は次のようになります。

(37)

これは、加法定理により、次のように書き換えられます。

(38)

この回転は h - r という単一の角度で決定される、一つの軸による回転です。このため、r h のどちらを変化させても同じ回転になり、自由度が一つ減ってしまいます。p = π/ 2 の回転によ って r の回転軸 (z 軸) が h の回転軸と一致します。この現象をジンバルロックといいます。

l 回転変換行列からオイラー角の算出

ある回転変換行列 M がオイラー変換 E(h, p, r) にもとづくものであったとします。

(39)

m1m5 の関係から、r を求めることができます。

(40)

同様に、m8m10 の関係から、h を求めることができます。

(41)

p m9 から求めることができます。

(42) ただし、m1 = m5 = 0 のときは cos p = 0 なので、p = ±π/ 2 となります。これはジンバルロッ

E(h,⇡/2, r) = 0 BB

@

sinhsinr+ coshcosr sinhcosr coshsinr 0 0

0 0 1 0

coshsinr sinhcosr coshcosr+ sinhsinr 0 0

0 0 0 1

1 CC A

E(h,⇡/2, r) = 0 BB

@

cos(h r) sin(h r) 0 0

0 0 1 0

sin(h r) cos(h r) 0 0

0 0 0 1

1 CC A

M= 0 BB

@

m0 m4 m8 m12

m1 m5 m9 m13

m2 m6 m10 m14

m3 m7 m11 m15

1 CC

A=E(h, p, r)

m1 = cospsinr

m5 = cospcosr ! r=atan2(m5, m1)

m8 = sinhcosp

m10= coshcosp ! h=atan2(m10, m8)

m9= sinp! p=asin( m9)

クが発生している状態であり、式 (40) や式 (41) で r h を求めることができません。その場 合は、たとえば h = 0 とし、m0m14 の関係から、h を求めることができます。

(43)

7.4.7 変換の順序

変換の合成は行列の積で表されますが、行列の積は交換の法則が成り立ちません。したがって、

同じ変換行列を合成した場合でも、その順序が異なれば、合成変換の結果は異なります。図 86 の 例では、正方形を回転してから x 軸方向に引き伸ばすとひし形になりますが、x 軸方向に引き伸 ばしてから回転すると回転した長方形になります。

図 86 変換の順序による合成変換の結果の違い

ドキュメント内 GLFW による OpenGL 入門 (ページ 137-143)