十分钟分享:如何使相机同时看到n个物体

过年之前领了一个小需求,觉得比较有意思,所以来分享一下。

需求是这样的,在一个threejs场景中有n个点,目前只知道这n个点的坐标位置。求计算一个合适的相机位置和朝向,使用相机刚好能看到它们。「有兴趣的同学可以先思考一下」

首先看一下我们目前的有的信息

  • 点的坐标
  • fov
  • 相机的原始位置、原始朝向点

第一步:可能很多同学都清楚,我们要借助这n个坐标点构建一个大的包围盒。这时候我们就很容易拿到最新的相机朝向点,即包围盒的中心。

第二步:跟着思路走,目前我们需要计算相机的最终位置了,而最终位置肯定是与包围盒有关,应该是在以包围盒中心为球心,以一个非常合适的距离为半径的球面上。

嗯...,那么现在我们最核心的就是思考如何计算这个合适距离。

我们来简化一下,将3d减弱到2d画个图,理想的相机距离应该是这样的

再来简化一下图形,我们只考虑一半

图中直角位置即我们的center,x便是我们此步骤最终要求的那个合适距离。由tan(2/fov) = h/x,可以得知只要知道h,x便也有了。h是什么呢,我们仔细观察一下h越大相机的开角便越大,那么自然就能看到更多的东西。我们这里的需求就是想要看到整个包围盒里面的所有东西,那么自然需要有一个最大的h。再看一图的h可以是矩形的宽高,但宽高不太确定因为我们还需要比较一下,确定最长的我们难道不可以使用对角线么。这毫无疑问最长了吧。「对角线的api工具」

那么x便很容易得出来 x = h / tan(2/fov)

第三步:此时我们需要根据计算出来的距离来计算相机的最终位置了,需求方给到我的是希望最终的朝向和原有的朝向不能发生变化(朝向的方向向量是一致的)

这其实比较简单,因为我们现在已经有了相机的最终朝向坐标(center)和距离x,这时我们只要一点从center位置出发沿着【原相机朝向坐标到原相机位置】的方向走x距离即可

这便一些简单的向量运算了

首先:原相机朝向坐标t到原相机位置p , 即p-t 。向量p减向量t的几何意义即为得到一个新的以t的终点的起点p的终点为重点的新向量。我们进行标准化拿到这个向量的方向向量。最后用这个方向向量*距离x 再加上 center向量就得到了最终的相机位置。

向量*标量:即向量拉长标量倍

向量加法的几何意义:即可以理解为从第一个向量的终点沿着第二个向量的方向走第二个向量的模

完整代码其实就几行,不过挺有意思的

ini 复制代码
    const box = new Box3()

    box.setFromPoints(currentPos.map(item => new Vector3(item[0], item[1], item[2])))

    const center = box.getCenter(new Vector3())
    const size = box.getSize(new Vector3())
    const halfDiagonal = size.length() * 0.5

    const maxDistance = halfDiagonal / Math.tan(this.camera.fov / 2 * Math.PI / 180)
    const cameraToCenterDistance = maxDistance
    const directionVector = (this.camera.position.clone()).sub(this.controls.target).normalize() // 相机指向物体中心的向量

    const lastPosition = directionVector.multiplyScalar(cameraToCenterDistance).add(center)
    const lastLookat = center
相关推荐
AiMan3 小时前
Poe还是不可以导出左侧所有对话,只能单条内容导出,方法不对吗
前端
AiMan4 小时前
文心生成的内容能否下载吗?
前端
前端双越老师4 小时前
程序员 1v1 访谈系列第十四期:接受焦虑 拥抱不确定
前端·ai编程·全栈
deli0075 小时前
MCP 协议 6 条消息拆开看:AI 为什么能自己读文件调接口
前端
风骏时光牛马5 小时前
请告诉我标题对应的内容、想要的风格,我马上给你生成。
前端
deli0076 小时前
OAuth 2.0 授权码流程实测:4 次跳转,少个 state 就被劫持
前端
deli0078 小时前
手机20%突然关机?电量百分比是估的,SOC曲线4组实测
前端
魂断蓝桥66613 小时前
如何用 three.js 把 3D 消防演练落到一栋楼里——第一课:场景搭建与火情定位
webgl·three.js·3d建筑·物联网3d·、3d工厂、3d工业园区、智慧制造、智慧工业、智慧工厂·3d定位、三维室内定位、3d建筑·3d消防
深蓝AI18 小时前
Meta 开源用了八年的设计系统 astryx:连坐两天 GitHub 总榜第一,组件库开始写给 agent 的说明书
前端·人工智能