计算四面体外心的问题

Issues calculating circumcenter of a tetrahedron

我正在尝试使用 C# 计算四面体的外心,我正在使用维基百科上提供的公式来完成此操作。

这是我在 C# 中尝试的方法。 似乎计算出的点总是明显错位。 我检查了我的实现,一切似乎都在正确计算。 circumcenter 是 Unity Vector3。

//calculate super tetrahedron
Vector3[] superT = {
    new Vector3(minMaxAvg.x - 2 * deltaMax, minMaxAvg.y - deltaMax    , minMaxAvg.z - deltaMax    ),
    new Vector3(minMaxAvg.x + 2 * deltaMax, minMaxAvg.y - deltaMax    , minMaxAvg.z - deltaMax    ),
    new Vector3(minMaxAvg.x               , minMaxAvg.y + 2 * deltaMax, minMaxAvg.z - deltaMax    ),
    new Vector3(minMaxAvg.x               , minMaxAvg.y               , minMaxAvg.z + 2 * deltaMax)
};

Vector3 v1 = superT[1] - superT[0];
Vector3 v2 = superT[2] - superT[0];
Vector3 v3 = superT[3] - superT[0];
        
Matrix3x3 mA = new Matrix3x3(v1, v2, v3);
float p1Dot = superT[0].Dot(superT[0]);
Vector3 B = new Vector3(superT[1].Dot(superT[1]) - p1Dot, superT[2].Dot(superT[2]) - p1Dot, superT[3].Dot(superT[3]) - p1Dot) * 0.5f;

circumcenter = mA.Invert().MultiplyPoint(B);

我正在使用自定义 Matrix3x3 class:

public class Matrix3x3 {
    public Vector3 c1, c2, c3;

    public Matrix3x3() {
        c1 = new Vector3();
        c2 = new Vector3();
        c3 = new Vector3();
    }

    public Matrix3x3(Vector3 v1, Vector3 v2, Vector3 v3) {
        this.c1 = v1;
        this.c2 = v2;
        this.c3 = v3;
    }

    public Vector3 MultiplyPoint(Vector3 p) {
        Vector3 res = new Vector3();
        res.x = c1.x * p.x + c2.x * p.y + c3.x * p.z;
        res.y = c1.y * p.x + c2.y * p.y + c3.y * p.z;
        res.z = c1.z * p.x + c2.z * p.y + c3.z * p.z;

        return res;
    }

    public Matrix3x3 Invert() {
        Matrix3x3 res = new Matrix3x3();
        float invdet = 1.0f / Determinant();

        res.Set(0, 0, (Get(1, 1) * Get(2, 2) - Get(2, 1) * Get(1, 2)) * invdet);
        res.Set(0, 1, (Get(0, 2) * Get(2, 1) - Get(0, 1) * Get(2, 2)) * invdet);
        res.Set(0, 2, (Get(0, 1) * Get(1, 2) - Get(0, 2) * Get(1, 1)) * invdet);
        res.Set(1, 0, (Get(1, 2) * Get(2, 0) - Get(1, 0) * Get(2, 2)) * invdet);
        res.Set(1, 1, (Get(0, 0) * Get(2, 2) - Get(0, 2) * Get(2, 0)) * invdet);
        res.Set(1, 2, (Get(1, 0) * Get(0, 2) - Get(0, 0) * Get(1, 2)) * invdet);
        res.Set(2, 0, (Get(1, 0) * Get(2, 1) - Get(2, 0) * Get(1, 1)) * invdet);
        res.Set(2, 1, (Get(2, 0) * Get(0, 1) - Get(0, 0) * Get(2, 1)) * invdet);
        res.Set(2, 2, (Get(0, 0) * Get(1, 1) - Get(1, 0) * Get(0, 1)) * invdet);

        return res;
    }

    public float Determinant() {
        return  Get(0, 0) * (Get(1, 1) * Get(2, 2) - Get(2, 1) * Get(1, 2)) -
                Get(0, 1) * (Get(1, 0) * Get(2, 2) - Get(1, 2) * Get(2, 0)) +
                Get(0, 2) * (Get(1, 0) * Get(2, 1) - Get(1, 1) * Get(2, 0));
    }

我有一个小辅助函数可以在 Unity 中计算 Vector3 的点积:

public static float Dot(this Vector3 v, Vector3 other) {
    return v.x * other.x + v.y * other.y + v.z * other.z;
}

这是目前的结果:

红点应该与四面体的所有点的距离相等,但从图像中可以清楚地看出情况并非如此。

请有人指出我正确的方向。我已经为此奋斗了几个小时。

我解决了!

花了我足够长的时间。

解决方案是转置我制作的矩阵。 或者换句话说:我将向量插入为行而不是列。

这让我感到困惑,因为我认为公式需要将向量作为列插入,因为角落里有一个转置符号。

嗯。我到此结束了。