Cesium 内置变量 czm_ellipsoidInverseRadii

Cesium 内置变量 czm_ellipsoidInverseRadii

js 复制代码
// 定义: 椭球体沿主轴 (x, y, z) 方向半径的倒数
// 类型: vec3
czm_ellipsoidInverseRadii
js 复制代码
// 实现
ellipsoid._oneOverRadii = new Cartesian3(
  x === 0.0 ? 0.0 : 1.0 / x,
  y === 0.0 ? 0.0 : 1.0 / y,
  z === 0.0 ? 0.0 : 1.0 / z,
);
应用

ellipsoidSurfaceFunction

js 复制代码
// 确定给定点是位于 3D 空间中椭球体表面的表面上、内部还是外部
float ellipsoidSurfaceFunction(vec3 point)
{
  // 归一化, 缩放到单位球上
  vec3 scaled = czm_ellipsoidInverseRadii * point;
  return dot(scaled, scaled) - 1.0;
}

椭球体: 一个以原点为中心、半轴长为 (a)、(b)、© 的椭球体的方程为:
x 2 a 2 + y 2 b 2 + z 2 c 2 = 1 \frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} = 1 a2x2+b2y2+c2z2=1

这里的 a , b , c a,b,c a,b,c是椭球体沿 x , y , z x,y,z x,y,z轴的半轴长度。

单位球体 :单位球体是以原点为中心、半径为 1 的球体,其方程为:
x 2 + y 2 + z 2 = 1 x^2 + y^2 + z^2 = 1 x2+y2+z2=1

归一化的目标是通过坐标变换,将椭球体的方程转换为单位球体的方程。

要将椭球体归一化为单位球体,我们需要对坐标进行缩放,使得椭球体的半轴长度被归一化为 1。具体步骤如下:

定义一个新的坐标系 ( x ′ , y ′ , z ′ ) (x', y', z') (x′,y′,z′),通过以下线性变换将原始坐标 ( x , y , z ) (x, y, z) (x,y,z) 映射到归一化坐标:
x ′ = x a , y ′ = y b , z ′ = z c x' = \frac{x}{a} , \quad y' = \frac{y}{b} , \quad z' = \frac{z}{c} x′=ax,y′=by,z′=cz

这等价于将点 (x, y, z) 乘以一个对角缩放矩阵,其对角元素是椭球体半轴长度的倒数:

x ′ y ′ z ′ \] = \[ 1 / a 0 0 0 1 / b 0 0 0 1 / c \] \[ x y z \] \\begin{bmatrix} x' \\ y' \\ z' \\end{bmatrix} = \\begin{bmatrix} 1/a \& 0 \& 0 \\\\ 0 \& 1/b \& 0 \\\\ 0 \& 0 \& 1/c \\\\ \\end{bmatrix} \\begin{bmatrix} x \\ y \\ z \\end{bmatrix} \[x′ y′ z′\]= 1/a0001/b0001/c \[x y z

代码实现:

js 复制代码
// 实现了上述缩放变换,将输入点 point = (x, y, z) 转换为归一化坐标 scaled = (x', y', z') = (x/a, y/b, z/c)。
vec3 scaled = czm_ellipsoidInverseRadii * point;

因此,通过这种缩放,椭球体的表面被映射到单位球体的表面

js 复制代码
// 计算变换后点的平方欧几里得距离
dot(scaled, scaled)

d o t ( s c a l e d , s c a l e d ) = x ′ 2 + y ′ 2 + z ′ 2 = x 2 a 2 + y 2 b 2 + z 2 c 2 \begin{align} dot(scaled, scaled) &= x'^2 + y'^2 + z'^2 \\ &=\frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} \end{align} dot(scaled,scaled)=x′2+y′2+z′2=a2x2+b2y2+c2z2

f ( x , y , z ) = x 2 a 2 + y 2 b 2 + z 2 c 2 − 1 f(x,y,z) = \frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} - 1 f(x,y,z)=a2x2+b2y2+c2z2−1

  • f ( x , y , z ) = 0 f(x,y,z)=0 f(x,y,z)=0, 原始点在椭球体表面
  • f ( x , y , z ) < 0 f(x,y,z)<0 f(x,y,z)<0, 原始点在椭球体内
  • f ( x , y , z ) > 0 f(x,y,z)>0 f(x,y,z)>0, 原始点在椭球体外

出处

js 复制代码
// 计算点 point 相对于椭球体表面的距离
float cartesianToGeographic(vec3 cartesian)
{
    vec3 inverseRadii = czm_ellipsoidInverseRadii;
    float radiix = 1.0/inverseRadii.x;
    float radiiy = 1.0/inverseRadii.y;
    float radiiz = 1.0/inverseRadii.z;
    float scale = sqrt( 1.0 / (cartesian.x * cartesian.x / (radiix * radiix) + cartesian.y * cartesian.y / (radiiy * radiiy) + cartesian.z * cartesian.z / (radiiz * radiiz)));
    vec3 pos = scale * cartesian;
    float dis = distance(cartesian, pos);
    return dis;
}

类似的功能:

js 复制代码
bool czm_ellipsoidContainsPoint(vec3 ellipsoid_inverseRadii, vec3 point)
{
    vec3 scaled = ellipsoid_inverseRadii * (czm_inverseModelView * vec4(point, 1.0)).xyz;
    return (dot(scaled, scaled) <= 1.0);
}
相关推荐
时间的情敌1 天前
Vue3 + Cesium 实战:本地上传 GLB 模型、模型上叠加 GLB、点击控制透明度
前端·vue.js·cesium
LuHang2 天前
从天地图切换到高德地图:一次真实的底图迁移实战
前端·vue.js·cesium
总要学点什么2 天前
第92篇:三维特效-圆(逐渐消逝)——从圆心开始,让一个洞把整片光啃到只剩外圈
gis·webgl·cesium·空间分析·1024程序员节
总要学点什么3 天前
第89篇:三维特效-螺旋圆效果——让螺旋臂卷起一圈圈外扩的涟漪
开发语言·javascript·ecmascript·webgl·cesium·空间分析·1024程序员节
vjmap3 天前
Cesium + MCP:在 Cursor、Claude Code 里一句话生成地图视频,唯杰 AI 地图动画上线
gis·cesium·mcp
总要学点什么6 天前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
总要学点什么9 天前
第79篇:数据可视化-模拟迁徙效果——把三十条航线画成会飞的弧
3d·信息可视化·数据挖掘·数据分析·gis·webgl·cesium
总要学点什么12 天前
第75篇:右键菜单控件——把一张会做事的菜单钉在鼠标落下的那点
前端·信息可视化·echarts·cesium·空间分析
迷迭绿14 天前
Cesium 轨迹回放播放器
前端·javascript·cesium
总要学点什么17 天前
第65篇:地图卷帘控件——点「关闭卷帘」,消失的却是右边那半张地图
信息可视化·gis·webgl·cesium·空间分析