当前位置: 首页 > 知识库问答 >
问题:

世界坐标下z_far平面顶点的计算。

桂宏旷
2023-03-14

我正在为我的计算机科学学位的顶点项目工作,我很难弄清楚如何做到标题所说的那样。只要假设摄像机在原点向下看--在gl坐标中的z(或在世界坐标中的正z),我的投影矩阵是基于16x9的纵横比和40度垂直视场。zfar为1000,znear为1。

我从两个不同的角度探讨了这个问题。我试着通过矩阵数学和三角法来计算它。然而,到目前为止,这两种方法都不适合我。

我的第一个本能,是取我的投影矩阵,求矩阵的逆,而不是乘以构成zfar平面的齐次坐标。例如:

vec4(-1.0,1.0,-1.0,1.0) * inverse_projection// calculates top left vertex of z_far plane in world coords etc..

下面的代码说明了我的意思。理论上,将{-1,1,-1}乘以逆投影矩阵后,得到的向量的z坐标应该是1000,因为这是在构造投影矩阵时使用的zfar。

glm::vec4 pp  = glm::vec4(-1, 1, -1, 1.0);


printf("zfar[0] = %.2f, %.2f, %.2f, %.2f\n", pp.x, pp.y, pp.z, pp.w);
pp = pp * inverse_projection;
printf("zfar[0] * inverse_projection = %.2f, %.2f, %.2f,  w=%.2f\n", pp.x/pp.w  ,pp.y/pp.w  ,pp.z/pp.w ,pp.w);
pp = pp * projection;
printf("zfar[0] * projection = %.2f, %.2f, %.2f,  w=%.2f\n",  pp.x/pp.w  ,pp.y/pp.w  ,pp.z/pp.w ,pp.w);

产出:

zfar[0] = -1.00, 1.00, -1.00, 1.00
zfar[0] * inverse_projection = -0.21, 0.12, -0.33,  w=1.50
zfar[0] * projection = -1.00, 1.00, -1.00,  w=1.00
void test_getFrustumInWorld( double height, double width, double v_fov, double z_near, double z_far, glm::mat4 projection)
{
    //height and width refer to height and width of screen
    glm::vec4 z_far_world[4];
    double z_far_height = (tan(v_fov/2)*z_far)*2;
    double aspect_ratio = height/width; //how many heights there are in one width
    double z_far_width = z_far_height * aspect_ratio;

    double zf_right = z_far_width/2.0;
    double zf_top = z_far_height/2.0;

    z_far_world[0] = glm::vec4(-zf_right, zf_top, 1000.0, 1.0);
    z_far_world[1] = glm::vec4(-zf_right,-zf_top, 1000.0, 1.0);
    z_far_world[2] = glm::vec4( zf_right,-zf_top, 1000.0, 1.0);
    z_far_world[3] = glm::vec4( zf_right, zf_top, 1000.0, 1.0);



    for(int i=0; i< 4; i++)
    {
        double w = z_far_world[i].w;
        printf("z_far_world[%d] = {%.2f, %.2f, %.2f, w=%.2f}\n",i,z_far_world[i].x/w,  z_far_world[i].y/w,  z_far_world[i].z/w,  z_far_world[i].w);

    }

    printf("\nprojected:\n");
    for(int i=0; i< 4; i++)
    {
        z_far_world[i] = z_far_world[i] * projection;
        double w = z_far_world[i].w;
        printf("z_far_world[%d] = {%.2f, %.2f, %.2f, w=%.2f}\n",i,z_far_world[i].x/w,  z_far_world[i].y/w,  z_far_world[i].z/w,  z_far_world[i].w);

    }
}
z_far_world[0] = {-1258.40, 2237.16, 1000.00, w=1.00}
z_far_world[1] = {-1258.40, -2237.16, 1000.00, w=1.00}
z_far_world[2] = {1258.40, -2237.16, 1000.00, w=1.00}
z_far_world[3] = {1258.40, 2237.16, 1000.00, w=1.00}

