有一种方法叫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中是否有类似的方法?
答案 0 :(得分:9)
是的,三维有类似的公式。
当且仅当您可以制作的四个三角形中的一个区域的面积等于总和(或总和/差异,例如P1 = P2 + P3-P4)时,这四个点位于同一平面内)的 其他三个领域。
Heron公式表明顶点 a , b , c 的三角形区域 A 为< / p>
其中 s = 0.5(a + b + c)。因此,您可以根据距离计算每个区域,并测试条件是否成立。
当且仅当由这四个点组成的四面体的体积为0时,这四个点在同一平面上。
苍鹭公式根据其边缘给出四面体的体积,因此您可以仅根据距离来测试它。以下是该公式的简要推导。
三角形相等只是 Heron 公式的一个特例,用于计算 n - 维单形的内容 n + 1 顶点。 n - 维单形的内容 1 / n!乘以包含前一个子空间的顶点(以任意线性序列取得)的“高度”顶点。想象一下如何将三角形的基础乘以它的高度(以及 1/2 )以获得三角形的面积,然后将该面积乘以高度(并且 1/3 )四面体以获得它的体积,等等。
请注意, k 维空间中单形的任何顶点都可以视为( k-1 ) - 维基上“金字塔”的顶点由其他顶点定义。让 Vk-1 表示基数的内容, h 顶点与包含基数的子空间的垂直距离,内容 Vk 给出了金字塔的强度>
因此,以 k = n 开头递归地将此公式应用于顶点(以任何顺序),我们有
其中 h1 只是前两个顶点之间的距离, h2 是包含这两个顶点的线上方第三个顶点的高度, h3 < / strong>是包含前三个顶点的平面上方第四个顶点的高度,依此类推。因此, n - 维单形的内容 1 / n!乘以包含该子空间的子空间上方的顶点(以任何线性序列取得)的“高度”以前的顶点。
通常我们可以应用 n 维旋转,将 n-1 顶点放入与其中一个轴正交的子空间。
这导致我们 Cayley-Menger行列式,就边长而言,三角形区域
根据边长度给出三角形区域的 Heron 公式
如果 U , V , W , u , v ,< strong> w 是四面体边缘的长度(前三个形成三角形; u 与 U 相反,依此类推),然后
其中:
如果其中一个点位于由其他三个点定义的平面上,则Volume为0,因此分子中的一个因子为0,这是您可以测试的条件。
Heron's Formula and Brahmagupta's Generalization
我在 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;
}