在线段上找到距离另一个点的指定距离的坐标的最佳方法

时间:2011-09-02 06:45:46

标签: math optimization computational-geometry

问题图片:

enter image description here

在我的代码中,我有4分:QRST

我知道以下

  • RTS;
  • 的坐标
  • 该段RT < RQ < RS;
  • 我需要找出Q
  • 的坐标

我已经知道点Q可以在线段TS上找到。但是我需要获取QI的坐标,这需要它是一个相对有效的计算。

对于这个问题,我有几个解决方案,但它们都是如此令人费解,我知道我必须做错事。我确信必须有一种简单优雅的方法来解决这个问题。最好的解决方案是最大限度地减少更密集计算的数量,但这也不会太长。

2 个答案:

答案 0 :(得分:1)

Q是围绕R的半径d的圆与线TS之间的交叉点,这导致具有系数中的多个参数的二次方程。我不知道以下是否是“最好的”解决方案(在它们之间使用数值解算器甚至可能更好),但它完全解决了。因为我认为它更具可读性,所以我改变了坐标名称,将T置于(T1,T2),S置于(S1,S2),为了使公式更短,R为(0,0) - 只需调整S和T以及相应的返回值。

tmp1 = S1^2 - S2*T2 - S1*T1 + S2^2;
tmp2 = sqrt(- S1^2*T2^2 + S1^2*d^2 + 2*S1*S2*T1*T2 - 2*S1*T1*d^2 -
      S2^2*T1^2 + S2^2*d^2 - 2*S2*T2*d^2 + T1^2*d^2 + T2^2*d^2);
tmp3 = S1^2 - 2*S1*T1 + S2^2 - 2*S2*T2 + T1^1 + T2^2;
t = (tmp1 + tmp2)/tmp3;
if (0 > t || t > 1) {
  // pick the other solution instead
  t = (tmp1 - tmp2)/tmp3;
}
Q1 = S1+t*(T1-S1);
Q2 = S2+t*(T2-S2);

显然,我不保证我没有拼写错误等等: - )

编辑:或者,你也可以通过一些迭代方法(比如牛顿)得到一个很好的近似值来找到dist(S+t*(T-S), R)-d的零,作为[0,1]中t的函数。如果我算得正确的话,那将需要 9次七次乘法和每牛顿步骤一次除法。重新使用上面的名称,看起来像这样:

t = 0.5;
d2 = d^2;
S1T1 = S1 - T1;
S2T2 = S2 - T2;
do {
  tS1T1 = S1 - t*S1T1;
  tS2T2 = S2 - t*S2T2;
  f = tS1T1*tS1T1 + tS2T2*tS2T2 - d2;
  fp = 2*(S1T1*tS1T1 + S2T2*tS2T2);
  t = t + f/fp;
} while (f > eps);

设置eps以控制所需的精度,但不要将其设置得太低 - 计算f确实涉及减法,在解决方案附近会出现严重的取消问题。

答案 1 :(得分:0)

由于(TS)线上有两个解决方案Q(T和S之间只有一个解决方案),任何解决方案可能都需要选择符号或arccos()等。

因此,一个好的解决方案可能是将Q放在(TS)线上(如图所示):

(1)   TQ(t) = t * TS

(其中O是某些来源)。要求Q与R的距离d给出t中的二次方程,这很容易解决(同样,也暗示了向量):

d^2 = |RQ(t)|^2 = |RT + TQ(t)|^2
然后,通过将解t0置于等式(1)中,经由OQ(t0)= OT + TQ(t),可以获得Q的坐标。必须选择解0 <= t <= 1,使得Q位于T和S之间。

现在,可能会发生最终公式在三角函数方面有一些简单的解释......也许你可以告诉我们t的值是什么,你用这种方法找到什么坐标,我们可以找一个更简单的公式?