如何从Python自定义vec3旋转值转换为方向向量?
要实现从旋转角度到方向向量的转换,核心是利用旋转矩阵对初始向前的方向向量((0,1,0))进行依次旋转变换。结合你定义的坐标系(X向右、Y向前、Z向上),我们可以按照「绕Z轴偏航→绕X轴俯仰」的顺序计算(若需要滚转可再添加绕Y轴的旋转),具体逻辑如下:
关键逻辑说明
- 角度转弧度:Python的
math模块三角函数使用弧度,需先将0-360的角度转换为弧度。 - 旋转顺序:
- 先绕Z轴(偏航角,对应
vec3.z)旋转:控制左右转向,改变方向向量的X、Y分量。 - 再绕X轴(俯仰角,对应
vec3.x)旋转:控制上下抬头/低头,改变方向向量的Y、Z分量。 - (可选)绕Y轴(滚转角,对应
vec3.y)旋转:控制左右倾斜,改变X、Z分量,若不需要可暂时忽略。
- 先绕Z轴(偏航角,对应
- 旋转矩阵应用:对初始方向向量
(0,1,0)依次应用各轴的旋转矩阵,得到最终方向向量。
修改后的vec3类代码
import math class vec3: def __init__(self, x: float, y: float, z: float): self.x = x self.y = y self.z = z def rot(self, other): self.x = (self.x + other.x) % 360 self.y = (self.y + other.y) % 360 self.z = (self.z + other.z) % 360 def dir(self): # 将角度转换为弧度 pitch = math.radians(self.x) # 绕X轴的俯仰角(上下) yaw = math.radians(self.z) # 绕Z轴的偏航角(左右) roll = math.radians(self.y) # 绕Y轴的滚转角(倾斜,可选) # 初始方向:Y轴向前 (0, 1, 0) dx, dy, dz = 0.0, 1.0, 0.0 # 第一步:绕Z轴旋转偏航角 new_dx = dx * math.cos(yaw) + dy * math.sin(yaw) new_dy = -dx * math.sin(yaw) + dy * math.cos(yaw) dx, dy = new_dx, new_dy # 第二步:绕X轴旋转俯仰角 new_dy = dy * math.cos(pitch) - dz * math.sin(pitch) new_dz = dy * math.sin(pitch) + dz * math.cos(pitch) dy, dz = new_dy, new_dz # 第三步:绕Y轴旋转滚转角(若不需要可注释) # new_dx = dx * math.cos(roll) + dz * math.sin(roll) # new_dz = -dx * math.sin(roll) + dz * math.cos(roll) # dx, dz = new_dx, new_dz return vec3(dx, dy, dz) # 测试示例 v = vec3(0, 0, 0) print(v.dir().x, v.dir().y, v.dir().z) # 输出: 0.0 1.0 0.0(符合预期) v.rot(vec3(0, 0, 90)) print(v.dir().x, v.dir().y, v.dir().z) # 输出: 1.0 0.0 0.0(符合预期) v.rot(vec3(0, 0, -45)) print(round(v.dir().x, 3), round(v.dir().y, 3), v.dir().z) # 输出: 0.707 0.707 0.0(正确的45度转向)
注意点
- 如果你需要保留绕Y轴的滚转功能,取消第三步的注释即可。
- 方向向量的分量范围会在
[-1, 1]之间,若需要归一化(确保向量长度为1),可以在最后添加归一化步骤:# 归一化方向向量(可选) length = math.sqrt(dx**2 + dy**2 + dz**2) if length > 0: dx /= length dy /= length dz /= length
内容的提问来源于stack exchange,提问作者MirceaKitsune
相关产品推荐
相关产品推荐

