计算从点到线段和线段到线段的平均距离

时间:2010-04-20 01:58:19

标签: math geometry wolfram-mathematica

我正在寻找一种算法来计算3D中一个点和一个线段之间的平均距离。因此,给定代表线段AB的两个点A(x1,y1,z1)和B(x2,y2,z2),以及第三个点C(x3,y3,z3),AB上每个点之间的平均距离是多少指向C?

我也对两个线段之间的平均距离感兴趣。因此,给定AB段和CD段,从AB上的每个点到CD上最近点的平均距离是多少?

我对我尝试的网络搜索没有任何运气,所以任何建议都会受到赞赏。

感谢。

3 个答案:

答案 0 :(得分:2)

首先,两点之间的距离是坐标的成对差的平方和的平方根。 (例如,从(0,0,0)到(1,1,1)的距离是sqrt(3),但这适用于任意数量维度的任意点。) 该距离称为l2-norm(小写L)或欧几里德范数。 为A点和B点之间的距离写出标准(A,B)。

关于平均距离的有趣问题...... (请注意,找到从点到线或线段之间的最小距离是一个更常见的问题。这里有一个答案可以很好地指出这个问题,但似乎它已被删除了其间。)

要找到从点C到线段AB的平均距离,请考虑到A和B之间任意点的距离,即(1-k)A + kB,其中k的范围为0到1。 那是常态(C,(1-k)A + kB)。 所以平均距离是从k = 0到1的范数(C,(1-k)A + kB)的积分。

Mathematica可以为任何特定的A,B和C做积分。

这是一个Mathematica实现:

avgd[A_,B_,C_] :=  Integrate[Sqrt@Dot[(1-k)*A+k*B-C, (1-k)*A+k*B-C], {k, 0, 1}]

也可以写出被委托人Norm[(1-k)*A+k*B-C]。无论哪种方式,Mathematica都可以针对特定点进行操作,但不能象征性地对其进行整合,尽管David显然是以某种方式这样做。 以下是大卫在评论中的例子:

> avgd[{0, 0, 0}, {4, 0, 0}, {4, 3, 0}] // N

3.73594

对于两个线段之间的平均距离问题,理论上我认为这应该有效:

avgd[A_,B_,C_,D_] := Integrate[Norm[(1-k)A+k*B - (1-j)C - j*D], {k,0,1}, {j,0,1}]

但Mathematica似乎甚至在特定点上扼要,更不用说象征性了。

答案 1 :(得分:1)

如果你的意思是我认为你的意思是“平均”(和“距离”,即dreeves提到的L2规范),这是一个我认为应该用来找到平均距离的程序在点和线段之间。你需要一个函数dot(A,B),它取两个向量的点积。

// given vectors (points) A, B, C
K1 = dot(A-C,A-C)
K2 = 2*dot(B-A,A-C)
K3 = dot(B-A,B-A)
L1 = sqrt(K3*(K1+K2+K3))
L2 = sqrt(K3*K1)
N = 4*K3*L1 + 2*K2*(L1-L2) + (K2*K2-4*K1*K3)*log((K2+2*L2)/(2*K3+K2+2*L1))
D = N / (8*K3^1.5)

假设我已正确转录所有内容,D将成为平均距离。

这基本上只是用于评估我在Mathematica中完成的积分结果的伪代码。可能有一些简洁的计算捷径,但如果有,我不知道。 (除非有一个,我会质疑你真正需要做多少计算)

如果要查找从线段CD上最近点到AB上所有点的平均距离,在大多数情况下,最近点将是C或D,因此您可以检查这两个点以查看哪个是更近(可能使用其他答案中引用的一些最小距离计算)。唯一的例外是CD和AB是平行的,你可以从一个到另一个运行垂直,在这种情况下,你必须更精确地定义你的要求。

如果你想找到CD上所有点与AB上所有点之间的平均距离......可以用双积分来完成,但我不禁想到最终公式会有多复杂。

答案 2 :(得分:1)

好吧,如果分析失败,请到达计算机并进行愚蠢的计算,直到您感觉到这些数字......

我也有Mathematica的副本。为了简单起见,因为三角形必须位于一个平面上,所以我在2D空间中进行了以下工作。为了简单起见,我在{0,0}处指定了一个点,并在{1,0}{0,1}指定了一个线段。如果有意义的话,点到线的平均距离必须是可以从{0.0}到线段上任何位置绘制的所有线的平均长度。当然,有很多这样的线,所以让我们从10开始。在Mathematica中,这可能会计算为

Mean[Table[EuclideanDistance[{0, 0}, {1 - k, 0 + k}], {k, 0, 1, 10.0^-1}]]]

给出了0.830255。下一步很明显,让我测量的线数更大。实际上,让我们制作一个平均值表,因为10.0的指数会变小(它们是负数!)。在Mathematica:

Table[Mean[Table[EuclideanDistance[{0, 0}, {1 - k, 0 + k}], {k, 0, 1, 
10.0^-i}]], {i, 0, 6}]

产生:

{1, 0.830255, 0.813494, 0.811801, 0.811631, 0.811615, 0.811613}

按照这种方法,我重新研究了@Dave的例子(忘了第三个维度):

Table[Mean[Table[EuclideanDistance[{0, 0}, {4, 0 + 3 k}], {k, 0, 1, 
10.0^-i}]], {i, 0, 6}]

给出:

{9/2, 4.36354, 4.34991, 4.34854, 4.34841, 4.34839, 4.34839}

这与@dreeves所说的@ Dave的算法计算不一致。

编辑:好的,所以我浪费了更多时间。对于我首先使用的简单示例,即{0,0}处的点和从{0,1}延伸到{1,0}的线段我在Mathematica中定义了一个函数(如有),像这样:

fun2[k_] := EuclideanDistance[{0, 0}, {0 + k, 1 - k}]

现在,这是可以整合的。 Mathematica给出:

   In[13]:= Integrate[fun2[k], {k, 0, 1}]

   Out[13]= 1/4 (2 + Sqrt[2] ArcSinh[1])

或者,如果你想要数字,那么:

In[14]:= NIntegrate[fun2[k], {k, 0, 1}]
Out[14]= 0.811613

这是我之前采用的纯数字方法。

我现在要回去工作了,并把它全部归结为一个由一个点和一个线段的终点定义的任意三角形。