十分钟分享:如何使相机同时看到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
相关推荐
ZC跨境爬虫3 分钟前
跟着 MDN 学 HTML day_30:(AbortController 实现可取消的异步请求)
前端·ui·html·edge浏览器·媒体
前端若水10 分钟前
选择器的威力 —— :has()、@layer、原生嵌套
前端·css·css3
nashane12 分钟前
HarmonyOS 6学习:Web组件本地资源跨域访问全解析与实战
前端·学习·harmonyos·harmonyos 5
小陈同学,,18 分钟前
地图第一次进来慢的问题二
前端
万少29 分钟前
公测期 0 元/月!商汤 SenseNova 免费 Token 再不领就没了
前端·javascript·后端
Hello--_--World31 分钟前
Webpack:Webpack 核心配置、什么是 Loader? 什么是plugin?webpack 构建流程
前端·webpack·node.js
优联前端32 分钟前
什么是 GEO?SEO对比GEO,如何做好 GEO?怎么验证 GEO 效果?
前端·人工智能·用户体验·geo·seo优化·优联前端
时间不早了sss33 分钟前
Python处理文档
开发语言·前端·python
Json____34 分钟前
前端入门练习题集-HTML/CSS/JS实战小项目15个
前端·css·html
科研小白_38 分钟前
【第二期:MATLAB点云处理基础】KD树与点云邻域搜索
java·前端·人工智能