(一)世界坐标系向观察坐标系的转换
假如任何形体都放在世界坐标系中,那么计算是相当复杂的,为了简化计算,我们需要把形体从世界坐标系转到观察坐标系中。观察坐标系的原点在是世界坐标系的位置为Eye,Z轴与观察方向一致(从Eye出发到At点的向量)如图4-1所示:
图4-1
假设观察坐标系的坐标轴分别以单位向量xaxis,yaxis,zaxis,则:
xaxis= normal (At-Eye);
yaxis= normal (cross(Up,zaxis));
zaxis= normal (zaxis,xaxis);
假设世界坐标系中任意一点P的坐标(x,y,z),在观察坐标系中的坐标(x',y',z')。
x' = (P-Eye)* xaxis = x*xaxis.x + y* xaxis.y + z * xaxis.z - xaxis*Eye
y' = (P- Eye)*yaxis = x*yaxis.x + y* yaxis.y + z * yaxis.z - yaxis*Eye
z'= (P- Eye)*zaxis = x*zaxis.x + y* zaxis.y + z * zaxis.z - zaxis*Eye
(二)齐次裁剪透视投影变换
真实的物体是三维的,但是计算机屏幕是二维的,必须把三维物体投影到屏幕平面上,而且还要保存深度信息,这个变换过程称为投影变换,如图4-2所示
图4-2
假设视截体Y方向的张角fov,近平面Zn,远平面的Zf,近平面的宽高比aspect,现在可以直到近平面的方程z=Zn,远平面 z=Zf。
图4-3
由图4-3可以看出,视截体的顶面方程为y=z*tan(fov/2);底面方程=-z*tan(fov/2);视截体的右侧面x=cot(fov/2)*aspect*z.
左侧面方程x=-cot(fov/2)*aspect*z.
首先寻求把顶面y = z*tan(fov/2) 转换为y'=1,y'=k*y ,k=cot(fov/2)*y/z就是满足条件的变换,底面变换也是这个表达式。
右侧面x = cot(fov/2)*aspect*z,转换为x'=1, x'=p*x, 从而p=(tan(fov/2)/aspect)/z(左侧面表达式相同).
最后寻求把近平面Zn转换为z'=0;Zf转换为z'=1. z'= r*z + s.于是r* Zn + s =0,r*Zf + s =1,由此求出 r= /(Zf-Zn), s= -Zn/(Af-Zn).
透视投影变换矩阵=
(三)视截体平面的计算
根据模型变换矩阵和投影变换矩阵,可以计算出视截体的6个平面。世界坐标系中的视截体在模型变换和透视投影变换后,成为观察坐标系中的[-1,1]*[-1,1]*[0,1]。设模型变换A,投影变换B,M=A*B,视截体的方程:ax+by+cz+d=0。该平面在观察坐标系中的形式为a'x'+b'y'+c'z'+d'=0.
(x',y',z',1) = (x,y,z,1)M
(x,y,z,1)(a,b,c,d)(转置)=0
(x',y',z',1)(a',b',c',d')(转置) = 0
可得:(x,y,z,1)M(a',b',c',d')(转置) = 0
(a,b,c,d)(转置)= M (a',b',c',d')(转置)
a=M11a'+M12b'+M13c'+M14d'
b=M21a'+M22b'+M23c'+M24d'
c=M31a'+M32b'+M33c'+M34d'
d=M41a'+M42b'+M43c'+M44d'
视截体的6个平面的法向量均指向视截体内部,视截体的左侧面leftplane 观察坐标系中的左侧面x+1=0 ,代入上式可得视截体左侧面的系数
a=M11+M14
b=M21+M24
c=M31+M34
d=M41+M44
右侧面的方程1-x=0;系数
a=M14-M11
b=M24-M21
c=M34-M31
d=M44-M41
同理:顶面系数
a=M14-M12
b=M24-M22
c=M24-M32
d=M44-M42
底面系数
a=M12+M14
b=M22+M24
c=M32+M34
d=M42+M44
近平面系数:
a=M13
b=M23
c=M33
d=M43
远平面系数:
a=M14-M13
b=M24-M23
c=M34-M33
d=M44-M43
上述内容是涉及视截体计算的数学基础,下一节实战视截体编程!