检查四个点是不是在同一平面上,仅使用距离(验证共线性)

Posted

技术标签:

【中文标题】检查四个点是不是在同一平面上,仅使用距离(验证共线性)【英文标题】:check if four points are on the same plane, only by using distances (verify colinearity)检查四个点是否在同一平面上,仅使用距离(验证共线性) 【发布时间】:2014-03-15 16:50:00 【问题描述】:

有一种称为Cayley-Menger determinant 的方法,如果给定所有成对距离,则可以确定 3 个点是否共线、4 个点是否共面等。

但是,在二维中,有一个非常简单的方法可以确定 3 个点 A,B,C 是否共线:三角不等式!

!(|AB| + |AC| = |BC|) AND !(|AB| + |BC| = |AC|) AND !(|AC| + |BC| = |AB|) IFF A, B, C 不共线

在 3-D 中是否有类似的方法?

【问题讨论】:

不清楚你在问什么。 “我需要一个不使用坐标的解决方案。[...] 我不知道任何坐标或平面/直线方程。” 那么 Cayley-Menger 行列式有什么问题?没有比这更简单的解决方案了。 2D 只是一种极其特殊的情况,您可以用更简单的方式来实现。 那么,为什么 2D 如此特别? 3D有什么问题?我应该怎么做才能将相同的规则应用于 3D? 这个问题似乎跑题了,因为它是关于数学的。 3D、4D 等都没有问题 @cagirici 关于这个话题我还能为你做些什么吗? 【参考方案1】:

是的,三个维度也有类似的公式。


解决方案 1

当且仅当您可以制作的四个三角形的面积之一的面积等于和(或和/差,例如 P1=P2+P3-P4 ) 的 其他三个领域。

Heron 公式指出三角形的面积 Aa, b, c

其中 s = 0.5(a + b + c)。因此,您可以根据距离计算每个区域并测试条件是否成立。


解决方案 2

这四个点在同一平面上当且仅当由这四个点组成的四面体的体积为0。

Heron 公式给出了四面体边的体积,因此您可以仅根据距离进行测试。这是公式的简要推导。

三角等式可以看作是 Heron 公式的一个特例,用于计算 n 的内容 - 从它的 n + 1 维单纯形强>顶点。 n 维单纯形的内容是包含前一个子空间的顶点的“高度”(以任何线性序列取)的 1/n! 倍顶点。想象一下,如何将三角形的底乘以它的高度(1/2)得到三角形的面积,然后将这个面积乘以高度(1/3 >) 的四面体得到它的体积,等等。

请注意,k 维空间中单纯形的任何顶点都可以视为 (k-1) 维基上的“金字塔”的顶点由其他顶点定义。令Vk-1表示基的内容,h表示顶点到包含基的子空间的垂直距离,即内容Vk金字塔的strong>由

给出

因此,将这个公式递归地应用于顶点(以任何顺序),从 k = n 开始,我们有

其中 h1 只是前两个顶点之间的距离,h2 是包含这两个顶点的线以上第三个顶点的高度,h3 是包含前三个顶点的平面上方第四个顶点的高度,依此类推。因此,n 维单纯形的内容是包含以前的顶点。

一般来说,我们可以应用 n 维旋转,将 n-1 个顶点放置到与其中一个轴正交的子空间中。

这将我们引向 Cayley-Menger 行列式,以边长表示三角形的面积

根据边长给出三角形面积的Heron公式

四面体体积的 Heron 公式

如果 UVWuv、w 是四面体边的长度(前三个形成三角形;uU 相对,依此类推),然后

地点:

如果其中一个点位于由其他三个点定义的平面上,则体积为 0,因此分子中的一个因子为 0,这是您可以测试的条件。

Heron's Formula and Brahmagupta's Generalization

Tetrahedron


我已经用 C++ 编写了函数heron_3d。此函数返回 boolean 值,指示 4 个点是否属于同一平面,使用 解决方案 1 中描述的方法:使用 解决方案 1 中描述的方法:将四面体的每个面与其他 3 个面的总和进行比较strong>Heron公式计算每个面积。

#include <cmath>
/**
 * @return area of triangle based on Heron formula
 */
double areaOfTriangle( double edge1, double edge2, double edge3) 
    double s = 0.5 * ( edge1 + edge2 + edge3);
    return std::sqrt( s * ( s - edge1) * ( s - edge2) * ( s - edge3));

/**
 * U, V, W, u, v, w are lengths of edges of the tetrahedron, as in 
 * http://en.wikipedia.org/wiki/Tetrahedron
 * @param U basis edge 1
 * @param V basis edge 2
 * @param W basis edge 3
 * @param u opposite to U
 * @param v opposite to V
 * @param w opposite to W
 * @return 
 */
bool heron_3d( double U, double V, double W,
               double u, double v, double w) 
    double areas[] =  areaOfTriangle( U, V, W),
                       areaOfTriangle( U, v, w),
                       areaOfTriangle( V, u, w),
                       areaOfTriangle( W, u, v);
    for ( int i = 0; i < 4; ++i) 
        double area = areas[ i];
        double sum = 0;
        for ( int j = 1; j < 4; ++j) 
            sum += areas[ (i + j) % 4];
        
        if ( area == sum) return true;
    
    return false;

用法:

int main(int argc, char** argv) 

    bool b0 = heron_3d( 3, 3, 0, 5, 5, 4);  // true
    bool b1 = heron_3d( 3, 3.1, 0.1, 5.1, 5, 4); // false
    bool b2 = heron_3d( 3, 5, 2, std::sqrt( 16 + 25), 5, 4); // true
    return 0;

【讨论】:

我需要一个不使用坐标的解决方案。类似于三角不等式。我不知道任何坐标或平面/直线方程。 @cagirici 现在你有一个简单的方法来测试它。请询问是否仍有不清楚的地方。 这个答案很棒!非常感谢。 这个测试在给定heron_3d(9.8994949366, 12.3288280059, 11.0453610172, 2.8284271247, 8.8317608663, 12.3288280059) 时失败。即使这些点是共面的,结果也是false。为什么会这样?

以上是关于检查四个点是不是在同一平面上,仅使用距离(验证共线性)的主要内容,如果未能解决你的问题,请参考以下文章

判断四个点是否在同一个平面上

四点共面

4点共面

1265 四点共面

1265 四点共面

1265 四点共面