陷入矩阵运算错误

时间:2015-01-19 10:22:39

标签: ios matrix opengl-es

我在iOS中设置了一个2D opengl视图,左上角为原点,右下角为(768,1366)

我的投影矩阵设置如下:

projectionMtx = GLKMatrix4MakeOrtho( 0, 768, 1366, 0, 10, -10);

当我得到触摸事件时,坐标是物理坐标,我需要将它们转换成我自己的逻辑坐标,所以我想这样:

V_physical = M_projection * V_logical

以来

所以V_logical = M_projection_invert * V_phsical

我实现了这样的代码:

(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch* touch = [[event allTouches] anyObject];
    CGPoint location = [touch locationInView:self.view];

    GLKVector4 locationVector = {
        (float)location.x,
        (float)location.y,
        0,
        0,
    };

    GLKVector4 result = GLKMatrix4MultiplyVector4(GLKMatrix4Invert(projectionMtx, nullptr),locationVector);


    NSLog(@"touch %.2f %.2f", location.x, location.y);
    NSLog(@"vector %.2f %.2f", result.v[0], result.v[1]);
}

然而,这是我从测试中得到的:

touch 367.00 662.00

vector 140928.00 -452151.28

我的数学错了或我的代码错了吗?

1 个答案:

答案 0 :(得分:2)

你的坐标系有些混乱。投影矩阵将其输入坐标(在完整3D管线中通常称为"眼睛坐标")映射到剪辑坐标。对于平行投影,剪辑坐标与标准化设备坐标(NDC)相同,它在x和y方向上的范围为[-1,1]。

这意味着您的正投影:

projectionMtx = GLKMatrix4MakeOrtho( 0, 768, 1366, 0, 10, -10);

将[0,768]的x范围映射到[-1,1],并将[1366,0]的y范围映射到[-1,1]。由矩阵完成的映射是:

xNdc = (2.0 / 768.0) * xEye - 1.0
yNdc = (2.0 / -1366.0) * yEye + 1.0

相反的是:

xEye = (768.0 / 2.0) * (xNdc + 1.0)
yEye = (-1366.0 / 2.0) * (yNdc - 1.0)

应用此逆转换得出:

(768.0 / 2.0) * (367.0 + 1.0) = 141312.0
(-1366.0 / 2.0) * (662.0 - 1.0) = -451463

由于我目前无法解释的原因,这稍微偏离了你所得到的(看起来像是一次性的差异),但它非常相似。

这显然没有意义。要使用反投影变换,输入坐标应在[-1,1]范围内。

在您的使用案例中,由于您将投影变换设置为以像素为单位变换坐标,并且您还接收以像素为单位的触摸输入,因此您无需执行任何操作即可在OpenGL坐标系中获取触摸输入。它们已经在相同的坐标系(像素)中。

如果您使用任何其他投影。您首先将触摸坐标映射到[-1,1]范围,然后应用逆投影变换。坐标映射将使用与上面用于将眼睛坐标映射到NDC的方程相同的方程式。