检查点在 3d 锥体内的正确方法是什么
What's the proper way to check a point is within a 3d cone
所以,这很尴尬,看起来我所有的高中数学技能都生锈了。
我费力地整理了一些似乎有效的代码,但看着它,我觉得我要么在迂回地做这件事,要么不理解它背后的数学原理。
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
}
}
我一直觉得有更好的方法可以做到这一点,我只需要 distanceOnViewAxis
和 distanceFromViewAxis
,用三角函数术语来说就是 相邻的 [=23] =]和直角三角形的对边,我知道角和斜边。
我看过几个类似的问题,但它们并没有真正帮助我。
这里有一个更简洁的解决方案,同时使用点积和叉积。
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);
}
我画了一些图表来展示这背后的数学原理(请注意,在图表中我考虑了锥体高度的限制,但你似乎不需要它)
所以,这很尴尬,看起来我所有的高中数学技能都生锈了。
我费力地整理了一些似乎有效的代码,但看着它,我觉得我要么在迂回地做这件事,要么不理解它背后的数学原理。
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
}
}
我一直觉得有更好的方法可以做到这一点,我只需要 distanceOnViewAxis
和 distanceFromViewAxis
,用三角函数术语来说就是 相邻的 [=23] =]和直角三角形的对边,我知道角和斜边。
我看过几个类似的问题,但它们并没有真正帮助我。
这里有一个更简洁的解决方案,同时使用点积和叉积。
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);
}
我画了一些图表来展示这背后的数学原理(请注意,在图表中我考虑了锥体高度的限制,但你似乎不需要它)