Python体素光线追踪器方向向量缩放的正确数学方法问询
体素光线追踪器:相机方向向量的正确计算方案
核心问题
你当前的方向向量计算逻辑错误在于,将Y轴旋转的正弦值直接作为dir_y,同时独立计算X/Z方向的分量,没有考虑上下转动(俯仰)对水平方向投影的非线性影响。正确的做法是基于球面坐标转笛卡尔坐标的标准转换公式,确保最终方向向量的模长始终为1,且视角变化无畸变。
正确推导与公式
定义:
- 偏航角(Yaw):对应你的Z轴旋转,绕Y轴转动,控制左右方向,范围0~360°
- 俯仰角(Pitch):对应你的Y轴旋转,绕X轴转动,控制上下方向,范围-90°~90°
转换步骤(弧度制):
- 将角度转为弧度:
yaw_rad = math.radians(yaw_angle) pitch_rad = math.radians(pitch_angle) - 计算俯仰角的余弦值,这是水平分量的缩放因子:
cos_pitch = math.cos(pitch_rad) - 生成最终方向向量:
dir_x = math.sin(yaw_rad) * cos_pitch dir_y = math.sin(pitch_rad) dir_z = math.cos(yaw_rad) * cos_pitch
为什么这个公式有效
因为三角函数的平方和恒等式:(sin(yaw)*cos(pitch))² + sin²(pitch) + (cos(yaw)*cos(pitch))² = cos²(pitch)*(sin²(yaw)+cos²(yaw)) + sin²(pitch) = cos²(pitch) + sin²(pitch) = 1
保证了方向向量的模长始终为1,完全符合3D空间中视线方向的物理逻辑:
- 当俯仰角为0(直视前方),
cos_pitch=1,X/Z分量保持原有的正余弦比例,无缩放 - 当俯仰角接近±90°(抬头/低头到极限),
cos_pitch趋近于0,X/Z分量也趋近于0,符合垂直看时无水平偏移的真实视角
修正后的代码示例
import math pitch_angle = 90 # 对应原问题中的angle_y for yaw_angle in (0, 45, 90, 135, 180, 225, 270, 315, 360): yaw_rad = math.radians(yaw_angle) pitch_rad = math.radians(pitch_angle) cos_pitch = math.cos(pitch_rad) dir_x = math.sin(yaw_rad) * cos_pitch dir_y = math.sin(pitch_rad) dir_z = math.cos(yaw_rad) * cos_pitch print(f"x: {dir_x} y: {dir_y} z: {dir_z}")
测试pitch_angle=90时,所有X/Z分量都会变为0,Y分量为1,完全符合垂直向上看的预期;当pitch_angle=45时,X/Z分量会乘以cos(45°)≈0.707,既保持了水平方向的比例,又保证了总模长正确,不会出现畸变。
之前缩放方法的问题
- 方案1
dir_x * (1 - abs(dir_y)):线性缩放不符合球面投影的非线性特性,导致上下视角时垂直方向出现收缩畸变 - 方案2
dir_x * (1 - abs(dir_y)/2):属于近似调整,初期畸变不明显,但接近极限角度时,因偏离真实的余弦缩放逻辑,会出现凹面镜般的弯曲效果
内容的提问来源于stack exchange,提问作者MirceaKitsune
相关产品推荐
相关产品推荐

