如何使相机适合对象

使用three.js我有以下几点。

  • 包含多个Object3D实例的场景
  • 几个预定义的相机Vector3的位置
  • 如果屏幕大小调整,canvas的dynamic宽度/高度
  • 用户可以从上面select一个对象
  • 用户可以select一个摄像头位置(从上方)

鉴于一个对象被查看,他们已经select了相机的位置,我如何计算最终的相机位置,以“最适合”屏幕上的对象?

如果摄像头的位置在某些屏幕上“按原样”使用,则在我的视口的边缘stream血,而其他的则显得较小。 我相信有可能将这个物体固定到相机的平截头体上,但是还没有find合适的东西。

我假设你正在使用透视相机。

您可以设置相机的位置,视野或两者。

下面的计算对于一个立方体的物体来说是精确的,所以按照物体的边界框来对待,以面对相机。

如果摄像机居中并正面观看立方体,请定义

dist = distance from the camera to the _closest face_ of the cube 

 height = height of the cube. 

如果您按如下方式设置相机的视野

 fov = 2 * Math.atan( height / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees 

那么立方体高度将与可见高度相匹配。

此时,您可以稍微抬起摄像头,或者增加一些视野。

如果视场是固定的,那么使用上面的公式来求解距离。


编辑:如果你想要立方体width匹配可见宽度 ,让aspect是canvas的宽高比(canvas宽度除以canvas高度),并设置像这样的相机视野

 fov = 2 * Math.atan( ( width / aspect ) / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees 

三.js r.69

基于WestLangleys的答案,这里是如何计算一个固定的相机视野的距离:

 dist = height / 2 / Math.tan(Math.PI * fov / 360); 

要计算放置摄像头以将对象放在屏幕上的距离,可以使用以下公式(使用Javascript):

 // Convert camera fov degrees to radians var fov = camera.fov * ( Math.PI / 180 ); // Calculate the camera distance var distance = Math.abs( objectSize / Math.sin( fov / 2 ) ); 

其中objectSize是对象的高度或宽度。 对于立方体/球体对象,您可以使用高度或宽度。 对于长度或宽度较大的非立方体/非球体对象,请使用var objectSize = Math.max( width, height )来获取较大的值。

请注意,如果您的物体位置不是0, 0, 0需要调整相机位置以包含偏移量。

这里是一个CodePen,展示了这一点。 相关线路:

 var fov = cameraFov * ( Math.PI / 180 ); var objectSize = 0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) ); var cameraPosition = new THREE.Vector3( 0, sphereMesh.position.y + Math.abs( objectSize / Math.sin( fov / 2 ) ), 0 ); 

您可以看到,如果您抓住窗口手柄并resize,则球体仍然占据屏幕高度的100%。 此外,该对象以正弦波方式( 0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) ) ))向上和向下缩放,以显示相机位置考虑对象的比例。

从user151496关于使用宽高比的build议,这似乎工作,虽然我只testing了几个不同的参数集。

 var maxDim = Math.max(w, h); var aspectRatio = w / h; var distance = maxDim/ 2 / aspectRatio / Math.tan(Math.PI * fov / 360);