请问如何确定屏幕上固定一点在世界坐标系中的三维坐标
例如屏幕上的点(X,Y), 我希望得到它在世界坐标系中的三维坐标,该如何求呢?
[解决办法]
在窗口中点击一个位置不能决定世界中的一个点。因为你点击一个点只能固定两个
分量,而z可以是任意的,因此,你只能决定一条线。那具体是哪一条线呢?看一下
流水线(opengl)就清楚了:
模型坐标(x,y,z) -> 扩展成齐次坐标(x,y,z,1) -> 进行world变换 -> (x ',y ',z ',1)
-> 进行view变换 -> (x ' ',y ' ',z ' ',1) -> 进行projection变换 -> (x ' ' ',y ' ' ',z ' ' ',w)
-> 进行perspective division(x ' ' '/w, y ' ' '/w, z ' ' '/w, w/w) = (x ' ' ' ',y ' ' ' ',z ' ' ' ', 1)
-> 齐次坐标再次转换成普通坐标 -> (x ' ' ' ', y ' ' ' ', z ' ' ' ') 这个时候点被变换到CVV
(Canonical View Volume)规则观察体中,(x ' ' ' ',y ' ' ' ',z ' ' ' ')都在
[-1,1]中,接着x ' ' ' '和y ' ' ' '会被进行viewport变换,z ' ' ' '不变 -〉(x ' ' ' ' ',y ' ' ' ' ',z ' ' ' ')中
的前两个用来在window中插值计算像素位置,z ' ' ' '用来做z-buffer的插值计算。
通过这个流程,可以看到,实际上点击的位置是经过视口变换的点,可以做逆视口变换处理。
这个时候得到CVV中xy面上的点x ' ' ' '和y ' ' ' ',因为CVV是点经过投影面(大多数情况设置成
前裁减平面)进行透视投影变换后的点,上面的透视除法x ' ' '/w和y ' ' '/w得到的是投影面A
(前裁减平面)上的点在CVV上x(-[-1,1],y(-[-1,1]这个规则投影面B上的点——实际上就是投影
面A到B的线性插值,对x ' ' ' '和y ' ' ' '再次进行从B到A的插值,得到投影面A的点,这个点在固定
管线中是
“view变换 -> (x ' ',y ' ',z ' ',1) -> 进行projection变换 -> (x ' ' ',y ' ' ',z ' ' ',w)”
这个变换中的中间值,本来应该是(x ' ',y ' ')变换到投影面A上,然后再变换到CVV的投影面B上
得到(x ' ' ',y ' ' '),但projection变换一次完成了!
得到A上的(x,y)之后,再把它和摄影机的位置连接起来作一条射线,这条射线就是我们要
求得射线,做picking的时候,在有效的objects中,和ray相交的第一个object就是picked
object。