假设我在3d空间中有一个实体,我知道它的位置矢量(x,y,z)及其速度矢量(因此它在空间中的方向)。
从已知点A开始,我希望分两步到达已知点B:
a)沿着具有已知半径R的圆形路径转弯,直到点C
b)从C点直接到最终B点。
速度(标量值)并不重要。速度(矢量)是已知的,所以我猜它应该定义圆所在的平面,与它相切,以及A和B之间的直线......
我想知道如何找到C的坐标(x,y,z)和那里的实体的速度矢量。
答案 0 :(得分:4)
如果我理解正确,您的情况(在包含A,B和 v 的平面中)如下图所示。给出点A和B,矢量 v 和距离 r 。你想找到C点。
好吧,让矢量 w =(-v y ,v x )是垂直于 v <的单位矢量/ strong>即可。然后O = A + r w 。
现在,| C - O | = r 和(C - B)·(C - O)= 0(其中·是点积)。将这些组合起来得到一个二次方程,你可以求解它找到C的两个可能位置。然后选择一个带有正确符号的(C - B)×(C - O)。
(圆圈的中心有第二个选择,O = A - r w ,表示顺时针转动而不是逆时针转动。这为C提供了另一种可能性我猜你必须使用一些启发式方法来决定你喜欢哪一个:也许是最小的∠AOC。)
St0rM在3D中请求帮助(参见注释)。这很简单!包含A,B和 v 的平面具有法向量 n =(A - B)× v 。设你 = n × v 是一个垂直于 n 和 v 的向量,让 w = û( u 方向的单位向量)。
你还需要考虑C与A的相同平面的约束:C· n = A. n 和“右边”符号(C - B)×(C - O)“成为”(C - B)×(C - O)· n 的正确符号。
无法解决这个方程组?
那么,如果(C - B)·(C - O)= 0,那么(C - O + O - B)·(C - O)= 0,因此(C - O)·(C - O )+(O - B)·(C - O)= 0,因此C·(O - B)= O·(O - B) - r 2 。
你会注意到这是一个平面的等式,C· n = A. n 也是如此。将这两个平面相交(see Wikipedia for details - 您可以使用更简单的解决方案,因为平面是正交的并且可以很容易地正交)以获得C所在的线的等式:C = H +λL,例如, L = n ×(B - O)。然后使用(C - O)·(C - O)= r 2 将其转换为λ中的二次方程。你会发现,如果你将线的等式重写为C = H +λL+ O,那么二次方程会简化很多,以便“-O”的出现消失。
这是Python中使用numpy
来执行向量代数的实现。我相信你可以弄清楚如何将它转换成你选择的语言。
import math
from numpy import cross, dot
from numpy.linalg import norm
def unit(v):
"""Return a unit vector in the same direction as v."""
return v / norm(v)
def turnpoints(A, B, v, r):
"""Generate possible turning instructions for a path from A to B
that starts out in direction v, turns through part of a circle of radius
r until it reaches a point C (to be determined), then heads straight for
B. Return each instruction in the form (sense, C) where sense is -1 for
clockwise and +1 for anticlockwise."""
n = unit(cross(A - B, v)) # Unit normal to plane containing A, B, v.
w = unit(cross(n, v)) # Unit normal to v lying in that plane.
for sense in (-1, +1): # Turn clockwise or anticlockwise?
O = A + sense * r * w # Centre of turning circle.
BB = B - O
m = unit(BB)
# C lies on the line H + l*L + O
H = dot(A, n) * n + (r**2 / norm(BB)) * m
L = cross(n, m)
# |C - O| = r**2 gives quadratic eqn in l with coefficients a=1, b=0, c.
c = dot(H, H) - r**2
disc = - 4 * c # Discriminant of quadratic eqn.
if disc < 0:
continue # No tangents (B inside circle).
elif disc == 0: # One tangent (B on circle).
C = H + O
yield (sense, C)
else: # Two tangents (B outside circle)
for sign in (-1, +1):
l = sign * math.sqrt(disc) / 2
C = H + l * L + O
# Only one choice for C is correct (the other involves
# reversing direction).
if dot(cross(C - B, C - O), n) * sense > 0:
yield (sense, C)
答案 1 :(得分:1)
呜,这很有趣。
由此,您应该能够获得C的位置,并且我相当确定,如果实体没有改变速度,则向量应该是从C到B的单位向量乘以原始速度矢量的大小。
任何或所有这些都可能是错误的。我只是在一张纸上乱涂乱画。
答案 2 :(得分:1)
也许这是一个较短的版本。您可以从以下位置计算C:
H = O +(r ^ 2)/ | BB |)* m
C = H + l *(sqrt(r ^ 2 - | HO | ^ 2))//这只是应用Pytagora来找出HC幅度
作为概念证明:
cml::vector3f A( 4, 3, 2);
cml::vector3f B( 1, 5, 0);
cml::vector3f v( 1, 0, 0);
float r = 1.4142;
cml::vector3f n = cml::cross((A-B),v);
n.normalize();
cout << "n: " << n << endl;
cml::vector3f w = cml::cross(n,v);
w.normalize();
cout << "w: " << w << endl;
cml::vector3f O = A + r*w;
cout << "O: " << O << endl;
cml::vector3f m = B-O;
m.normalize();
cout << "m: " << m << endl;
cml::vector3f OB = B - O;
cml::vector3f H = O + m * ( pow(r,2) / OB.length() );
cout << "H: " << H << endl;
cml::vector3f l = cml::cross(m,n);;
l.normalize();
cout << "l: " << l << endl;
cml::vector3f OH = H - O;
cml::vector3f C = H + l * ( sqrt( pow(r,2)-pow(OH.length(),2) ) );
cout << "C: " << C << endl;