Cesium中用到的图形技术——Computing the horizon occlusion point
译者注:本文翻译自Cesium官方博文《Computing the horizon occlusion point》,by KEVIN RING。
你厌倦了地平线剔除吗? 太好了,我也没有!
上一次,我们解释了地平线剔除是关于什么的,并展示了一种非常有效的方法来测试一个点是否被椭圆体遮挡。然而,我们想要测试遮挡的对象很少是简单的点。特别是,我们希望能够测试地形瓦片是否被椭球体遮挡。但是地形瓦片是由数千个顶点组成的复杂对象。
Deron Ohlarik在上一篇博客文章中谈到了此问题,他解释说,对于任何任意几何图形,我们都可以计算与几何图形有特殊关系的点的位置(我们称为水平遮挡点)。无论观察者从哪个方向接近几何体,该点都会同时或在几何体的任何部分变为可见之前对观察者可见。这正是我们所需要的!但是,如何计算这样的点的许多细节留给读者练习。此外,还不清楚这种方法是否可以推广到椭球而不是球体。该博客旨在填补这两个空白。
再次,这里介绍的技术完全归功于Frank Stoner。
让我们来看看我们的情况。和以前一样,我们通过将每个分量 X、Y和Z乘以沿该轴的椭球半径的倒数,将所有坐标转换到椭球尺度空间。

在此图中,地球以蓝色显示,地形图块以棕色显示。在尺度空间中,地球是一个单位球体。围绕地形图块的边界球的中心显示为点C。边界球不是缩放空间中的球体,但这与我们无关,因为我们将只使用它的中心。
首先,我们任意决定我们的地平线遮挡点将位于这条中心线OC的某个位置,OC是从地球中心到地形图块边界球中心的向量。我们只需要计算它沿该向量的距离。点V是地形图块中的一个顶点。点H是从V的角度看地平线上的一个点。从V的角度看,有无数个地平线点,在单位球面上形成一个圆,但这些地平线点中只有两个点通过V形成一个向量,或与中心线相交。一个显示为实线HP。另一个显示为连接到V为虚线。在虚线上,与中心线的交点出现在点V之前,所以它会比另一个交点更靠近椭球的中心,我们不需要关心它。如果点V是地形图块中的唯一顶点,那么此图中的点P将是我们的地平线遮挡点。对于多个顶点,我们对每个顶点重复 P 的计算,然后选择离椭圆体最远的那个。
那么我们如何计算给定地形瓦片顶点的P点呢?让我们标记下图中的各个角度。

