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

时间:2014-03-15 16:50:01

标签: c++ algorithm math geometry linear-algebra

有一种方法叫Cayley-Menger determinant,以便找出3个点是共线的,4个点是共面的,只要给出所有成对距离。

然而,在二维中,有一种非常简单的方法来确定3点,{A,B,C}是否共线:三角不等式!

!(|AB| + |AC| = |BC|) AND !(|AB| + |BC| = |AC|) AND !(|AC| + |BC| = |AB|) IFF A,{{ 1}},B不是共线的

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

1 个答案:

答案 0 :(得分:9)

是的,三维有类似的公式。


解决方案1 ​​

  

当且仅当您可以制作的四个三角形中的一个区域的面积等于总和(或总和/差异,例如P1 = P2 + P3-P4)时,这四个点位于同一平面内)的   其他三个领域。

Heron公式表明顶点 a b c 的三角形区域 A 为< / p>

enter image description here

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


解决方案2

  

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

苍鹭公式根据其边缘给出四面体的体积,因此您可以仅根据距离来测试它。以下是该公式的简要推导。

三角形相等只是 Heron 公式的一个特例,用于计算 n - 维单形的内容 n + 1 顶点。 n - 维单形的内容 1 / n!乘以包含前一个子空间的顶点(以任意线性序列取得)的“高度”顶点。想象一下如何将三角形的基础乘以它的高度(以及 1/2 )以获得三角形的面积,然后将该面积乘以高度(并且 1/3 )四面体以获得它的体积,等等。

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

enter image description here

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

enter image description here

其中 h1 只是前两个顶点之间的距离, h2 是包含这两个顶点的线上方第三个顶点的高度, h3 < / strong>是包含前三个顶点的平面上方第四个顶点的高度,依此类推。因此, n - 维单形的内容 1 / n!乘以包含该子空间的子空间上方的顶点(以任何线性序列取得)的“高度”以前的顶点。

通常我们可以应用 n 维旋转,将 n-1 顶点放入与其中一个轴正交的子空间。

这导致我们 Cayley-Menger行列式,就边长而言,三角形区域

enter image description here

根据边长度给出三角形区域的 Heron 公式

enter image description here

四面体体积的苍鹭公式

如果 U V W u v ,< strong> w 是四面体边缘的长度(前三个形成三角形; u U 相反,依此类推),然后

enter image description here

其中:

enter image description here

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

Heron's Formula and Brahmagupta's Generalization

Tetrahedron


我在 C ++ 中编写了函数heron_3d。此函数返回boolean值,指示4个点是否属于同一平面,使用解决方案1 ​​中描述的方法:将四面体的每个面与其他3个面的总和进行比较 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;
}