找到应用哪个 vec3 旋转来对齐 2 个三角形

Find which vec3 rotation to apply to align 2 triangles

我有一个情况,我有 2 具尸体,假设其中一具在 T-Pose 中,另一具空闲,手臂向下。 我必须找到你的肘部应用了哪个旋转,例如,匹配第一个 body 的(elbow-to-hand 骨骼)和第二个 body 的(elbow-to-hand 骨骼) . 我考虑过取三个顶点(它们具有几乎相同的网格,所以这不是问题,但我不能使用顶点的法线,因为它们不一样)。

然后事情是,我在第一个 body 上有三个点形成一个三角形,在第二个 body 上有 3 个点形成另一个三角形,我想找到需要对一个点应用哪个旋转三角形匹配另一个。

如果有帮助,我会使用 unity 和 c# 来实现。

编辑:重要!三角形可能不具有相同的尺寸但它们是二维的所以我只需要知道它的旋转

如果我对你的问题理解正确,你需要求出同一个三角形在 2D 中的两个构型之间的变换:{v1,v2,v3} 和 {w1, w2,w3}。我假设你知道顶点对应关系,例如 v1->w1, v2->w2, v3->w3.

您可以执行以下操作: 1. 找到两个配置之间的旋转角度。 2.旋转一个点,例如v1,得到rotatedV1 3. 找到 rotatedV1 和 w1 之间的翻译。

这是代码。为了简单起见,我使用了 WPF struct Vector3D。最终结果是一个标准的double数组,收集了一个4x4的变换矩阵

    static void miniTest() {

        // first triangle 
        Vector3D v1 = new Vector3D();
        Vector3D v2 = new Vector3D(2, 0, 0);
        Vector3D v3 = new Vector3D(2, 3, 0);

        Vector3D w1 = new Vector3D(0,-1, 0);
        Vector3D w2 = new Vector3D(0 , -3, 0);
        Vector3D w3 = new Vector3D(3, -1, 0);


        double[,] transofrmation = getTrMatrix(v1, v2, v3, w1, w2, w3);    

    }

    public static double[,] getTrMatrix(Vector3D V1, Vector3D V2, Vector3D V3, Vector3D W1, Vector3D W2, Vector3D W3) {
        Vector3D s1 = V2 - V1;
        s1.Normalize();

        Vector3D z1 = W2 - W1;
        z1.Normalize();

        double angle = Math.Acos(Vector3D.DotProduct(s1, z1));

        double[,] rotT = new double[,] {
            { Math.Cos(angle), -Math.Sin(angle), 0},
            { Math.Sin(angle), Math.Cos(angle), 0},
            { 0,0,1},
        };

        double[] rotatedV1 = multiply(rotT, V1);

        Vector3D translation = new Vector3D( W1.X - rotatedV1[0], W1.Y - rotatedV1[1], W1.Z - rotatedV1[2]);

        double[,] T = new double[,] {
            { Math.Cos(angle), -Math.Sin(angle), 0, translation.X},
            { Math.Sin(angle), Math.Cos(angle), 0, translation.Y},
            { 0,0,1, translation.Z},
            {0,0,0,1 } };

        return T;
    }


    // apply rotation matrix to vector
    static double[] multiply(double[,] rotMat, Vector3D vec) {

        double[] result = new double[3];

        result[0] = rotMat[0, 0] * vec.X + rotMat[0, 1] * vec.Y + rotMat[0, 2] * vec.Z;
        result[1] = rotMat[1, 0] * vec.X + rotMat[1, 1] * vec.Y + rotMat[1, 2] * vec.Z;
        result[1] = rotMat[2, 0] * vec.X + rotMat[2, 1] * vec.Y + rotMat[2, 2] * vec.Z;
        return result;
    }