【问题标题】:How to get an hypersphere center point out of 5 surface points?如何从 5 个表面点中获得一个超球面中心点?
【发布时间】:2021-04-21 03:42:05
【问题描述】:

我正在尝试在 4 维空间中实现一个 voronoi 采样器,这应该是一个非常简单的任务,但是选择一个好的起点分布,由于缺乏均匀性,有时会产生一些非常倾斜的 voronoi 单元分布(我接受有关如何生成均匀随机点散射的建议)。

于是我开始研究生成质心voronoi细胞的案例,偶然发现了题目上的问题。我首先假设可以从五个表面点中定义一个 4D 超球面。

我什至得到了一些代码来从 3D 空间中的 三个 点生成一个 3D 球体中心点(在这种情况下,这些点总是在球体的赤道上),我分享了here。我还设法从 四个 表面点中找到了将球体中心作为三维空间中心的代码,但是由于大量矩阵行列式计算,它变得非常大,我承认这有点粉碎了我的希望自己将其扩展到 4D。

我在https://math.stackexchange.com 中找到了很多演示,但这不是我可以轻易转换成代码的东西。

更新更新更新!!!

大家好,我终于有周末了,所以我可以拍一些照片。

首先,我看到了以下 C# (Unity3D) 代码,我可以直观地确认它正在创造奇迹。当所有点共面时,它显然会失败,但这是意料之中的。

static public Vector3 TetrahedronCircumcenter3D(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
{
    Vector3 ba = b - a; //all points from an 'a' point of view
    Vector3 ca = c - a;
    Vector3 da = d - a;
    Vector3 crosscd = Vector3.Cross(ca, da); //perpendicular vectors to those above
    Vector3 crossdb = Vector3.Cross(da, ba);
    Vector3 crossbc = Vector3.Cross(ba, ca);
    return a + (
        (
            ba.sqrMagnitude * crosscd +
            ca.sqrMagnitude * crossdb +
            da.sqrMagnitude * crossbc
        ) *
        (0.5f / (ba.x * crosscd.x + ba.y * crosscd.y + ba.z * crosscd.z)) // half point
    );
}

正如我所说,它在视觉上有效。

我从一个不幸丢失的链接中得到这个,该链接解释了如何从垂直线的交叉点计算单纯形的外心。这两个词很重要,因为这就是我一直在寻找的:“单纯外心”。单纯形是在 R^n 中可以得到的最简单的形状:在 R^2 中是三角形,在 R^3 中是四面体,在 R^4 中是五面体等等。

然后我决定尝试将其扩展为简单地将其扩展到 4D。我首先偶然发现了一个问题,除了 3-D 和(奇怪的)7-D 之外,不能指望两个向量之间存在垂直叉积,我以为我已经完成了。但是一句话给出了下一个线索(这很明显,在有人说之后:你可以从 4-D 中 3 个向量之间的叉积中得到一个垂直的 4-D 向量。搜索公式,我什至发现了一些东西更好:code

扩展该代码以使用 Vector4 是微不足道的。

扩展代码如下所示:

static public Vector4 PentatopeCircumcenter4D(Vector4 a, Vector4 b, Vector4 c, Vector4 d, Vector4 e)
{
    Vector4 ba = b - a; //all points from an 'a' point of view
    Vector4 ca = c - a;
    Vector4 da = d - a;
    Vector4 ea = e - a;
    Vector4 crosscde = CrossProduct(ca, da, ea); //perpendicular vectors
    Vector4 crossdeb = CrossProduct(da, ea, ba);
    Vector4 crossebc = CrossProduct(ea, ba, ca);
    Vector4 crossbcd = CrossProduct(ba, ca, da);
    return a +
        (
            (
                crosscde * ba.sqrMagnitude +
                crossdeb * ca.sqrMagnitude +
                crossebc * da.sqrMagnitude +
                crossbcd * ea.sqrMagnitude
            ) *
            (0.5f / (ba.x * crosscde.x + ba.y * crosscde.y + ba.z * crosscde.z + ba.w * crosscde.w))
        );
}

这引出了下一个问题:如何确认这是有效的?

编辑:这里解释了基本原理:https://ctools.ece.utah.edu/Triangulation/TriangulationSphereCntr.pdf

编辑:它不适用于 4D。从点 a、b、c、d 和 e 到计算中心的距离不一样。 a, b, d 是一致的。点 c 和 e 显示不同的距离。

编辑:在运行时手头没有线性代数求解器,也无法减少其他来源中指定的系统,我不得不走矩阵的道路。代码有点广泛,但没有什么可怕的。路上有一些 5x5 矩阵行列式,但我通过检查所有点与给定中心之间的距离来让它工作,现在看起来很完美。但是,上述暂定解决方案不起作用。

【问题讨论】:

    标签: 3d geometry 4d


    【解决方案1】:

    通过行列式(like (29) here,但有 4 个维度)的超球面方程对于 4D 来说是非常巨大的。

    有一种方法需要计算逆矩阵(过程比较简单,矩阵代数中的标准问题)。

    选择一个点为底X0,制作4个向量V1 = X1 - X0, V2 = X2 - X0 ,以此类推。 计算它们的半长

    L1 = V1.norm / 2 ...
    

    获取归一化(单位)向量:

    U1 = V1 / (2*L1) ...
    

    求解方程得到半径矢量R(从X0到超球体中心)

     | R.x |     |  U1.x  U1.y  U1.z  U1.w |               | L1 |
     | R.y |     |  U2.x  U2.y  U2.z  U2.w |.Inversed *    | L2 |
     | R.z |  =  |  U3.x  U3.y  U3.z  U3.w |               | L3 |
     | R.w |     |  U4.x  U4.y  U4.z  U4.w |               | L4 |
    

    超球心是

     C = X0 + R
    

    here 描述了这个等式的基本原理

    它使用半径向量到 V 向量的投影,就像在三角形外接圆的 2D 情况下中垂线的方法

    【讨论】:

    • 您好!感谢你的回答。我用一些进一步的发展更新了这个问题。似乎我发现了一些可以利用你所展示的理由的东西。
    • @Fernando D'Andrea 我没有足够的数学想象力来直观地控制 4D 的正确性:)。但是您可以检查从源点到结果球体中心的距离
    猜你喜欢
    • 2011-09-17
    • 2021-10-08
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多