检查点的正确方法是在 3d 圆锥内

Posted

技术标签:

【中文标题】检查点的正确方法是在 3d 圆锥内【英文标题】:What's the proper way to check a point is within a 3d cone 【发布时间】:2019-06-17 00:35:27 【问题描述】:

所以,这很尴尬,看起来我所有的高中数学技能都已经生锈了。

我费力地整理了一些似乎可以工作的代码,但看着它,我觉得我要么在绕道而行,要么不理解其背后的数学原理。

    glm::vec3 cameraDirection = glm::normalize(camera->lookat - camera->position);
    glm::vec3 cameraViewAxis = camera->position + (cameraDirection * (camera->farPlaneDistance) );          

    for(const auto & obj : scene->objects)
        glm::vec3 point = obj.position;

        glm::vec3 objDirection = glm::normalize(point - camera->position);
        float cosAlpha = glm::dot(objDirection, cameraDirection);

        float distance = glm::distance(camera->position, point);
        float distanceOnViewAxis = distance * cosAlpha;

        glm::vec3 pointOnViewAxis = camera->position + (cameraDirection * distanceOnViewAxis);

        float distanceFromViewAxis = glm::distance(pointOnViewAxis, point);
        float viewRadius = getViewRadius(distanceOnViewAxis); // based on FOV/aspect ratio

        if(distanceFromViewAxis < viewRadius)
            // might be visible
        
    

我觉得有更好的方法可以做到这一点,我只需要distanceOnViewAxisdistanceFromViewAxis,在三角函数中它们是相邻相反 em> 直角三角形的边,我知道角和斜边。

我查看了一些类似的问题,但它们并没有真正帮助我。

【问题讨论】:

见Detect if a cube and a cone intersect each other? 【参考方案1】:

这是一个更简洁的解决方案,同时使用点积和叉积。

bool is_in_cone(const glm::vec3& camera_pos, const glm::vec3& camera_direction, const glm::vec3& object_pos) 
    auto normalized_dir = glm::normalize(camera_direction);
    auto obj_vector = object_pos - camera_pos;
    auto dis_on_view_axis = glm::dot(obj_vector, normalized_dir);
    if (dis_on_view_axis < 0.0f) return false;
    return glm::length(glm::cross(obj_vector, normalized_dir)) <= getViewRadius(dis_on_view_axis);

我画了一些图表来展示这背后的数学原理(请注意,在图表中我考虑了圆锥高度的限制,但您似乎不需要它)

【讨论】:

以上是关于检查点的正确方法是在 3d 圆锥内的主要内容,如果未能解决你的问题,请参考以下文章

鼠标坐标到 3D 世界/投影以进行点碰撞

在圆柱/圆锥上统一生成 3D 点

我是不是正确执行这些步骤来检查用户的应用内结算订阅?

python+selenium+unitest框架断言方法详细教程

Direct3D 9 入门样例程序 圆锥体

如何检查 3d 网格的凸度?