三维空间向量的欧拉角变换计算及Python脚本报错排查
问题分析与修复方案
索引越界错误的核心原因
- 输入文件存在空行、格式错误的行(列数不足4列),导致
line.split()生成的line_data长度小于4,访问line_data[3]时触发索引越界。 - 代码未对输入行做有效性校验,直接按固定列数取值。
代码修复与优化
1. 输入行有效性校验
处理每行前先检查分割后的数据长度,跳过空行和注释行,避免索引越界。
2. 向量归一化处理
计算点积前归一化向量,避免浮点数精度问题导致点积超出acos的定义域[-1,1]。
3. 避免除零异常
针对向量X/Y分量均为0的情况做特殊处理,防止sqrt或atan2触发除零错误。
4. 输出格式修正
原始代码遗漏了输入的X/Y/Z坐标,修复后保留输入4列并新增3列角度数据,符合需求。
修复后的完整代码
import numpy as np import math def calculate_vector_directionality(x, y, z): """计算3D空间中向量的方向性(方位角),单位:度""" if x == 0 and y == 0: return 0.0 # X/Y均为0时方位角定义为0 directionality = math.atan2(y, x) * 180 / math.pi return directionality if directionality >= 0 else directionality + 360 def calculate_angular_transformations(vector, z_axis): """计算将Z轴向量变换为与目标向量平行所需的rotation、tilt、psi角,单位:度""" vec_norm = np.linalg.norm(vector) if vec_norm == 0: return 0.0, 0.0, 0.0 # 零向量返回默认角度 vector_normalized = vector / vec_norm z_axis_normalized = z_axis / np.linalg.norm(z_axis) # 计算rotation角(与Z轴的夹角) dot_product = np.dot(vector_normalized, z_axis_normalized) dot_product = np.clip(dot_product, -1.0, 1.0) # 处理浮点数精度溢出 rotation = math.acos(dot_product) * 180 / math.pi # 计算tilt角(XY平面内的方位角) if vector_normalized[0] == 0 and vector_normalized[1] == 0: tilt = 0.0 else: tilt = math.atan2(vector_normalized[1], vector_normalized[0]) * 180 / math.pi tilt = tilt if tilt >= 0 else tilt + 360 # 计算psi角(与XY平面的夹角) xy_magnitude = math.hypot(vector_normalized[0], vector_normalized[1]) if xy_magnitude == 0: psi = 90.0 if vector_normalized[2] > 0 else -90.0 else: psi = math.atan2(vector_normalized[2], xy_magnitude) * 180 / math.pi return rotation, tilt, psi def main(): try: with open("input.txt", "r") as input_file, open("output.txt", "w") as output_file: # 写入表头(可选) output_file.write("ID,X,Y,Z,DIR,ROTATION,TILT,PSI\n") for line_num, line in enumerate(input_file, 1): line = line.strip() # 跳过空行和注释行 if not line or line.startswith("#"): continue line_data = line.split() # 校验列数 if len(line_data) != 4: print(f"警告:第{line_num}行列数错误,已跳过") continue try: line_id = int(line_data[0]) x = float(line_data[1]) y = float(line_data[2]) z = float(line_data[3]) except ValueError: print(f"警告:第{line_num}行数据类型错误,已跳过") continue vector = np.array([x, y, z]) z_axis = np.array([0, 0, 1]) directionality = calculate_vector_directionality(x, y, z) rotation, tilt, psi = calculate_angular_transformations(vector, z_axis) # 保留原始输入列,新增角度列 output_file.write(f"{line_id},{x:.6f},{y:.6f},{z:.6f},{directionality:.6f},{rotation:.6f},{tilt:.6f},{psi:.6f}\n") except FileNotFoundError: print("错误:未找到input.txt文件") except Exception as e: print(f"发生未知错误:{str(e)}") if __name__ == "__main__": main()
关键修复点说明
- 输入校验:过滤无效行,避免索引越界和类型转换错误。
- 归一化处理:解决点积超出
acos定义域的问题,保证角度计算有效性。 - 异常分支处理:针对零向量、XY分量为零的场景做特殊逻辑,避免运行时错误。
- 输出对齐需求:严格按照“输入基础上新增3列”的要求生成输出文件。
内容的提问来源于stack exchange,提问作者Mrhansenable
相关产品推荐
相关产品推荐

