3D空间向量绕指定轴旋转实现异常,求排查及正确实现方案
问题排查结论
你的代码核心问题出在罗德里格斯旋转公式的前置条件没有满足:罗德里格斯公式要求参与计算的旋转轴必须是单位长度向量,你当前的RotateVector方法直接使用传入的任意长度的轴向量计算叉乘,当轴向量长度不为1时,旋转结果就会出现偏差。
另外你的叉乘运算、旋转点平移逻辑本身没有错误。
修正方案
修改RotateVector方法,在计算前先对旋转轴做归一化处理,注意要复制轴向量后再归一化,避免修改外部传入的原始轴对象:
public Vector3D RotateVector(Vector3D axis, double angle) { // 复制轴向量,避免修改外部原始数据 Vector3D normalizedAxis = new Vector3D(axis.X, axis.Y, axis.Z); normalizedAxis.Normalize(); Vector3D vxp = normalizedAxis.Cross(this); Vector3D vxvxp = normalizedAxis.Cross(vxp); return this + Math.Sin(angle) * vxp + (1 - Math.Cos(angle)) * vxvxp; }
调用示例(对应你给出的输入用例)
// 输入解析:3.0 2.0 4.0 3.141592653 0.0 0.0 0.0 0.0 1.0 0.0 Vector3D source = new Vector3D(3.0, 2.0, 4.0); double angle = 3.141592653; Vector3D pivot = new Vector3D(0.0, 0.0, 0.0); Vector3D axis = new Vector3D(0.0, 1.0, 0.0); Vector3D result = source.RotateAboutPoint(pivot, axis, angle); // 输出result.X、result.Y、result.Z即可得到 -3.0 2.0 -4.0,和示例一致
补充说明
罗德里格斯公式默认的旋转方向遵循右手定则:右手握住旋转轴,大拇指指向轴的正方向,四指环绕的方向为正角度的旋转方向,如果你的业务需求是左手定则旋转,将传入的角度取反即可。
内容的提问来源于stack exchange,提问作者Denys Zhereb
相关产品推荐
相关产品推荐

