我有一个透视相机,我正在使用它来观察由地球模型组成的3D场景。地球模型是椭圆形的。我想基于模型上的某个边界框来概述这个模型,即基本上我想对这个3D模型进行简单的2D概述。我想为此计算相机距离。
我实际上在开放场景图中这样做,所以我可以得到一个osg :: BoundingBox用于所需的场景/区域。
我使用一种非常简单的方法来计算距离。
distanceVertical = ((boundingBox.yMax - boundingBox.ymin)/2.0)/ tan(fovy/2)
distanceHorizontal = ((boundingBox.xMax - boundingBox.xmin)/2.0)/ tan(fovx/2)
cameraDistance = max(distanceVertical, distanceHorizontal)
这个计算都在世界空间,但不知怎的,它没有给我正确的距离。我在计算这个错误吗?
答案 0 :(得分:0)
请注意,您无法使用宽高比将fovy(您为setProjectionMatrixAsPerspective提供的那个)直接翻译为fovx。这将假设投影是'#34;曲线"但事实并非如此,它与相机保持平坦距离。
有了这些信息,你必须找到另一种方法来计算你的情况下的x大小distanceHorizontal
。
由于您正在使用边界框,因此请注意,只有当摄像机位于与框中心对齐的z时,这才会起作用,因为边界框是轴对齐的。
// Assuming you fetch the aspectRatio and the fovy from the camera...
double aspectRatio = 1.0;
double fovy = degreeToRadian( 45.0 );
{
double fovyDeg;
double zNear; // discarded
double zFar; // discarded
camera->getProjectionMatrixAsPerspective( fovyDeg, aspectRatio, zNear, zFar );
fovy = degreeToRadian( fovyDeg );
}
double halfSizeY = ((boundingBox.yMax - boundingBox.ymin) / 2.0);
double halfSizeX = ((boundingBox.xMax - boundingBox.xmin) / 2.0);
// Prevent a division by 0.
if ( halfSizeX == 0.0 ) halfSizeX = 0.0001;
if ( aspectRatio == 0.0 ) aspectRatio = 0.0001;
double itemSizeRatio = halfSizeY / halfSizeX;
double distanceVertical = halfSizeY / tan(fovy/2);
// The horizontal should be computed from the vertical value, and not from a fovx
double distanceHorizontal = distanceVertical * itemSizeRatio / aspectRatio;
cameraDistance = max(distanceVertical, distanceHorizontal);
我还没有尝试过这个解决方案,但我曾经不得不在这些方面实施一些东西。这种逻辑似乎在纸上起作用。