在标记角α和β之后,通过简单的三角形角的知识,我们可以通过他们表达其他的角。
接下来,根据正弦定律:
\]
根据三角函数\(sin(90+θ) = cos(θ)\),有:
\]
\]
β是直角三角形中的角,因此有:
\]
\]
\]
然后,我们使用复合角公式:
\]
\]
我们已经知道如何去计算\(cos(β)\)。同样通过勾股定理,我们能计算\(sin(β)\):
\]
\]
\]
通过点积的定义,我们能够计算\(cos(α)\):
\]
\]
\]
最后,通过矢量叉积的模,我们能够计算\(sin(α)\):
\]
\]
通过以上的计算,我们就能够计算\(OP\)的模了。汇总如下:
\]
\]
\]
\]
\]
请记住,我们通过构造了解\(\hat{OP}\);我们选择它从椭圆体的中心指向地形图块的边界球体的中心。为了计算点P在椭球尺度空间中的位置,我们简单地将方向乘以上面计算的模。由于我们的遮挡测试使用缩放空间中表示的点,因此我们完成了。如果我们还想知道真实、未密封坐标中的位置,我们只需要将位置的每个分量乘以沿相应轴的椭球半径。
下面是 Cesium 中的代码,为了清晰起见略作调整:
function computeMagnitude(ellipsoid, position, scaledSpaceDirectionToPoint) {
var scaledSpacePosition = ellipsoid.transformPositionToScaledSpace(position);
var magnitudeSquared = scaledSpacePosition.magnitudeSquared();
var magnitude = Math.sqrt(magnitudeSquared);
var direction = scaledSpacePosition.divideByScalar(magnitude);
// For the purpose of this computation, points below the ellipsoid
// are considered to be on it instead.
magnitudeSquared = Math.max(1.0, magnitudeSquared);
magnitude = Math.max(1.0, magnitude);
var cosAlpha = direction.dot(scaledSpaceDirectionToPoint);
var sinAlpha = direction.cross(scaledSpaceDirectionToPoint).magnitude();
var cosBeta = 1.0 / magnitude;
var sinBeta = Math.sqrt(magnitudeSquared - 1.0) * cosBeta;
return 1.0 / (cosAlpha * cosBeta - sinAlpha * sinBeta);
}
如您所见,此计算比我们上次描述的用于在地平线上测试该点的计算成本更高。可能可以通过使用前面描述的锥体测试测试每个顶点来优化它,并且如果发现顶点在锥体之外,则仅计算顶点的精确水平遮挡点。我将把它留给读者作为练习。
无论如何,这种计算的成本是它主要只适用于静态几何的主要原因。如果几何体相对于椭球体发生变化,则需要在每次变化时重复此计算。这可能会变得昂贵。
另外,在使用这种方法时,请记住一个重要的警告。在现实世界中,被WGS84椭球遮挡的物体不一定被地球的真实表面遮挡。这是因为地球表面实际上在世界部分地区略低于椭球体。根据您的应用,使用WGS84作为遮挡体积可能是可以接受的,或者您可能需要使用更保守的椭球。
Cesium中用到的图形技术——Computing the horizon occlusion point的更多相关文章
- Web项目开发中用到的缓存技术
在WEB开发中用来应付高流量最有效的办法就是用缓存技术,能有效的提高服务器负载性能,用空间换取时间.缓存一般用来 存储频繁访问的数据 临时存储耗时的计算结果 内存缓存减少磁盘IO 使用缓存的2个主要原 ...
- SQL on Hadoop中用到的主要技术——MPP vs Runtime Framework
转载声明 本文转载自盘点SQL on Hadoop中用到的主要技术,个人觉得该文章对于诸如Impala这样的MPP架构的SQL引擎和Runtime Framework架构的Hive/Spark SQL ...
- Excel催化剂开源第46波-按行列排列多个图形技术要点
此篇对应功能出自:第10波-快速排列工作表图形对象 - 简书 https://www.jianshu.com/p/eab71f2969a6 在Excel的对象模型中,列的宽度不是一般所期待的和行高一样 ...
- vue + cesium开发(4) 绘制图形
在官方例子中每个图形都是一个entity,官方例子提供了显示正方形.圆形.锥形.图片等多种案例! // 初始花 var viewer = new Cesium.Viewer("cesiumC ...
- 盘点SQL on Hadoop中用到的主要技术
转载自:http://sunyi514.github.io/2014/11/15/%E7%9B%98%E7%82%B9sql-on-hadoop%E4%B8%AD%E7%94%A8%E5%88%B0% ...
- 3D游戏图形技术解析(7)——视差映射贴图(Parallax Mapping)【转】
http://www.cnblogs.com/taotaobujue/articles/2781371.html 视差映射贴图(Parallax Mapping) ● 传统纹理贴图的弊端 纹理贴图大家 ...
- ShadowGun 图形技术分析
https://zhuanlan.zhihu.com/p/27966138 ShadowGun虽然是2011年的移动平台的游戏demo,但是里面的很多优化技巧到现在来看都是很值得学习的,毕竟是上过西瓜 ...
- 浅析DirectX11技术带给图形业界的改变(一) 浅析DirectX11技术带给图形业界的改变【转】
浅析DirectX11技术带给图形业界的改变(一) 浅析DirectX11技术带给图形业界的改变 前言:2009年10月23日,微软高调发布了其最新一代操作系统——Windows7,这款操作系统相对于 ...
- HMS Core图形图像技术展现最新功能和应用场景,加速构建数智生活
[2022年7月15日,杭州]HUAWEI Developer Day(华为开发者日,简称HDD)杭州站拉开帷幕.在数字经济不断发展的今天,开发者对图形图像的开发需求更加深入和多样化,从虚拟环境重构到 ...
- OpenGL基础图形编程
一.OpenGL与3D图形世界1.1.OpenGL使人们进入三维图形世界 我们生活在一个充满三维物体的三维世界中,为了使计算机能精确地再现这些物体,我们必须能在三维空间描绘这些物体.我们又生活在一个充 ...
随机推荐
- 基于Java Swing和BouncyCastle的证书生成工具
"Almost no one will remember what he had just not interested." - Nobody "几乎没有人会记得他所丝毫 ...
- ciscn_2019_c_1 题解
main函数如下: int __cdecl main(int argc, const char **argv, const char **envp) { int v4; // [rsp+Ch] [rb ...
- 【Vue3响应式入门#01】Reactivity
专栏分享:vue2源码专栏,vue3源码专栏,vue router源码专栏,玩具项目专栏,硬核推荐 欢迎各位ITer关注点赞收藏 背景 以下是柏成根据Vue3官方课程整理的响应式书面文档 - 第一节, ...
- 对于goland相对较新一些版本新建项目时没有go mod模式选项的坑
前言 对于一些小白在网上看很早的一些go视频,使用goland2020.3.x版本或者其之前版本创建新项目,里面会有GO Modules(vgo)这个选项,也就是gomod模式创建新项目,然而对于现在 ...
- 【pwn】ez_pz_hackover_2016 --pwngdb和pwntools的结合,动态调试
首先checksec 没开nx,说明堆栈可执行,初步考虑需要shellcode,然后拖进ida看主函数逻辑 看chall函数 printf("Yippie, lets crash: %p ...
- 神经网络入门篇:详解计算一个神经网络的输出(Computing a Neural Network's output)
一个神经网络的输出 首先,回顾下只有一个隐藏层的简单两层神经网络结构: 图1.3.1 其中,\(x\)表示输入特征,\(a\)表示每个神经元的输出,\(W\)表示特征的权重,上标表示神经网络的层数(隐 ...
- Transformers 中原生支持的量化方案概述
本文旨在对 transformers 支持的各种量化方案及其优缺点作一个清晰的概述,以助于读者进行方案选择. 目前,量化模型有两个主要的用途: 在较小的设备上进行大模型推理 对量化模型进行适配器微调 ...
- JavaScript高级程序设计笔记09 代理与反射
代理与反射 ES6新增的代理和反射为开发者提供了拦截并向基本操作嵌入额外行为的能力. 具体就是,可以给目标对象定义一个关联的代理对象,而这个代理对象可以作为抽象的目标对象来使用. 在对目标对象的各种操 ...
- hci0 command 0xfc20 tx timeout(Realtek 8761B Chipset, Bluetooth 5.0)
当前使用的Linux内核版本: 4.4.189 插上USB Bluetooth 5.0 Adapter后,dmesg显示如下log: [ 240.348480] usb 3-1.2: new full ...
- Mysql数据库查询之模糊查询
一.什么是模糊查询模糊查询是根据一定的模式匹配规则,查找与指定条件相似或相符的数据.二.模糊查询实操通配符查询1.% 表示任意0个或多个字符形式一: select 查询字段 from 表名 where ...