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

时间:2019-06-17 00:35:27

标签: 3d geometry glm-math

所以,这很尴尬,似乎我所有的高中数学技能都消失了。

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

    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
        }
    }

我有点the,有更好的方法,我只需要distanceOnViewAxisdistanceFromViewAxis,就三角学而言,它们是 adjacent 对角线

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

1 个答案:

答案 0 :(得分: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);
}

我绘制了一些图形以显示其背后的数学运算(请注意,在该图形中,我考虑了圆锥体高度的限制,但您似乎并不需要它) The equation in the bottom-right corner is for a point inside the cone to satisfy.