【问题标题】:Use of maths in the Apple pARk sample code在 Apple PARk 示例代码中使用数学
【发布时间】:2012-03-13 09:23:37
【问题描述】:

我研究了 pARK 示例项目 (http://developer.apple.com/library/IOS/#samplecode/pARk/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011083) 所以我可以在我正在开发的应用程序中应用它的一些基础知识。我几乎什么都懂,除了:

  • 计算兴趣点是否必须出现的方式。它得到姿态,将其与投影矩阵相乘(以获得 GL 坐标中的旋转?),然后将该矩阵与兴趣点的坐标相乘,最后,查看该向量的最后一个坐标以找出如果必须显示兴趣点。这有哪些数学基础?

非常感谢!!

【问题讨论】:

    标签: ios


    【解决方案1】:

    我假设您指的是以下方法:

    - (void)drawRect:(CGRect)rect
    {
         if (placesOfInterestCoordinates == nil) {
             return;
         }
    
        mat4f_t projectionCameraTransform;
        multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransform);
    
        int i = 0;
        for (PlaceOfInterest *poi in [placesOfInterest objectEnumerator]) {
            vec4f_t v;
            multiplyMatrixAndVector(v, projectionCameraTransform, placesOfInterestCoordinates[i]);
    
            float x = (v[0] / v[3] + 1.0f) * 0.5f;
            float y = (v[1] / v[3] + 1.0f) * 0.5f;
            if (v[2] < 0.0f) {
                poi.view.center = CGPointMake(x*self.bounds.size.width, self.bounds.size.height-y*self.bounds.size.height);
                poi.view.hidden = NO;
            } else {
                poi.view.hidden = YES;
            }
            i++;
        }
    }
    

    这是在感兴趣的地方执行类似于 OpenGL 的顶点变换,以检查它们是否在可视截锥体中。截锥体是在以下行中创建的:

    createProjectionMatrix(projectionTransform, 60.0f*DEGREES_TO_RADIANS, self.bounds.size.width*1.0f / self.bounds.size.height, 0.25f, 1000.0f);
    

    这将设置一个具有 60 度视场的截锥体、一个 0.25 的近剪裁平面和一个 1000 的远剪裁平面。然后,任何超过 1000 个单位的兴趣点都将不可见。

    因此,要逐步执行代码,首先将设置截锥体的投影矩阵和相机视图矩阵相乘,相机视图矩阵只是简单地旋转对象,使其相对于相机正确向上。然后,对于每个感兴趣的地方,其位置乘以 viewProjection 矩阵。这会将感兴趣地点的位置投影到视锥中,应用旋转和透视。

    接下来的两行将转换后的地点位置转换为所谓的标准化设备坐标。 4 分量向量需要折叠到 3 维空间,这是通过将其投影到平面 w == 1 上,将向量除以其 w 分量 v[3] 来实现的。然后可以通过检查其坐标是否位于边长为 2 且原点为 [0, 0, 0] 的立方体中来确定该点是否位于投影平截头体内。在这种情况下,x 和 y 坐标从 [-1 1] 到 [0 1] 范围内有偏差,以匹配 UIKit 坐标系,方法是加 1 并除以 2。

    接下来,检查v[2]分量z是否大于0。这实际上是不正确的,因为它没有被偏置,应该检查它是否大于-1。这将检测感兴趣的地方是否在投影平截头体的前半部分,如果是,则该对象被视为可见并显示。

    如果您不熟悉顶点投影和坐标系,这是一个庞大的主题,学习曲线相当陡峭。然而,网上有很多材料涵盖它,这里有几个链接可以帮助您入门:

    http://www.falloutsoftware.com/tutorials/gl/gl0.htm

    http://www.opengl.org/wiki/Vertex_Transformation

    祝你好运//

    【讨论】:

    • 那么,我们将投影矩阵和相机矩阵相乘只是为了以适当的方式旋转对象?对吗?
    • 相机矩阵旋转位置以匹配设备当前旋转,在- (void)onDisplayLink:(id)sender。如上所述,投影矩阵将位置投影到平截头体中。通过将这些矩阵相乘,这两个变换可以在位置位置的单个矩阵向量乘法中执行。
    • 完美,这就是我所需要的。我仍然只有一个疑问:为什么我们要检查位置是否在边长为 2 且原点为 [0, 0, 0] 的立方体中?是因为投影矩阵的创建方式,还是始终相同,与矩阵的创建方式无关?
    • 投影矩阵的构造使得任何落在定义的平截头体中的东西都将被转换到立方体空间并包含在立方体中。如果该位置位于截锥体之外,那么它将被转换为立方体之外的位置。它使剪切对象变得简单,并且还使对象根据其 z 坐标正确缩放。
    • 是的,我知道。但是为什么边长是 2,而不是 3?是针对这个特定示例还是始终如此?
    猜你喜欢
    • 2012-06-11
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    相关资源
    最近更新 更多