Since there are two solutions Q on the (TS) line (with only one solution between T and S), any solution probably involves some choice of sign, or arccos(), etc.
Therefore, a good solution is probably to put Q on the (TS) line like so (with vectors implied):
(1) TQ(t) = t * TS
(where O is some origin). Requiring that Q be at a distance d from R gives a 2nd degree equation in t, which is easy to solve (again, vectors are implied):
d^2 = |RQ(t)|^2 = |RT + TQ(t)|^2
The coordinates of Q can then be obtained by putting a solution t0 into equation (1), via OQ(t0) = OT + TQ(t). The solution 0 <= t <= 1 must be chosen, so that Q lies between T and S.
Now, it may happen that the final formula has some simple interpretation in terms of trigonometric functions… Maybe you can tell us what value of t and what coordinates you find with this method and we can look for a simpler formula?
Q 是围绕 R 的半径为 d 的圆与直线 TS 之间的交点,这导致了系数中有多个参数的二次方程。我不知道以下是否是“最佳”解决方案(在两者之间使用数值求解器甚至可能更好),但它已经完全解决了。因为我认为它更具可读性,所以我更改了坐标名称,将 T 放在 (T1, T2),将 S 放在 (S1, S2),为了使公式更短,将 R 放在 (0, 0) – 只需调整 S和 T 以及相应的返回值。
编辑:或者,您也可以通过某种迭代方法(例如牛顿)得到一个很好的近似值,以找到 dist(S+t* (TS), R)-d,作为 [0,1] 中 t 的函数。如果我数正确的话,每牛顿步需要九七次乘法和一次除法。重新使用上面的名称,看起来像这样:
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 确实涉及减法,这将在解决方案附近产生严重的取消问题。
Q is the intersecting point between a circle of radius d around R and the line TS, which leads to a quadratic equation with a number of parameters in the coefficients. I don't know if the following if “the best” solution (it may even be better to use a numerical solver in between), but it is completely worked out. Because I think it's more readable, I've changed your coordinate names to put T at (T1, T2), S at (S1, S2) and, to keep the formulas shorter, R at (0, 0) – just adjust S and T and the returned values accordingly.
Obviously, I take no warranties that I made no typos etc. :-)
EDIT: Alternatively, you could also get a good approximation by some iterative method (say, Newton) to find a zero of dist(S+t*(T-S), R)-d, as a function of t in [0,1]. That would take nine seven multiplications and one division per Newton step, if I count correctly. Re-using the names from above, that would look something like this:
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);
Set eps to control your required accuracy, but do not set it too low – computing f does involve a subtraction that will have serious cancellation problems near the solution.
发布评论
评论(2)
由于 (TS) 线上有两个解 Q(T 和 S 之间只有一个解),任何解都可能涉及某种符号选择,或 arccos() 等。
因此,一个好的解决方案可能是将 Q 放在(TS) 线像这样(隐含向量):(
其中 O 是某个原点)。要求 Q 与 R 的距离为 d,给出 t 中的二阶方程,该方程很容易求解(再次隐含向量):
然后可以通过将解 t0 代入方程(1)来获得 Q 的坐标,通过 OQ(t0) = OT + TQ(t)。必须选择解 0 <= t <= 1,以便 Q 位于 T 和 S 之间。
现在,最终的公式可能会在三角函数方面有一些简单的解释......也许你可以告诉我们什么值t 以及您用此方法找到的坐标是什么,我们可以寻找更简单的公式吗?
Since there are two solutions Q on the (TS) line (with only one solution between T and S), any solution probably involves some choice of sign, or arccos(), etc.
Therefore, a good solution is probably to put Q on the (TS) line like so (with vectors implied):
(where O is some origin). Requiring that Q be at a distance d from R gives a 2nd degree equation in t, which is easy to solve (again, vectors are implied):
The coordinates of Q can then be obtained by putting a solution t0 into equation (1), via OQ(t0) = OT + TQ(t). The solution 0 <= t <= 1 must be chosen, so that Q lies between T and S.
Now, it may happen that the final formula has some simple interpretation in terms of trigonometric functions… Maybe you can tell us what value of t and what coordinates you find with this method and we can look for a simpler formula?
Q 是围绕 R 的半径为 d 的圆与直线 TS 之间的交点,这导致了系数中有多个参数的二次方程。我不知道以下是否是“最佳”解决方案(在两者之间使用数值求解器甚至可能更好),但它已经完全解决了。因为我认为它更具可读性,所以我更改了坐标名称,将 T 放在 (T1, T2),将 S 放在 (S1, S2),为了使公式更短,将 R 放在 (0, 0) – 只需调整 S和 T 以及相应的返回值。
显然,我不保证我没有犯错等。:-)
编辑:或者,您也可以通过某种迭代方法(例如牛顿)得到一个很好的近似值,以找到
dist(S+t* (TS), R)-d
,作为 [0,1] 中 t 的函数。如果我数正确的话,每牛顿步需要九七次乘法和一次除法。重新使用上面的名称,看起来像这样:设置 eps 来控制所需的精度,但不要将其设置得太低 - 计算 f 确实涉及减法,这将在解决方案附近产生严重的取消问题。
Q is the intersecting point between a circle of radius d around R and the line TS, which leads to a quadratic equation with a number of parameters in the coefficients. I don't know if the following if “the best” solution (it may even be better to use a numerical solver in between), but it is completely worked out. Because I think it's more readable, I've changed your coordinate names to put T at (T1, T2), S at (S1, S2) and, to keep the formulas shorter, R at (0, 0) – just adjust S and T and the returned values accordingly.
Obviously, I take no warranties that I made no typos etc. :-)
EDIT: Alternatively, you could also get a good approximation by some iterative method (say, Newton) to find a zero of
dist(S+t*(T-S), R)-d
, as a function of t in [0,1]. That would takenineseven multiplications and one division per Newton step, if I count correctly. Re-using the names from above, that would look something like this:Set eps to control your required accuracy, but do not set it too low – computing f does involve a subtraction that will have serious cancellation problems near the solution.