十分钟分享:如何使相机同时看到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
相关推荐
醉城夜风~12 分钟前
CSS盒模型(Box Model)
前端·css
雪隐1 小时前
个人电脑玩AI-15让5060 Ti给你打工——MiniMax H3 本地部署实录:一个自带录音棚的视频模型,和它的 NVFP4 瘦身奇遇
前端·人工智能·后端
GuWenyue1 小时前
不用第三方SDK!Vue3原生Fetch实现DeepSeek流式输出,90%前端都会踩的分片解析坑一次性解决
前端·人工智能·llm
独隅1 小时前
前端离线暂停更新策略:Service Worker 与 PWA 实战指南
前端
不如摸鱼去2 小时前
Wot UI 2.3.0 发布:二维码组件来了,Open Wot 与 wot-starter 同步更新
前端·ui·微信小程序·前端框架·uni-app
Cloud_bread2 小时前
从ReAct到自主闭环:Agentic Coding核心执行引擎的技术演进
前端·react.js·前端框架
cidy_982 小时前
OptMem 使用教程
前端
杉氧2 小时前
用 Compose 挑战交互与动效天花板:ComposeCraftLab 开源实验室全解析
android·前端·kotlin
Canace3 小时前
AI 生成到 90% 突然断了:你的解决方案是?
前端·人工智能
TinssonTai3 小时前
Vite 8 版 Chrome 插件全家桶,popup/options/sidepanel 一次集齐
前端·vue.js