Closed. This question is off-topic。它当前不接受答案。












想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。

7年前关闭。



Improve this question





我需要编写一种可靠的方法来检索以下情况的答案...

给定线段AB和任意点C,我如何在与穿过点C的AB平行的线上找到最接近A的点? (上面提到的可靠是指算法能够找到D,同时允许A,B和C的坐标完全任意且不可预测。我已经遇到了很多解决方案,我无法适应所有可能的情况,可悲的是...)

对于下图中显示的数据,我如何可靠地找到D的x,y坐标?

A = <425, 473>
B = <584, 533>
C = <371, 401>
D = <???, ???>


知道AB和CD是平行的,这显然意味着斜率是相同的。

我尝试了许多不同的公式都无济于事,并且已经为此工作了几周。我很沮丧!

最佳答案

这是一个最小化的问题。

通常,N维空间中两个点(A和B)之间的欧几里得距离为
Dist(A,B)= sqrt((A1-B1)^ 2 + ... +(AN-BN)^ 2)

如果需要找到空间曲线A(t)(在某个N维空间中嵌入的一维对象)与点B之间的最小距离,则需要求解以下方程式:

d Dist(A(t),B) / dt = 0    // (this is straightforward calculus: we're at either a minimum or maximum when the rate of change is 0)


然后针对距离函数测试一组根(t1,t2等),以找出哪一个根的D值最小。



现在找到以y = mx + b形式通过C的平行线的方程式:

m = (Ay - By)/(Ax-Bx)
b = Cy - mCx


让我们以空间曲线形式将其编写为,然后将其插入第1部分的公式中:

Dist(D(t),A) = sqrt((t-Ax)^2 + (m*t+b-Ay)^2)


取我们的导数:

d Dist(D(t),A)/ dt = d sqrt((t-Ax)^2 + (m*t+b-Ay)^2) / dt

= (t + (m^2)*t - Ax + m*b - m*Ay)/sqrt(t^2 + (m^2)t^2 - 2*t*Ax + 2*m*t*b - 2*m*t*Ay + (Ax)^2 + (Ay)^2 + b^2 - 2*b*Ay )
= ((1+m^2)*t - Ax + m*b - m*Ay)/sqrt((1+m^2)*(t^2)  + 2*t*(m*b - Ax - m*Ay) + (Ax)^2 + (Ay)^2 + b^2 - 2*b*Ay )


将此值设置为0并求解t会得到:
t =(Ax-m * b + m * Ay)/(1 + m ^ 2)
作为唯一的根(您可以通过替换回自己并验证是否一切都按需取消来自己检查)。

将t的这个值重新插入到我们的空间曲线中会得到以下结果:
D =

然后,如果您想要用A,B,C表示明确的解,或者如果只想数值解,则可以将其作为三步过程进行计算,然后插入m和b的表达式:

m = (Ay - By)/(Ax-Bx)
b = Cy - mCx
D=<(Ax-m*b+m*Ay)/(1+m^2),b+m*(Ax-m*b+m*Ay)/(1+m^2)>


这对于所有具有平行直线的情况都是有效的。将其实现为数字(而不是解析)代码时,请注意以下几点:如果这些线垂直放置,则计算m =(Ay-By)/(Ax-Bx)将除以0,这将使您的代码不起作用。您可以按以下方式放入安全阀:

if( Ax == Bx) {
    D = <Cx,Ay>
} else {
    // normal calculation here
}


对于认真的数值工作,您可能希望根据公差而不是由于舍入误差和所有有趣的东西(即abs(Ax-Bx)

关于trigonometry - 用任意点找出两条平行线之间的最短距离,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15848421/

10-10 10:02