You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中3D坐标变换问题:绕锚点旋转后坐标计算错误

3D坐标旋转变换修正(Autodesk Inventor 右手坐标系)

需求

计算3D长方体绕对侧锚点(x、y、z轴)旋转后目标点的新坐标,实现装配场景中两个长方体的精准对齐:物体1置于原点,绕锚点旋转后,物体2的原点需与物体1的连接点重合,且二者旋转角度完全一致。

原代码问题

原C#函数因以下问题导致位置计算错误:

  • 旋转过程中直接修改原向量分量,后续旋转使用已被修改的值,造成矩阵运算顺序混乱
  • 错误使用Math.Abs()强制坐标为正,破坏了旋转后的位置偏移关系
  • Y轴旋转的矩阵公式不符合右手坐标系的旋转变换逻辑

原代码:

Vector3 coordinateTransformation(Vector3 vector, float r_x, float r_y, float r_z, Vector3 origin)
{
    vector.X = vector.X;  //Just for demonstration
    vector.Y = vector.Y * Convert.ToSingle(Math.Cos(DegreesToRadians(r_x))) - vector.Z * Convert.ToSingle(Math.Sin(DegreesToRadians(r_x)));
    vector.Z = vector.Y * Convert.ToSingle(Math.Sin(DegreesToRadians(r_x))) + vector.Z * Convert.ToSingle(Math.Cos(DegreesToRadians(r_x)));
    
    vector.X = vector.X * Convert.ToSingle(Math.Cos(DegreesToRadians(r_y))) + vector.Z * Convert.ToSingle(Math.Sin(DegreesToRadians(r_y)));
    vector.Y = vector.Y;  //Just for demonstration
    vector.Z = vector.Z * Convert.ToSingle(Math.Cos(DegreesToRadians(r_y))) - vector.X * Convert.ToSingle(Math.Sin(DegreesToRadians(r_y)));
    
    vector.X = vector.X * Convert.ToSingle(Math.Cos(DegreesToRadians(r_z))) - vector.Y * Convert.ToSingle(Math.Sin(DegreesToRadians(r_z)));
    vector.Y = vector.X * Convert.ToSingle(Math.Sin(DegreesToRadians(r_z))) + vector.Y * Convert.ToSingle(Math.Cos(DegreesToRadians(r_z)));
    vector.Z = vector.Z;  //Just for demonstration

    vector.X = Math.Abs(vector.X) + origin.X;
    vector.Y = Math.Abs(vector.Y) + origin.Y;
    vector.Z = Math.Abs(vector.Z) + origin.Z;
    
    return vector;
}

修正后的代码(匹配标准右手系旋转变换)

以下代码复现标准3D旋转变换逻辑,通过临时变量避免计算干扰,严格遵循Autodesk Inventor右手坐标系规则:

// 辅助函数:角度转弧度
private float DegreesToRadians(float degrees)
{
    return Convert.ToSingle(Math.PI * degrees / 180.0);
}

Vector3 coordinateTransformation(Vector3 vector, float r_x, float r_y, float r_z, Vector3 origin)
{
    // 保存原始向量分量,防止旋转过程中被覆盖导致计算错误
    float x = vector.X;
    float y = vector.Y;
    float z = vector.Z;
    float radX = DegreesToRadians(r_x);
    float radY = DegreesToRadians(r_y);
    float radZ = DegreesToRadians(r_z);

    // 1. 绕X轴旋转(右手系:从X轴正方向看向原点,逆时针为正)
    float y1 = y * Convert.ToSingle(Math.Cos(radX)) - z * Convert.ToSingle(Math.Sin(radX));
    float z1 = y * Convert.ToSingle(Math.Sin(radX)) + z * Convert.ToSingle(Math.Cos(radX));

    // 2. 绕Y轴旋转(右手系:从Y轴正方向看向原点,逆时针为正)
    float x2 = x * Convert.ToSingle(Math.Cos(radY)) + z1 * Convert.ToSingle(Math.Sin(radY));
    float z2 = z1 * Convert.ToSingle(Math.Cos(radY)) - x * Convert.ToSingle(Math.Sin(radY));

    // 3. 绕Z轴旋转(右手系:从Z轴正方向看向原点,逆时针为正)
    float x3 = x2 * Convert.ToSingle(Math.Cos(radZ)) - y1 * Convert.ToSingle(Math.Sin(radZ));
    float y3 = x2 * Convert.ToSingle(Math.Sin(radZ)) + y1 * Convert.ToSingle(Math.Cos(radZ));

    // 平移回锚点坐标系,移除错误的绝对值处理
    Vector3 result = new Vector3();
    result.X = x3 + origin.X;
    result.Y = y3 + origin.Y;
    result.Z = z2 + origin.Z;

    return result;
}

关键修正点

  • 使用临时变量保存每一步旋转结果,避免原向量分量被覆盖导致后续计算偏差
  • 修正Y轴旋转的计算逻辑,匹配右手坐标系的标准旋转矩阵
  • 移除Math.Abs(),保留旋转后的正负偏移量,确保位置计算准确
  • 明确X→Y→Z的旋转顺序,与标准3D变换工具逻辑对齐

内容的提问来源于stack exchange,提问作者John Step

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:10:37