航向、俯仰、滚转转方向矩阵:Y/Z轴计算及异常修复求助
解决Heading/Pitch/Roll转方向矩阵的异常及滚转失效问题
问题分析
- 滚转未生效:原代码仅在Z轴的部分分量中错误引入roll参数,未完整执行绕物体前向轴(X轴)的滚转旋转,导致Y、Z轴完全不受滚转影响。
- 俯仰角<-81度异常:原代码的Y、Z轴计算未正确结合三个旋转角的关联关系,当俯仰角接近-90度时,
cos(pitch)趋近于0,错误的向量计算导致矩阵不再满足正交性,引发功能异常。 - 额外问题:原代码Z轴方向错误(指向左侧而非右侧),违反DCS中Z轴为物体右侧的定义。
解决方案
采用航向→俯仰→滚转的欧拉角旋转顺序,依次计算旋转后的正交单位向量:
- 先计算航向(绕世界Y轴)旋转后的基础右侧向量;
- 基于基础向量计算俯仰(绕物体Z轴)旋转后的前向(X)、上向(Y)向量;
- 最后执行滚转(绕物体X轴)旋转,修正上向(Y)和右侧(Z)向量,确保三个向量始终保持正交。
修正后的代码
--[[ get_orientation - 基于航向、俯仰、滚转(角度)生成物体的方向矩阵 @param heading number - 航向(度) @param pitch number - 俯仰(度) @param roll number - 滚转(度) @returns orientation table - 包含三个正交单位向量:x(前向)、y(上向)、z(右侧) ]] local function get_orientation(heading, pitch, roll) local h = math.rad(heading) local p = math.rad(pitch) local r = math.rad(roll) -- 1. 航向旋转(绕世界Y轴)后的基础右侧向量 local z_h = { x = -math.sin(h), y = 0, z = math.cos(h) } -- 2. 俯仰旋转(绕Z_h轴)后的前向(X)、上向(Y)向量 local x_hp = { x = math.cos(h) * math.cos(p), y = math.sin(p), z = math.sin(h) * math.cos(p) } local y_hp = { x = -math.cos(h) * math.sin(p), y = math.cos(p), z = -math.sin(h) * math.sin(p) } -- 3. 滚转旋转(绕X_hp轴),得到最终的上向(Y)、右侧(Z)向量 local cos_r = math.cos(r) local sin_r = math.sin(r) local final_y = { x = y_hp.x * cos_r - z_h.x * sin_r, y = y_hp.y * cos_r - z_h.y * sin_r, z = y_hp.z * cos_r - z_h.z * sin_r } local final_z = { x = y_hp.x * sin_r + z_h.x * cos_r, y = y_hp.y * sin_r + z_h.y * cos_r, z = y_hp.z * sin_r + z_h.z * cos_r } return { x = x_hp, y = final_y, z = final_z } end --[[ get_position_matrix - 生成包含位置和方向的完整位置矩阵 @param lat number - 纬度(度) @param lon number - 经度(度) @param alt number - 高度(米) @param heading number - 航向(度) @param pitch number - 俯仰(度) @param roll number - 滚转(度) @returns position_table table - DCS兼容的位置矩阵格式 ]] local function get_position_matrix(lat, lon, alt, heading, pitch, roll) -- 转换经纬度为DCS米坐标 local x, z = terrain.convertLatLonToMeters(lat, lon) -- 获取方向矩阵 local orientation = get_orientation(heading, pitch, roll) -- 返回符合DCS要求的位置矩阵结构 return { x = orientation.x, y = orientation.y, z = orientation.z, p = { x = x, y = alt, z = z } } end -- 使用示例 local lat = 41.610278 local lon = 41.599444 local heading = 90 local pitch = 25 local roll = 30 -- 可修改此值测试滚转效果 local alt = 100 local position = get_position_matrix(lat, lon, alt, heading, pitch, roll) Export.LoSetCameraPosition(position) local actual = Export.LoGetCameraPosition() return { position = position, actual = actual }
代码要点说明
- 严格遵循欧拉角旋转顺序,确保三个方向向量始终保持正交,避免俯仰角接近±90度时的异常;
- 完整实现滚转旋转逻辑,滚转角度会正确影响上向和右侧向量;
- 修正了原代码中Z轴的方向错误,现在Z轴正确指向物体右侧;
- 封装了
get_position_matrix函数,直接满足接收经纬度、高度、姿态参数生成位置矩阵的需求。
内容的提问来源于stack exchange,提问作者JfrogT
相关产品推荐
相关产品推荐

