...

第7章 座標変換

by user

on
Category: Documents
7

views

Report

Comments

Transcript

第7章 座標変換
7
7.1
7.1.1
OpenGL
×
×
×
6
±
OpenGL
API
(
78)
×
×
×
(
CPU
)
100
GPU
×
(
79)
部品
配置
部品
配置
78
79
80
101
7.1.2
(
)
(
80)
7.1.3
(
81)
81
82
×
y
y
y
視点座標系
ローカル座標系
z
y
z
x
スクリーン
x
z
x
z
ローカル座標系
82
102
x
ワールド座標系
7.1.4
×
(View Volume)
×
2
(Canonical View Volume)
×
(
×
ビューボリューム (View Volume)
視野錐台 (View Frustum)
標準ビューボリューム
(Canonical View Volume)
1
-1
-1
直交投影
(Orthographic Projection)
1
1
-1
透視投影
(Perspective Projection)
83
×
×
(Orthogonal Projection)
(Perspective Projection)
(View Frustum,
×
)
84
103
(
19)
83)
7.2
7.2.1
6
x0 = ax + b
x
(1)
a
b
x0 = axx x + ayx y + bx
y 0 = axy x + ayy y + by
(2)
x0 = axx x + ayx y + azx z + bx
y 0 = axy x + ayy y + azy z + by
z 0 = axz x + ayz y + azz z + bz
(3)
(3)
1 0
axx
x0
@ y 0 A = @ axy
axz
z0
0
ayx
ayy
ayz
10
1 0
1
bx
azx
x
azy A @ y A + @ by A
bz
azz
z
ayx
ayy
ayz
0
azx
azy
azz
0
(4)
7.2.2
(4)
x, y, z
0
1 0
x0
axx
B y 0 C B axy
B 0 C=B
@ z A @ axz
1
0
x’, y’, z’
1
C
C
A
(5)
(3)
(
(
10
bx
x
B y
by C
CB
bz A @ z
1
1
)
(5)
)
(
)
(x*, y*, z*)
(x, y, z, w)
x⇤
=
y⇤
=
z⇤
=
x
w
y
w
z
w
(6)
104
(x, y, z)
w
CG
0
x
B y
B
@ z
1
0
x
B y
B
@ z
0
(x, y, z, 1)
0
(x, y, z)
(x, y, z, 0)
(x, y, z)
1
(7)
1
(8)
C
C ) (x, y, z)
A
C
C ) (x, y, z)
A
0
1 0
x
ax
B y C B ay
C B
aB
@ z A = @ az
w
aw
1
⇣
⌘ ⇣
⌘
C
C ) ax , ay , az = x , y , z
A
aw aw aw
w w w
(9)
CG
P 0, P 1
P0
P0 = (x0, y0, z0, w0), P1 = (x1, y1, z1, w1)
P1
0
1
x1 /w1
B y1 /w1 C
P0
C
=B
@ z1 /w1 A
w0
1
P1
w1
w0
w 0 P1
0
1 0
x0 /w0
x1 /w1 x0 /w0
B y0 /w0 C B y1 /w1 y0 /w0
B
C B
@ z0 /w0 A = @ z1 /w1 z0 /w0
1
0
w1
0
0
0
1
w 0 x1
B w 0 y1 C
C
w 1 P0 = B
@ w 0 z1 A
w0 w1
1
C
C
A
(10)
w 0w 1
1
0
1
w 1 x0
w 0 x1 w 1 x0
B w 1 y0 C B w 0 y 1 w 1 y0 C
B
C B
C
@ w 1 z 0 A = @ w 0 z1 w 1 z0 A
w1 w0
0
(11)
(11)
0
P0
P1
0
(11)
w 0w 1
N
X
i=1
1 0 P
1
xi /wi
P
P ◆
✓P
P xi /wi
B yi /wi C B
Pi
xi
yi
zi
yi /wi C
B
C
B
C
P
=
)
,
,
@ zi /wi A = @
zi /wi A
wi
N
N
N
i=1
1
N
N
X
0
105
(12)
7.3
7.3.1
(5)
0
v
M
v’ = Mv
1
x
B y C
C
v=B
@ z A
w
0 0 1
x
B y0 C
0
C
v =B
@ z0 A
w0
0
m0 m4
B m1 m5
M=B
@ m2 m6
m3 m7
0 0 1 0
x
m0
B y 0 C B m1
B 0 C=B
@ z A @ m2
w0
m3
1
(15)
0
(13)
(14)
m4
m5
m6
m7
v’
x0
y0
z0
w0
=
=
=
=
1
m12
m13 C
C
m14 A
m15
m8
m9
m10
m11
m8
m9
m10
m11
(15)
10
m12
x
B y
m13 C
CB
m14 A @ z
m15
w
1
C
C
A
(16)
(x’, y’, z’, w’)
m0 x
m1 x
m2 x
m3 x
+
+
+
+
m4 y
m5 y
m6 y
m7 y
+
+
+
+
m8 z
m9 z
m10 z
m11 z
v’
1 0
x0
m0
B y 0 C B m1
B 0 C=B
@ z A @ m2
w0
m3
m4
m5
m6
m7
m12 w
m13 w
m14 w
m15 w
(17)
M
x’ = (m0 m4 m8 m12)
0
+
+
+
+
m8
m9
m10
m11
(x y z w)
v
T
10
m12
x
B y
m13 C
CB
m14 A @ z
m15
w
((17)
1
C
C
A
)
(18)
l OpenGL
(16)
4
4
CPU
OpenGL
GPU
106
GPU
0
m0
B m1
M=B
@ m2
m3
m4
m5
m6
m7
m8
m9
m10
m11
1
m12
m13 C
C
m14 A
m15
行列の表記
GLfloat(m[](=({
((m0, m1, m2,
!!m4, m5, m6,
m3,
m7,
!!m8, m9, m10, m11,
!!m12, m13, m14, m15
};
配列の要素の格納順序
85
7.3.2
t = (tx, ty, tz)
0
T(tx, ty, tz)
1
tx
ty C
C
tz A
1
(19)
1
x + tx
C B y + ty C
C=B
C
A @ z + tz A
1
(20)
1
B 0
T(t) = T(tx , ty , tz ) = B
@ 0
0
0
1
0
0
0
0
1
0
(x, y, z)
0
1
B 0
B
@ 0
0
0
1
0
0
0
0
1
0
10
tx
x
B y
ty C
CB
tz A @ z
1
1
T(7, 8, 0)
1
0
86
y
y
T(7, 8, 0)
O
x
8
O
x
7
86
0
1
B 0
B
@ 0
0
0
1
0
0
0
0
1
0
0
1
10
0
tx
x
x
B y C B y
ty C
CB
C=B
tz A @ z A @ z
1
0
0
1
C
C
A
(20)
l
m
107
// (x, y, z)
m
GLfloat *loadTranslate(GLfloat x, GLfloat y, GLfloat z, GLfloat *m)
{
m[12] = x;
m[13] = y;
m[14] = z;
m[ 1] = m[ 2] = m[ 3] =
m[ 4] = m[ 6] = m[ 7] =
m[ 8] = m[ 9] = m[11] = 0.0f;
m[ 0] = m[ 5] = m[10] = m[15] = 1.0f;
return m;
}
x, y, z
m
16
(20)
m0
m5
m10
m15
1
m12
x
m13
y
m14
(15)
z
m
l
0
//
m
GLfloat *loadIdentity(GLfloat *m)
{
return loadTranslate(0.0f, 0.0f, 0.0f, m);
}
7.3.3
s = (sx, sy, sz)
0
sx 0 0
B 0 sy 0
S(s) = S(sx , sy , sz ) = B
@ 0 0 sz
0 0 0
S(sx, sy, sz)
1
0
0 C
C
0 A
1
(21)
y
S(2, 2, 1)
O
x
87
s x, = s y, = s z = a
w
1/a
108
0
a
B 0
B
@ 0
0
0
1
B 0
B
@ 0
0
0
a
0
0
0
0
a
0
0
1
0
0
0
0
1
0
10
0
x
B y
0 C
CB
0 A@ z
1
1
10
0
B
0 C
CB
0 A@
1/a
1
0
1
ax
C B ay C
C=B
C
A @ az A ) (ax, ay, az)
1
1 0
1
x
x
B
C
y C
C = B y C ) (ax, ay, az)
z A @ z A
1
1/a
(22)
(23)
l
// (x, y, z)
m
GLfloat *loadScale(GLfloat x, GLfloat y, GLfloat z, GLfloat *m)
{
m[ 0] = x;
m[ 5] = y;
m[10] = z;
m[ 1] = m[ 2] = m[ 3] =
m[ 4] = m[ 6] = m[ 7] =
m[ 8] = m[ 9] = m[11] =
m[12] = m[13] = m[14] = 0.0f;
m[15] = 1.0f;
return m;
}
x, y, z
x
m
(23)
y
z
16
(15)
m0
x
m5
y
m
7.3.4
y
1
O
s
1
88
109
x
m10
z
m15
1
88
Y
0
s
s
1
0
0
0
0
1
0
1
0
0 C
C
0 A
1
1
B 0
Hxy (s) = B
@ 0
0
s
1
0
0
0
0
1
0
1
0
0 C
C
0 A
1
1
B s
Hyx (s) = B
@ 0
0
0
1
0
0
0
0
1
0
1
B 0
Hxy (s) = B
@ 0
0
X
(24)
(24)
x, y, z
0
0
1
0
0 C
C
0 A
1
0
1
B 0
Hyz (s) = B
@ 0
0
0
1
0
0
0
s
1
0
1
B 0
Hzy (s) = B
@ 0
0
0
1
s
0
0
0
1
0
0
1
0
0 C
C
0 A
1
1
0
0 C
C
0 A
1
0
1
B 0
Hzx (s) = B
@ s
0
0
1
0
0
0
0
1
0
1
B 0
Hxz (s) = B
@ 0
0
0
1
0
0
s
0
1
0
0
1
0
0 C
C
0 A
1
1
0
0 C
C
0 A
1
(25)
7.3.5
lX
θ!
89 X
0
1
B 0
Rx (✓) = B
@ 0
0
0
cos ✓
sin ✓
0
0
sin ✓
cos ✓
0
1
0
0 C
C
0 A
1
(21)
110
lY
θ!
90 Y
0
cos ✓
B
0
Ry (✓) = B
@ sin ✓
0
0 sin ✓
1
0
0 cos ✓
0
0
1
0
0 C
C
0 A
1
(22)
lZ
θ!
91 Z
0
cos ✓
B sin ✓
Rz (✓) = B
@ 0
0
sin ✓
cos ✓
0
0
0
0
1
0
1
0
0 C
C
0 A
1
(23)
l
(l, m, n)
111
(l,m,n)
θ!
92
R(l,
0 m, n,2 ✓)
l + (1 l2 ) cos ✓
B lm(1 cos ✓) + n sin ✓
=B
@ ln(1 cos ✓) m sin ✓
0
lm(1 cos ✓) n sin ✓
m2 + (1 m2 ) cos ✓
mn(1 cos ✓) + l sin ✓
0
ln(1 cos ✓) + m sin ✓
mn(1 cos ✓) l sin ✓
n2 + (1 n2 ) cos ✓
0
1
0
0 C
C
0 A
1
(24)
l
(24)
x, y, z
a
m
// (x, y, z)
a
m
GLfloat *loadRotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z, GLfloat *m)
{
const GLfloat d(sqrt(x * x + y * y + z * z));
if (d >
{
const
const
const
const
0.0f)
GLfloat
GLfloat
GLfloat
GLfloat
l(x / d), m(y / d), n(z / d);
l2(l * l), m2(m * m), n2(n * n);
lm(l * m), mn(m * n), nl(n * l);
c(cos(a)), c1(1.0f – c), s(sin(a));
m[ 0] = (1.0f - l2) * c + l2;
m[ 1] = lm * c1 + n * s;
m[ 2] = nl * c1 - m * s;
m[ 4] = lm * c1 - n * s;
m[ 5] = (1.0f - m2) * c + m2;
m[ 6] = mn * c1 + l * s;
m[ 8] = nl * c1 + m * s;
m[ 9] = mn * c1 - l * s;
m[10] = (1.0f - n2) * c + n2;
m[ 3] = m[ 7] = m[11] = m[12] = m[13] = m[14] = 0.0f;
m[15] = 1.0f;
}
return m;
}
112
7.4
i’, j’, k’
p
i, j, k
p
(x, y, z)
p
p = xi + yj + zk = x0 i0 + y 0 j0 + z 0 k0
i
(x’, y’, z’)
j
0
1
x
@ y A=
z
k
i0
j0
(30)
1
x0
@ y0 A
z0
0
k0
(31)
(x, y, z)
0
1
x
@ y A=
z
1
i j k
i0
j0
1
x0
@ y0 A
z0
0
k0
(32)
(i j k), (i’ j’ k’)
0
1
x
@ y A=
z
i j k
T
i0
j0
M
M=
i
j
k
T
M
i0
j0
k0
1
x0
@ y0 A
z0
0
(x’, y’, z’)
k0
0
i · i0
= @ j · i0
k · i0
(
(33)
(x, y, z)
i · j0
j · j0
k · j0
1
i · k0
j · k0 A
k · k0
(34)
)
r, s, t
0
1
1
0
1
tx
rx
sx
r = @ ry A , s = @ s y A , t = @ ty A
tz
rz
sz
0
X
Y
(35)
Z
x, y, z
0 1
1
0 1
0
1
0
x = @ 0 A, y = @ 1 A, z = @ 0 A
1
0
0
0
r, s, t
(36)
x, y, z
M
113
8
< x = Mr
y = Ms
:
z = Mt
x
y
z
(37)
=M
r
s
t
(38)
y
r
M
s
M
x
M
z
t
93
0
1
@ 0
0
0
1
0
1
0
0
rx
0 A = M @ ry
1
rz
sx
sy
sz
1
tx
ty A
tz
(39)
M
0
rx
M = @ ry
rz
sx
sy
sz
1
tx
ty A
tz
1
0
rx
= @ ry
rz
sx
sy
sz
1T 0
rx
tx
ty A = @ s x
tz
tx
ry
sy
ty
1 0 T 1
r
rz
sz A = @ sT A
tz
tT
(40)
7.5
7.5.1
94
4
y
3
(41)
T(4, 3, 0)
T(0, 3, 0)
T(4, 0, 0)
94
114
x
T(0, 3, 0)T(4, 0, 0)
0
1
B 0
=B
@ 0
0
0
1
0
0
0
0
1
0
1
B 0
=B
@ 0
0
0
1
0
0
0
0
1
0
0
10
0
1
B 0
3 C
CB
0 A@ 0
1
0
0
1
0
0
0
0
1
0
1
4
3 C
C = T(4, 3, 0)
0 A
1
1
4
0 C
C
0 A
1
(41)
l
OpenGL
//
m0
m1
m
GLfloat *multiply(const GLfloat *m0, const GLfloat *m1, GLfloat *m)
{
for (int j = 0; j < 4; ++j)
{
for (int i = 0; i < 4; ++i)
{
const int ji(j * 4 + i);
m[ji] = 0.0f;
for (int k = 0; k < 4; ++k)
m[ji] += m0[k * 4 + i] * m1[j * 4 + k];
}
}
return m;
}
//
m0
m1
m
GLfloat *multiply(const GLfloat *m0, const GLfloat *m1, GLfloat *m)
{
for (int ji = 0; ji < 16; ++ji)
{
const int i(ji & 3), j(ji & ~3);
m[ji] = m0[i] * m1[j] + m0[4 + i] * m1[j + 1]
+ m0[8 + i] * m1[j + 2] + m0[12 + i] * m1[j + 3];
}
return m;
}
115
7.5.2
0
r00
B r01
M = T(t)R(l, m, n, ✓) = B
@ r02
0
r10
r11
r12
0
r20
r21
r22
0
1
tx
ty C
C
tz A
1
(42)
!
M
0
r00
R̄ = @ r01
r02
r10
r11
r12
0
1
0
1
R̄
tx
r20
r21 A , t = @ ty A ) M = @
tz
r22
0T
t
1
t
1
A
(43)
7.5.3
7.3.5
M = T(p) Rz(θ) T(−p)
y
y
y
p
p
T( p)
O
T(p)
Rz(θ)
θ"
x
x
O
M = T(p) Rz(θ) T( p)
95
7.5.4
l
116
O
x
y
(移動)
O
x
96
M = T(p) S(s) T(−p)
y
y
y
p
p
T(-p)
x
O
T(p)
S(s)
x
O
x
O
M = T(p) S (s) T( p)
97
7.5.5
X Y Z
l
X
Y
Z
(x y z)
(r s t)
F
sr
ss
S
F=
✓
r s t 0
0 0 0 1
st
M = FSF
◆
X
Y
Z
T
(44)
117
0
sr
B 0
S=B
@ 0
0
s
0
ss
0
0
0
0
st
0
y
1
0
0 C
C
0 A
1
(45)
s
s
s
y
r
r
O
x
FT
r
O
S
O
r
F
O
x
M = F S FT
98
7.5.6
y
O
y
x
R(θ)
O
y
O
y
x
S(s)
y
x
S(s)
O
99
7.6
7.6.1
X, Y, Z
118
O
x
y
x
R(θ)
O
x
y
heading
pitch
roll
z
x
100
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)
E(h, p, r) = Ry (h)Rx (p)Rz (r)
0
cos h
B
0
=B
@ sin h
0
0
1
0
0
sin h
0
cos h
0
0
10
0
1
B 0
0 C
CB
0 A@ 0
1
0
sin h sin p sin r + cos h cos r
B
cos p sin r
=B
@ cos h sin p sin r sin h cos r
0
0
cos p
sin p
0
0
sin p
cos p
0
10
0
cos r
B sin r
0 C
CB
0 A@ 0
1
0
sin h sin p cos r cos h sin r
cos p cos r
cos h sin p cos r + sin h sin r
0
sin r
cos r
0
0
sin h cos p
sin p
cos h cos p
0
0
0
1
0
1
0
0 C
C
0 A
1
(46)
1
0
0 C
C
0 A
1
7.6.2
p=
/2
sin p = 1, cos p = 0
(46)
0
sin h sin r + cos h cos r
B
0
E(h, ⇡/2, r) = B
@ cos h sin r sin h cos r
0
sin h cos r
cos h sin r
0
cos h cos r + sin h sin r
0
119
0
1
0
0
1
0
0 C
C
0 A
1
(47)
0
cos(h r) sin(h
B
0
0
E(h, ⇡/2, r) = B
@ sin(h r) cos(h
0
0
r)
r)
0
1
0
0
1
0
0 C
C
0 A
1
(48)
(h - r)
r
h
p=
r
(Z
)
/2
h
7.6.3
M
0
m0
B m1
M=B
@ m2
m3
m1
m4
m5
m6
m7
m5
(49)
! r = atan2(m5 , m1 )
(50)
m10
m8 = sin h cos p
m10 = cos h cos p
p
1
m12
m13 C
C = E(h, p, r)
m14 A
m15
m8
m9
m10
m11
r
m1 = cos p sin r
m5 = cos p cos r
m8
E(h, p, r)
h
!
(51)
h = atan2(m10 , m8 )
m9
m9 =
sin p !
p = asin( m9 )
m1 = m5 = 0
cos p = 0
(50)
h=0
m0 = cos(h ⌥ r)
m4 = sin(h ⌥ r)
(52)
m0
!
p=
(51)
r
m14
h = 0, r =
/2
h
h
(53)
atan2(m0 , m4 )
7.7
7.7.1
(
x
)
y
120
z
x
y
OpenGL
(
101)
z
y
y
z
x
x
z
101
z
z
y
y
-z
O
x
O
z
x
z
102
7.7.2
l
e = (ex, ey, ez)
g = (gx, gy, gz)
u = (ux, uy, uz)
y
(0, 1, 0)
上方向の y
ベクトル
u = (ux , uy , uz )
視点の位置
e = (ex , ey , ez )
目標点の位置
g = (gx , gy , gz )
O
z
103
121
x
l
e = (ex, ey, ez)
0
1 0
B 0 1
Tv = B
@ 0 0
0 0
0
0
1
0
Tv
ex
ey C
C
ez A
1
r, s, t
l
O = (0, 0, 0)
1
(54)
e
g–e
u
(r s t)
y
y
y
u
t
t
t
x
O
r
x
O
r
s
O
x
g e
z
z
t=e−g
z
r=u×t
104
(r s t)
z
t = (tx, ty, tz)
x
y
r
t=e
e−g
r = (rx, ry, rz)
u×t
t
s=t×r
u
t
s = (sx, sy, sz)
t×r
0
ex
g = @ ey
ez
0
u y tz
r = u ⇥ t = @ u z tx
u x ty
0
t y rz
s = t ⇥ r = @ tz rx
tx r y
1 0
1
gx
tx
g y A = @ ty A
gz
tz
1
1 0
u z ty
rx
u x tz A = @ r y A
rz
u y tx
(55)
1
1 0
sx
tz ry
tx rz A = @ s y A
sz
t y rx
l
(r s t)
(40)
Rv
122
(56)
0
B
B
B
B
B
Rv = B
B
B
B
@
rT
|r|
sT
|s|
tT
|t|
0
0
1 0
0 C B
C B
C B
B
0 C
C B
=
C B
C B
C B
B
0 C
A @
rx
|r|
sx
|s|
tx
|t|
0
0 1
ry
|r|
sy
|s|
ty
|t|
rz
|r|
sz
|s|
tz
|t|
0
0
C
C
C
0 C
C
C
C
0 C
C
A
1
0
s
1
(56)
0
r
0
4 × 4 = 16
t
rv
3×3
l
Tv
Rv
(57)
Mv = Rv Tv
y
z
(0, 1, 0)
O (1, 0, 0)
(0, 0, 1)
z
105
l
//
m
GLfloat *loadLookat(
GLfloat ex, GLfloat ey,
GLfloat gx, GLfloat gy,
GLfloat ux, GLfloat uy,
GLfloat *m)
{
//
GLfloat tv[16];
loadTranslate(-ex, -ey,
GLfloat ez,
GLfloat gz,
GLfloat uz,
-ez, tv);
// t
= e - g
const GLfloat tx(ex - gx);
const GLfloat ty(ey - gy);
const GLfloat tz(ez - gz);
// r
= u x t
const GLfloat rx(uy * tz - uz * ty);
const GLfloat ry(uz * tx - ux * tz);
const GLfloat rz(ux * ty - uy * tx);
123
//
//
//
x
// s
= t
x r
const GLfloat sx(ty * rz - tz * ry);
const GLfloat sy(tz * rx - tx * rz);
const GLfloat sz(tx * ry - ty * rx);
// s
const GLfloat s2(sx * sx + sy * sy + sz * sz);
if (s2 == 0.0f) return m;
//
GLfloat rv[16];
// r
const GLfloat
rv[ 0] = rx /
rv[ 4] = ry /
rv[ 8] = rz /
r(sqrt(rx * rx + ry * ry + rz * rz));
r;
r;
r;
// s
const GLfloat
rv[ 1] = sx /
rv[ 5] = sy /
rv[ 9] = sz /
s(sqrt(s2));
s;
s;
s;
// t
const GLfloat
rv[ 2] = tx /
rv[ 6] = ty /
rv[10] = tz /
t(sqrt(tx * tx + ty * ty + tz * tz));
t;
t;
t;
//
rv[ 3] = rv[ 7] = rv[11] = rv[12] = rv[13] = rv[14] = 0.0f;
rv[15] = 1.0f;
//
return multiply(rv, tv, m);
}
7.8
7.8.1
(
)
(
106
[-1, 1]
(Canonical View Volume)
xy
124
×
)
y
1
−1
−1
1
O
1
x
−1
z
106
7.8.2
l
2
(left, bottom)
(right, top)
(near, far)
xy
z
(
near
(xy
)
far
(View Volume)
後方面
(yon)
前方面
(hither)
top
y
視体積
(view volume)
left
right
bottom
視点
−near
−far
x
z
107
(hither)
(yon)
z
−near
z
−far
125
)
2
y
y
y
O
O
O
x
x
z
x
z
z
中心が原点になるよう平行移動
大きさを正規化
108
l
((right + left) / 2, (top + bottom) / 2, −(far + near) / 2)
+
2
+
2
109
(21)
(58)
far
near
Z
0
Mcentering
1 0 0
B
B
B
B 0 1 0
=B
B
B
B 0 0 1
@
0 0 0
right + lef t
2
top + bottom
2
f ar + near
2
1
1
C
C
C
C
C
C
C
C
A
126
(58)
l
2
right – left top – bottom –(far – near)
1
2
1
1
2
1
110
2
(21)
(59)
far
near
Z
0
Mscaling
2
B right lef t
B
B
0
B
=B
B
B
0
@
0
top
0
0
2
bottom
0
2
0
f ar
0
near
0
1
0 C
C
C
0 C
C
C
0 C
A
1
(59)
l
Mo
Mo
Mcentering
Mscaling
= Mscaling Mcentering
0
2
B right lef t
B
B
B
0
=B
B
B
B
0
@
0
top
0
0
2
bottom
0
0
2
f ar
0
near
0
right + lef t
right lef t
top + bottom
top bottom
f ar + near
f ar near
1
1
C
C
C
C
C
C
C
C
A
l
m
//
m
GLfloat *loadOrthogonal(GLfloat left, GLfloat right,
GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar, GLfloat *m)
{
const GLfloat dx(right - left);
127
(60)
const GLfloat dy(top - bottom);
const GLfloat dz(zFar - zNear);
if (dx !=
{
m[ 0] =
m[ 5] =
m[10] =
m[12] =
m[13] =
m[14] =
m[15] =
m[ 1] =
}
0.0f && dy != 0.0f && dz != 0.0f)
2.0f / dx;
2.0f / dy;
-2.0f / dz;
-(right + left) /
-(top + bottom) /
-(zFar + zNear) /
1.0f;
m[ 2] = m[ 3] = m[
dx;
dy;
dz;
4] = m[ 6] = m[ 7] = m[ 8] = m[ 9] = m[11] = 0.0f;
return m;
}
7.8.3
2
(left, bottom)
(right, top)
(near, far)
(
)
(View Frustum)
後方面
(yon)
前方面
(hither)
top
y
left
right
bottom
視点
z
−near
視錐台
(view frustum)
−far
x
111
(z
2
128
)
y
y
y
O
O
x
z
O
x
z
x
z
透視変換して平行移動と正規化
Z軸が中心を通るようにせん断変形
112
l
z
–near
left) / 2, (top + bottom) / 2)
((right +
z = –1
((right + left) / 2near, (top +
bottom) / 2 near)
−
−
−1
2
2
113
0
Mshear
B 1 0
B
B
=B
B 0 1
B
@ 0 0
0 0
right + lef t
2 near
top + bottom
2 near
1
0
1
0 C
C
C
0 C
C
C
0 A
1
(61)
l
(
–near
,z
)
(–near x / z, –near y / z)
l
129
(x, y, z)
z
y
後方面
(yon)
前方面
(hither)
y
− near
z
z
y
−near
z
O
−far
視錐台
(view frustum)
114
Mperspective
0
near
B 0
B
=B
@ 0
0
0
near
0
0
0
0
f ar + near
2
1
0
0
1
C
C
C
f ar near A
(62)
0
l
Mp
Mperspective
Mshear
Mscaling
Mp
= Mscaling Mperspective Mshear
0
2 near
B right lef t
B
B
B
0
B
=B
B
B
0
B
@
0
0
2 near
top bottom
0
0
right + lef t
right lef t
top + bottom
top bottom
f ar + near
f ar near
1
0
1
C
C
C
C
0
C
C
2 f ar near C
C
C
f ar near A
0
l
m
//
m
GLfloat *loadFrustum(GLfloat left, GLfloat right,
GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar, GLfloat *m)
{
const GLfloat dx(right - left);
const GLfloat dy(top - bottom);
const GLfloat dz(zFar - zNear);
if (dx !=
{
m[ 0] =
m[ 5] =
m[ 8] =
m[ 9] =
0.0f && dy != 0.0f && dz != 0.0f)
2.0f *
2.0f *
(right
(top +
zNear /
zNear /
+ left)
bottom)
dx;
dy;
/ dx;
/ dy;
130
(63)
m[10]
m[11]
m[14]
m[ 1]
=
=
=
=
-(zFar + zNear) / dz;
-1.0f;
-2.0f * zFar * zNear / dz;
m[ 2] = m[ 3] = m[ 4] = m[ 6] = m[ 7] = m[12] = m[13] = m[15] = 0.0f;
}
return m;
}
7.8.4
(z
115
xz
)
A = (xa, za)
C
B = (xb, zb)
z=
near
D
A = (xa , za )
Q = (xq , zq )
B = (xb , zb )
near
C
P
D
t
O
1−t
x
z
115
CD
t:1–t
Q = (xq, zq)
P
Q
x
AB
(64)
8
xa
xb
>
(1 t) + t
>
>
z
zb
>
>
xq = a
>
>
1
1
<
(1 t) + t
za
zb
>
>
1
>
>
>
> zq = 1
1
>
:
(1 t) + t
za
zb
(64)
P
Q
z
zq
xq
(64)
A
z
za
z = 1
Q
zq
131
B
z
zb
(z
)
−far near
(far − near) / 2
(59)
Mscaling
0
−2 / (far − near)
[-1, 1]
far
f ar near
z
f ar
near
⇥
2
2
f ar
near
far - near
1
2
near
z O
-far
-near
-far
z
-
O
-near
-near
-far
z O
far - near
-1
2
116
(62)
x⇤
=
y⇤
=
z⇤
=
near
x
z
near
y
z
f ar near
z
(65)
f ar + near
2
(62)
(66)
(x, y, z)
(67)
1 0 near
x0
0
B y0 C B
B 0 C=B
B
@ z A @ 0
w0
0
0
Mperspective
0
near
0
0
0
0
f ar + near
2
1
10
1
x
CB
CB y C
C
C
f ar near A @ z A
1
0
0
0
(66)
x0 = near x
y 0 = near y
f ar + near
z0 =
z + f ar near
2
w0 = z
(x*, y*, z*)
(67)
(65)
132
7.8.5
y
(68)
f
fovy
)
(fovy)
aspect ratio
2
(
z = −near
−bottom = top = near / f −left
= right = aspect near / f
(63)
(69)
y
1
O
z
fovy
−1
y
fovy
−f
O
−near
x
z
−near
−far
−far
117
1
✓
◆ = cot
f=
f ovy
tan
2
0
f
B aspect
B
0
B
Mp = B
B
0
@
0
0
f
0
0
✓
f ovy
2
◆
(68)
0
0
f ar + near
f ar near
1
0
0
2 f ar near
f ar near
0
1
C
C
C
C
C
A
l
m
//
m
GLfloat *loadPerspective(GLfloat fovy, GLfloat aspect,
GLfloat zNear, GLfloat zFar, GLfloat *m)
{
const GLfloat dz(zFar - zNear);
if (dz !=
{
m[ 5] =
m[ 0] =
m[10] =
0.0f)
1.0f / tan(fovy * 0.5f);
m[5] / aspect;
-(zFar + zNear) / dz;
133
(69)
m[11]
m[14]
m[ 1]
m[ 6]
m[12]
=
=
=
=
=
-1.0f;
-2.0f *
m[ 2] =
m[ 7] =
m[13] =
zFar * zNear / dz;
m[ 3] = m[ 4] =
m[ 8] = m[ 9] =
m[15] = 0.0f;
}
return m;
}
134
Fly UP