3D Tiles的4x4的仿射变换矩阵

前言

项目需要,使用Cesium技术,把STL格式模型加载进去。

一、格式转换

第一步,先将STL文件转换为glTF格式

第二步,将glTF文件转换为3D Tiles格式,使用Cesium ion

二、矩阵整体结构

这个矩阵是一个4x4的仿射变换矩阵,用于在3D Tiles中描述模型的位置、旋转和缩放。

复制代码
[
   a,  b,  c,  d, 
   e,  f,  g,  h, 
   i,  j,  k,  l, 
   m,  n,  o,  p
]
  • 第一到第三行前三列表示旋转矩阵

    [
    a, b, c,
    e, f, g,
    i, j, k,
    ]

  • 第四行前三列(m, n, o)表示平移向量,p为齐次坐标的标准形式。

    [
    m, n, o,p
    ]

其实就是它的模型的位置

地心坐标系(ECEF: Earth-Centered, Earth-Fixed): 在这个坐标系中,地球的中心被定义为原点,X、Y、Z 轴固定在地球上并随地球自转。通常,X 轴指向本初子午线和赤道的交点,Y 轴指向90度经度和赤道的交点,Z 轴指向北极。

3D Tiles: 通常包含几何、材质、纹理等信息,使用的是地心坐标系来定义这些信息在地球表面的位置。

具体值替换,通过其他手段获取【模型目标放置位置】的经纬度,再转成地心坐标系ECEF。

三、经纬度转地心坐标系ECEF

将经纬度转换为地心坐标系 (ECEF, Earth-Centered, Earth-Fixed) 坐标系的步骤如下:

1. 了解坐标系

  • 经纬度: 地理坐标系,表示地球表面的位置。由纬度 (latitude, φ)、经度 (longitude, λ) 和高度 (altitude, h) 定义。

    • 纬度 φ: 从赤道向北或向南的角度,范围为 -90°(南极)到 90°(北极)。
    • 经度 λ: 从本初子午线向东或向西的角度,范围为 -180°(西)到 180°(东)。
    • 高度 h: 海拔高度,即点到地球表面的垂直距离。
  • 地心坐标系 (ECEF): 地心为原点,X 轴指向赤道与本初子午线的交点,Y 轴指向赤道与经度 90° 的交点,Z 轴指向北极。

2. 转换公式

要将经纬度 (φ, λ, h) 转换为地心坐标系下的 (X, Y, Z) 坐标,需使用以下公式:

3. 示例代码 (Python)

python 复制代码
import math

def lat_lon_to_ecef(lat, lon, alt):
    # 常量
    a = 6378137.0  # 长半轴 (meters)
    b = 6356752.314245  # 短半轴 (meters)
    e2 = 1 - (b**2 / a**2)  # 离心率平方

    # 将角度转换为弧度
    lat_rad = math.radians(lat)
    lon_rad = math.radians(lon)

    # 计算N
    N = a / math.sqrt(1 - e2 * math.sin(lat_rad)**2)

    # 计算X, Y, Z
    X = (N + alt) * math.cos(lat_rad) * math.cos(lon_rad)
    Y = (N + alt) * math.cos(lat_rad) * math.sin(lon_rad)
    Z = ((1 - e2) * N + alt) * math.sin(lat_rad)

    return X, Y, Z

# 示例
lat = 52.2296756  # 纬度
lon = 21.0122287  # 经度
alt = 100  # 高度 (meters)

x, y, z = lat_lon_to_ecef(lat, lon, alt)
print(f"ECEF坐标: X={x}, Y={y}, Z={z}")

4. 结果解释

  • X, Y, Z 表示点在地心坐标系中的位置。
  • 在地心坐标系中,坐标的单位通常为米 (meters)。

5. 应用场景

  • 地图渲染:将经纬度转换为地心坐标系,用于三维地球模型或地图渲染。
  • 卫星导航:将卫星的经纬度位置转换为地心坐标系,用于定位和跟踪。

通过上述公式和代码,你可以将任何经纬度坐标转换为地心坐标系 (ECEF) 的三维坐标。

四、矩阵详细参数介绍

这个矩阵通常用于3D图形学中进行平移、旋转、缩放和投影变换。以下是该矩阵中每个字母的位置和意义的详细说明:

1. 矩阵形式

原矩阵格式为:

复制代码
[ a, b, c, d ]
[ e, f, g, h ]
[ i, j, k, l ]
[ m, n, o, p ]

2. 每个字母的意义

a. 旋转与缩放部分(3x3部分):
  • a, b, c:第一行描述的是X轴方向的旋转和缩放。
  • e, f, g:第二行描述的是Y轴方向的旋转和缩放。
  • i, j, k:第三行描述的是Z轴方向的旋转和缩放。

具体来说:

  • a, f, k:沿着X、Y、Z轴的缩放因子。

变大变小,比如把加载进来的模型缩小10倍,这三个字母全部 乘 0.1 。剩下懂吧。

  • b, c, e, g, i, j:描述旋转的混合项,表示在X、Y、Z轴之间的旋转关系。

注意!!!!!进行旋转操作前一定要先把缩放因子先全部改为1,旋转完后再改回去!!!

