我正在尝试获取一个4x4投影矩阵,将世界上的一个点转换为显示坐标。
有一个像素(x,y)和相应的z值(来自zbuffer
),我用vtkWorldPointPicker
类获得了它的3D世界坐标。我们用 x 表示结果。
根据documentation,我可以通过将矩阵GetCompositeProjectionTransformMatrix
应用于 x 来计算世界点的视图坐标。接下来,我使用vtkViewport::ViewToDisplay
(*)中的代码使用从视图到初始显示坐标的转换:
dx = (v[0] + 1.0) * (sizex*(v[2]-v[0])) / 2.0 + sizex*v[0];
dy = (v[1] + 1.0) * (sizey*(v[3]-v[1])) / 2.0 + sizey*v[1];
其中sizex
和sizey
是图像的宽度和高度(以像素为单位),v
是计算出的视图坐标。
不幸的是,我收到的值与原始值不符:
display [0, 0, 0.716656] // x,y-pixel coordinates and the zbuffer
x = [0.0255492, -0.0392383, 0.00854707] // world coordinates (using vtkWorldPointPicker)
// camera->GetCompositeProjectionTransformMatrix
P = [
-1.84177 0 0 0
0 1.20317 1.39445 0
0 -757.134 653.275 -9.9991
0 -0.757126 0.653268 0 ]
v = [-0.0470559, -0.0352919, 25.2931, 0.0352919] // P*x
a = [7697.18, -0.597848] // using (*)
这种方法(一般来说)是否正确,还是有更传统的方法来做到这一点?谢谢你的帮助。
修改:vtkViewport::ViewToDisplay
提供的代码段不正确。它应该是:
dx = (v[0] + 1.0) * (sizex*(vp[2]-vp[0])) / 2.0 + sizex*vp[0];
dy = (v[1] + 1.0) * (sizey*(vp[3]-vp[1])) / 2.0 + sizey*vp[1];
注意,v
是指标准化的视图坐标,vp
是视口(默认为vp := [0, 0, 1, 1]
)!
答案 0 :(得分:0)
转换确实有效,尽管可能有内置的方法来获得最终矩阵。
假设只使用一个(默认)视口,将视图转换为显示坐标的矩阵为:
M = [X/2, 0, 0, X/2,
0, Y/2, 0, Y/2,
0, 0, 1, 0,
0, 0, 0, 1]
其中X
和Y
是图像的宽度和高度(以像素为单位)。
因此,给定世界坐标中的点x
,均匀形式的显示坐标为:
c = M * P * x;
其中P
是CompositeProjectionTransformMatrix
。标准化后(c[i] /= c[3]
,i = 0,1,2
),我们得到原始像素值。