projected:
z_far_world[0] = {0.16, -0.50, 0.50, w=-2002.00}
z_far_world[1] = {0.16, 0.50, 0.50, w=-2002.00}
z_far_world[2] = {-0.16, 0.50, 0.50, w=-2002.00}
z_far_world[3] = {-0.16, -0.50, 0.50, w=-2002.00}

我哪里出错了?我是不是误会什么了?我完全卡住了。

共有1个答案

吴缪文
2023-03-14

在您的glm代码中,存在两个主要问题:

glm假设(至少对于矩阵运算)我们使用的是列向量。这意味着,默认的操作顺序是m*t。如果要使用t*M形式的行向量和操作,则必须转换M才能正确工作。

一个投影的Z坐标-1.0不在远平面上,而是在近平面上。此外,OpenGL期望(默认情况下)值在距离更远时更大。所以如果你想要远平面上的点,那么它的z坐标必须是1.0。

 类似资料:
  • 通过前两节课的学习,想必你已经对Threejs的层级模型有了一定认识,那么本节课就在层级模型概念的基础上,继续给家讲解两个新的概念,即本地坐标系和世界坐标系。 如果你对本地坐标系和世界坐标系已经有了一定概念,那么可以直接访问模型的位置属性.position获得模型在本地坐标系或者说模型坐标系下的三维坐标,通过模型的.getWorldPosition()方法获得该模型在世界坐标下的三维坐标。 .ge

  • 想象一个笛卡尔平面,每个细胞对象代表平面中的一个点(该平面将是迷宫)。在构建迷宫时,我想弄清楚一个单元格对象是一个顶点(四个角点)还是一个边界点(任何在迷宫边缘的单元格,顶点也是边界点)。 我需要知道,以便我可以添加相邻单元格作为特定单元格的邻居(我正在创建一个带有节点的图结构)。不同的边框对什么单元格是邻居有不同的要求(例如,右上的顶点不能有y+1或x+1的邻居,因为它在迷宫之外,而左下的顶点不

  • 我正在进行一个处理项目,需要能够确定鼠标是否在圆内。因此,我需要获得圆的位置和鼠标的位置。但是,圆的位置已使用矩阵函数进行了修改,如和。例如: 在处理中有什么方法可以做到这一点吗?我在看留档,但似乎找不到任何功能。如果没有,我如何实现我的目标? 谢谢。

  • 我使用的是平顶六边形网格(按照这里列出的手册http://www.redblobgames.com/grids/hexagons/)。 当然,在平顶的情况下,x坐标可以用作x像素坐标。因此,从立方体坐标计算X像素坐标相对容易。假设是十六进制的总宽度,是x、y、z坐标数组,则x像素坐标为: 我不知道如何计算y像素坐标。相邻HEX之间的高度应不足等于。但是如何基于立方体坐标计算偏移量呢?

  • 本文向大家介绍Cocos2d-x学习笔记之世界坐标系、本地坐标系、opengl坐标系、屏幕坐标系,包括了Cocos2d-x学习笔记之世界坐标系、本地坐标系、opengl坐标系、屏幕坐标系的使用技巧和注意事项,需要的朋友参考一下  cocos2d-x的坐标系很重要,想要学好该引擎,深入理解它的坐标体系很重要。注释写的很清楚了,对照上运行结果一块来看代码吧!

  • 我有一个校准的摄像机(固有矩阵和失真系数),我想知道摄像机的位置知道一些3D点和他们在图像中的对应点(2D点)。 我知道可以帮助我,读完这个和这个之后,我明白了solvePnP和的输出是物体在相机坐标系中的旋转和平移。 所以我需要找出世界坐标系中的相机旋转/平移。 我不知道Python/Numpy(我使用的是C++),但这对我来说没有多大意义: 从solvePnP输出的RVEC、tvec是3x1矩