如何使相机适合对象
使用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);