下面是使用Python实现计算3D仿真变换矩阵的代码,可以沿X轴、Y轴或Z轴旋转一个给定角度,并输出对应的旋转矩阵。

python 复制代码
import numpy as np

def rotation_matrix_x(theta):
    """返回绕X轴旋转theta角度的4x4变换矩阵"""
    return np.array([
        [1, 0, 0, 0],
        [0, np.cos(theta), -np.sin(theta), 0],
        [0, np.sin(theta), np.cos(theta), 0],
        [0, 0, 0, 1]
    ])

def rotation_matrix_y(theta):
    """返回绕Y轴旋转theta角度的4x4变换矩阵"""
    return np.array([
        [np.cos(theta), 0, np.sin(theta), 0],
        [0, 1, 0, 0],
        [-np.sin(theta), 0, np.cos(theta), 0],
        [0, 0, 0, 1]
    ])

def rotation_matrix_z(theta):
    """返回绕Z轴旋转theta角度的4x4变换矩阵"""
    return np.array([
        [np.cos(theta), -np.sin(theta), 0, 0],
        [np.sin(theta), np.cos(theta), 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1]
    ])

# 示例:旋转45度(π/4弧度)
theta = np.pi / 4

# 计算沿X轴、Y轴、Z轴旋转的矩阵
R_x = rotation_matrix_x(theta)
R_y = rotation_matrix_y(theta)
R_z = rotation_matrix_z(theta)

print("Rotation matrix around X axis:\n", R_x)
print("Rotation matrix around Y axis:\n", R_y)
print("Rotation matrix around Z axis:\n", R_z)

说明

  1. theta 是旋转角度,以弧度为单位。如果你有角度,可以使用 np.radians(angle_in_degrees) 来转换为弧度。
  2. rotation_matrix_x, rotation_matrix_y, 和 rotation_matrix_z 函数分别计算绕X轴、Y轴、Z轴旋转的4x4变换矩阵。
  3. 输出结果是对应轴旋转后的4x4矩阵。

运行这个代码后,你会得到沿各轴旋转45度的变换矩阵。可以根据需要调整 theta 来得到不同的旋转矩阵。

b. 平移部分(第四列的前三个元素):
  • d, h, l :描述的是物体在X、Y、Z轴上的平移(移动)。
    • d:表示X轴方向的平移。
    • h:表示Y轴方向的平移。
    • l:表示Z轴方向的平移。
c. 齐次坐标部分(第四行):
  • m, n, o:理论上应该是0, 0, 0,表示在平移变换中不涉及旋转或缩放的部分。
  • p:通常为1,表示齐次坐标系统中的一个常数,用于确保矩阵的维度一致性。

3. 简化的理解

  • 旋转a, f, k主要控制旋转的缩放因子,b, c, e, g, i, j控制不同轴之间的旋转关系。
  • 缩放a, f, k也可以控制物体在X、Y、Z轴方向上的缩放比例。
  • 平移d, h, l直接控制物体的移动。单位为米。
  • 齐次性p保证矩阵的齐次特性(通常为1),m, n, o通常为0。

4. 示例应用

  • 如果你只需要一个简单的平移矩阵,a=f=k=1, b=c=e=g=i=j=0, d, h, l分别是X, Y, Z方向的平移量,p为1。
  • 如果你只需要旋转,比如绕Z轴旋转θ角度,那么a=cos(θ), b=-sin(θ), e=sin(θ), f=cos(θ),其余元素为0或1(没有缩放和平移)。

5. 总结

  • a, f, k:控制X、Y、Z方向的缩放。
  • b, c, e, g, i, j:控制不同轴之间的旋转关系。
  • d, h, l:控制X、Y、Z方向的平移。
  • m, n, o:通常是0,表示没有额外的仿射变换。
  • p:通常为1,表示矩阵的齐次性。
相关推荐
a11177612 小时前
中国古建筑瑰宝 3D THreeJS 开源
3d
REDcker14 小时前
Cesium三维WebGIS入门详解
前端·gis·web·cesium·webgis
星云_byto17 小时前
DCDA:双评判器扩散对齐,开放天气LiDAR-4D雷达融合3D检测泛化新范式
3d·扩散模型·3d目标检测·开放天气泛化·lidar-4d雷达融合·鲁棒感知·k-radar
USB_ABC19 小时前
工程级视频矩阵选型技术指南:无缝矩阵切换延迟参数标准与评估要点
线性代数·矩阵·音视频
2401_8595062420 小时前
珠宝玉石加工的智能化改造:AI视觉检测、3D建模与区块链溯源实践
人工智能·3d·视觉检测
a11177621 小时前
3D 建筑编辑器 Pascal Editor THreeJS 开源
前端·3d·html
Frostnova丶21 小时前
(19)LeetCode 54. 螺旋矩阵
算法·leetcode·矩阵
Frostnova丶1 天前
(18)LeetCode 73. 矩阵置零
算法·leetcode·矩阵
易筋紫容1 天前
你手中的魔表,是一道线性代数题
线性代数
a1117761 天前
坦克大战3D Three.js 3D (开源项目)
开发语言·javascript·3d