我如何找到四面体的周界?


9

我正在寻找最小化的方程式,以找到在给定四个3D点的情况下四面体外球面中心坐标半径

我在互联网上发现的内容主要涉及平面3D三角形的外接球面,一些粗略的数学定义或一些非常单一的情况,例如规则四面体。无论如何,我设法找到下面的等式,但我错过了一些东西:

    ->  ->      ->
let d1, d2, and d3 three vectors of any face of the triangle :

    | d1x  d1y  d1z |   | x |   | d1^2 |
2 * | d2x  d2y  d2z | * | y | = | d2^2 |
    | d3x  d3y  d3z |   | z |   | d3^2 |

我在该领域的知识有其局限性,但我认为我可以处理矩阵和向量运算。但是等式的右边部分是每个向量的范数的平方吗?(它们都放入向量中)。该方程式有效吗?只是作家懒散地忘了写| d1 | ^ 2吗?还是定义某些数学属性的常用方法。

PS:这是用于Delaunay三角剖分实现的。该方程式(数字9)在下面的链接中:https : //www2.mps.mpg.de/homes/daly/CSDS/t4h/tetra.htm


4
尝试数学stackexchange。
Majte 2015年

谢谢,我找到了一种计算那里的环绕度的方法!
herme5


3
@ herme5,随时在这里发布您自己的答案,以计算答案。将来可能会有很多人来这里寻找答案,与您分享对他们来说将是宝贵的。发表您自己的答案甚至接受它是完全可以接受的。
蒂姆·霍尔特

2
感谢您的通知@TimHolt。我会做的 !不过,我不确定我是怎么做到的,那是两年多以前了!让我找到并看一下我的旧实现
herme5 '18

Answers:


2

尽管这是一条古老的线索,但我认为后代可以参考一下。公式的来源来自Philip J. Schneider和David H. Eberly的“ 用于计算机图形学几何工具”。根据文本需要注意的事情

四面体V0,V1,V2,V3的顺序使其与规范的(0,0,0),(1,0,0),(0,1,0),(0,0,1)同构)。

据我了解,同构性在几何中使用时可能有几种不同的含义。如果他表示图论是同构的,则以下代码应正确运行,因为任何四面体的拓扑都是相同的(K4,完整的图)。我使用规范顶点的顺序中的各种排列来测试针对Wolfram alpha的函数结果,但结果没有差异。如果顺序证明有问题,建议您在输入此函数后检查由顶点V1,V2,V3形成的三角形的法线,并通过点积检验将这些点视为半空间,以找出如果那个三角形朝向正确的方向。如果不是,那么简单std::swap三角形的任意两个顶点中的一个会颠倒法线的方向,您可以继续。但是就像我说的那样,我发现各种排列没有区别。

这是经过翻译的代码,没有使用矩阵来避免实现上的混淆,这很简单。

void Circumsphere(const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, Vec3* center, float* radius)
{
  //Create the rows of our "unrolled" 3x3 matrix
  Vec3 Row1 = v1 - v0;
  float sqLength1 = length2(Row1);
  Vec3 Row2 = v2 - v0;
  float sqLength2 = length2(Row2);
  Vec3 Row3 = v3 - v0;
  float sqLength3 = length2(Row3);

  //Compute the determinant of said matrix
  const float determinant =   Row1.x * (Row2.y * Row3.z - Row3.y * Row2.z)
                            - Row2.x * (Row1.y * Row3.z - Row3.y * Row1.z)
                            + Row3.x * (Row1.y * Row2.z - Row2.y * Row1.z);

  // Compute the volume of the tetrahedron, and precompute a scalar quantity for re-use in the formula
  const float volume = determinant / 6.f;
  const float iTwelveVolume = 1.f / (volume * 12.f);

  center->x = v0.x + iTwelveVolume * ( ( Row2.y * Row3.z - Row3.y * Row2.z) * sqLength1 - (Row1.y * Row3.z - Row3.y * Row1.z) * sqLength2 + (Row1.y * Row2.z - Row2.y * Row1.z) * sqLength3 );
  center->y = v0.y + iTwelveVolume * (-( Row2.x * Row3.z - Row3.x * Row2.z) * sqLength1 + (Row1.x * Row3.z - Row3.x * Row1.z) * sqLength2 - (Row1.x * Row2.z - Row2.x * Row1.z) * sqLength3 );
  center->z = v0.z + iTwelveVolume * ( ( Row2.x * Row3.y - Row3.x * Row2.y) * sqLength1 - (Row1.x * Row3.y - Row3.x * Row1.y) * sqLength2 + (Row1.x * Row2.y - Row2.x * Row1.y) * sqLength3 );

  //Once we know the center, the radius is clearly the distance to any vertex
  *radius = length(*center - v0);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.