计算四面体外心的问题
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;
}
这是目前的结果:
红点应该与四面体的所有点的距离相等,但从图像中可以清楚地看出情况并非如此。
请有人指出我正确的方向。我已经为此奋斗了几个小时。
我解决了!
花了我足够长的时间。
解决方案是转置我制作的矩阵。
或者换句话说:我将向量插入为行而不是列。
这让我感到困惑,因为我认为公式需要将向量作为列插入,因为角落里有一个转置符号。
嗯。我到此结束了。
我正在尝试使用 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;
}
这是目前的结果:
红点应该与四面体的所有点的距离相等,但从图像中可以清楚地看出情况并非如此。
请有人指出我正确的方向。我已经为此奋斗了几个小时。
我解决了!
花了我足够长的时间。
解决方案是转置我制作的矩阵。 或者换句话说:我将向量插入为行而不是列。
这让我感到困惑,因为我认为公式需要将向量作为列插入,因为角落里有一个转置符号。
嗯。我到此结束了。