C# 创建逆旋转矩阵的错误

C# 创建逆旋转矩阵的错误,c#,matrix,rotation,algebra,C#,Matrix,Rotation,Algebra,我需要三角化一个3D多边形(一组有序顶点的平面集合)。为此,我将多边形旋转到X/Z平面中,并对旋转的顶点应用耳朵剪裁算法。在那之后,我将顶点旋转回来,得到一个三角形多边形。 然而,我的轮换似乎有一个错误。 要将多边形旋转到X/Z平面,请执行以下操作: 首先,我取多边形的法向量并从中创建一个逆旋转矩阵 internal static Matrix4 CreateInverseRotationMatrix(Vector3 up) // up is normal vector of polyg

我需要三角化一个3D多边形(一组有序顶点的平面集合)。为此,我将多边形旋转到X/Z平面中,并对旋转的顶点应用耳朵剪裁算法。在那之后,我将顶点旋转回来,得到一个三角形多边形。 然而,我的轮换似乎有一个错误。 要将多边形旋转到X/Z平面,请执行以下操作:

首先,我取多边形的法向量并从中创建一个逆旋转矩阵

    internal static Matrix4 CreateInverseRotationMatrix(Vector3 up) // up is normal vector of polygon
    {
        Vector3 right;
        // take the longer axis and calculate a normal vector
        if (up.X.AbsoluteValue > up.Z.AbsoluteValue)
            right = up.Cross(new Vector3(0, 0, 1));
        else
            right = up.Cross(new Vector3(1, 0, 0));

        // create the third vector of the matrix
        var backward = right.Cross(up);
        // create inverse rotation matrix
        Matrix4<Rational> m = new Matrix4<Rational>(right.X, right.Y, right.Z, 0, up.X, up.Y, up.Z, 0, backward.X, backward.Y, backward.Z, 0, 0, 0, 0, 1);
        return m;
    }
我在Blender中绘制了一个多边形示例。例如,多边形P={(-11),(-0.510.5),(0110),(0.5050),(1000),(1-0.505),(1-1-11)}

旋转多边形PR={(01-4)(0,51-2,5)(11-1)(0,510,5)(0112)(-1112)}


旋转顶点的y分量均为1,因此多边形位于X/Z平面,这是正确的。但是旋转多边形的形状与未旋转多边形的形状明显不同,我不知道为什么。

我忘记了规范化基向量。因此,它应该是:

internal static Matrix4 CreateInverseRotationMatrix(Vector3 up) // up is normal vector of polygon
{
    Vector3 right;
    up = up.Unit();
    // take the longer axis and calculate a normal vector
    if (up.X.AbsoluteValue > up.Z.AbsoluteValue)
        right = up.Cross(new Vector3(0, 0, 1));
    else
        right = up.Cross(new Vector3(1, 0, 0));
    right = right.Unit();
    // create the third vector of the matrix
    var backward = right.Cross(up);
    // create inverse rotation matrix
    Matrix4<Rational> m = new Matrix4<Rational>(right.X, right.Y, right.Z, 0, up.X, up.Y, up.Z, 0, backward.X, backward.Y, backward.Z, 0, 0, 0, 0, 1);
    return m;
}
内部静态矩阵x4 CreateInversionMatrix(Vector3 up)//up是多边形的法向量
{
向量3右;
up=up.Unit();
//取较长的轴并计算法向量
如果(向上X绝对值>向上Z绝对值)
右=向上交叉(新向量3(0,0,1));
其他的
右=向上交叉(新向量3(1,0,0));
右=右。单位();
//创建矩阵的第三个向量
var向后=右交叉(向上);
//创建反向旋转矩阵
Matrix4 m=新的Matrix4(右X,右Y,右Z,0,上X,上Y,上Z,0,向后X,向后Y,向后Z,0,0,0,1);
返回m;
}

我忘记了规范化基向量。因此,它应该是:

internal static Matrix4 CreateInverseRotationMatrix(Vector3 up) // up is normal vector of polygon
{
    Vector3 right;
    up = up.Unit();
    // take the longer axis and calculate a normal vector
    if (up.X.AbsoluteValue > up.Z.AbsoluteValue)
        right = up.Cross(new Vector3(0, 0, 1));
    else
        right = up.Cross(new Vector3(1, 0, 0));
    right = right.Unit();
    // create the third vector of the matrix
    var backward = right.Cross(up);
    // create inverse rotation matrix
    Matrix4<Rational> m = new Matrix4<Rational>(right.X, right.Y, right.Z, 0, up.X, up.Y, up.Z, 0, backward.X, backward.Y, backward.Z, 0, 0, 0, 0, 1);
    return m;
}
内部静态矩阵x4 CreateInversionMatrix(Vector3 up)//up是多边形的法向量
{
向量3右;
up=up.Unit();
//取较长的轴并计算法向量
如果(向上X绝对值>向上Z绝对值)
右=向上交叉(新向量3(0,0,1));
其他的
右=向上交叉(新向量3(1,0,0));
右=右。单位();
//创建矩阵的第三个向量
var向后=右交叉(向上);
//创建反向旋转矩阵
Matrix4 m=新的Matrix4(右X,右Y,右Z,0,上X,上Y,上Z,0,向后X,向后Y,向后Z,0,0,0,1);
返回m;
}

您使用的是点还是点?使用浮点运算的FPoint。Point会将数字舍入为整数,这可能会导致形状的变化。所有类的内部数据类型都是doubleTry:new Vector3m(0.0,0.0,1.0)对不起,Vector3中的“m”是一个拼写错误,我已修复它。你的意思是,不用if/else分支,只写“right=up.Cross(newvector3(0,0,1));”?我试过这个,它真的很有效!也许你能解释一下为什么。你用的是点还是点?使用浮点运算的FPoint。Point会将数字舍入为整数,这可能会导致形状的变化。所有类的内部数据类型都是doubleTry:new Vector3m(0.0,0.0,1.0)对不起,Vector3中的“m”是一个拼写错误,我已修复它。你的意思是,不用if/else分支,只写“right=up.Cross(newvector3(0,0,1));”?我试过这个,它真的很有效!也许你能解释一下原因。
internal static Matrix4 CreateInverseRotationMatrix(Vector3 up) // up is normal vector of polygon
{
    Vector3 right;
    up = up.Unit();
    // take the longer axis and calculate a normal vector
    if (up.X.AbsoluteValue > up.Z.AbsoluteValue)
        right = up.Cross(new Vector3(0, 0, 1));
    else
        right = up.Cross(new Vector3(1, 0, 0));
    right = right.Unit();
    // create the third vector of the matrix
    var backward = right.Cross(up);
    // create inverse rotation matrix
    Matrix4<Rational> m = new Matrix4<Rational>(right.X, right.Y, right.Z, 0, up.X, up.Y, up.Z, 0, backward.X, backward.Y, backward.Z, 0, 0, 0, 0, 1);
    return m;
}