我有一个由两个向量组成的线段,比如说v1和v2,一个向量v3和一个角度 a 。我如何在Java中编写方法(我也使用Apache Commons Math来表示向量)这给了我一个向量v4,这样线段v1-v2和v3- v4处于角度 a ?有无限的v4元素,如果我可以给该方法一个大小以便线段v3-v4具有该大小,那就更好了。 (全部在2d空间,角度可以是弧度或度数,无关紧要)
编辑按照承诺,我已经包含了我正在尝试解决的问题的图像。我有一个由2个向量定义的线段(线条有点长但无关紧要),角度和第三个点。我需要绘制第二条线,它与第一条线相交,角度为 a 。由于Javafx中的所有行(我在这里使用)是通过定义两个点来绘制的,所以我需要找到红点(或任何可能的点)。
编辑:使用Ali的答案,我得到了以下方法,可以满足我的需求:
public Pair<Vector2D, Vector2D> calculateFourthPoint(Vector2D v1, Vector2D v2, Vector2D v3, double angleInDegrees) {
Vector2D r = v1.subtract(v2);
double rx = r.getX();
double ry = r.getY();
double angle = toRadians(angleInDegrees);
double a = pow(rx, 2) + pow(ry, 2);
double b = 2 * sqrt(pow(rx, 2) + pow(ry, 2)) * cos(angle) * rx;
double c = pow(rx, 2) * pow(cos(angle), 2) + pow(ry, 2) * pow(cos(angle), 2) - pow(ry, 2);
double discriminant = sqrt(pow(b, 2) - (4 * a * c));
double sx1 = (-b + discriminant) / (2 * a);
double sx2 = (-b - discriminant) / (2 * a);
double sy1 = sqrt(1 - pow(sx1, 2));
double sy2 = sqrt(1 - pow(sx2, 2));
Vector2D s1 = new Vector2D(sx1, sy1);
Vector2D s2 = new Vector2D(sx2, sy2);
Vector2D v4_1 = v3.subtract(s1);
Vector2D v4_2 = v3.subtract(s2);
return new Pair<Vector2D, Vector2D>(v4_1, v4_2);
}
答案 0 :(得分:2)
我不知道Apache Commons Math,所以我用伪代码编写。让vx
和vy
分别表示向量x
的{{1}}和y
组件。
允许v
和r=v1-v2
。您有2个未知数(即s=v3-v4
和sx
;以及sy
),因此您需要2个方程式。这些应该是:
v4=v3-s
要拼写出来,上面的等式是:
dot_product(r,s)=length(r)*cos a // forces the desired angle
dot_product(s,s)=1 // just sets the length of s to 1
(1) rx*sx + ry*sy = sqrt(rx^2+ry^2)*cos a
(2) sx^2 + sy^2 = 1
和sx
中的第一个等式是线性的。让我们从第一个等式中消除sy
(假设sy
不为零)
ry
并将此 sy = (1/ry)*(sqrt(rx^2+ry^2)*cos a - rx*sx)
替换为第二个等式。你得到sy
中的二次方程(我不想在这里写它,因为它很复杂)并且有2个解。您可以通过将sy
值替换为(假设sx
不为零)来获得相应的sy
:
rx
最后, sx = (1/rx)*(sqrt(rx^2+ry^2)*cos a - ry*sy).
。 你得到2个v4解决方案,一个用于二次方程的每个解。 (在我的回答中,将忽略例如v4=v3-s
为空向量的退化情况。)
答案 1 :(得分:2)
羞耻我们不能在这里做LaTeX风格的方程式(或可以我们?我不知道,从未在这里做过......),但是这里有:
v1-v2 · v3-v4 = |v1-v2| * |v3-v4| * cos(a) (by definition)
将|v3-v4|
定义为单位向量,以便
v1-v2 · v3-v4 = |v1-v2|*1*cos(a) = |v1-v2|*cos(a)
左手边工作
v1·v4 + v2·v4 = |v1-v2|*cos(a) - v1·v3 + v2·v3
或
(v1+v2)·v4 = |v1-v2|*cos(a) - (v1-v2)·v3
,而
|v3-v4| = (v3-v4)·(v3-v4) = 1
因此,2个未知数中有2个方程。现在,为了简洁起见,
aa = (v1+v2|x
bb = (v1+v2|y
x1 = v4|x
x2 = v4|y
A = |v1-v2|*cos(a) - (v1-v2)·v3
其中|x
表示x
- 组件等。有了这个,琐碎的替换给了我们
( (A-aa*x1)/bb )^2 + (aa*x1)^2 = 1 (-> 2 solutions)
( (A-bb*x2)/aa )^2 + (bb*x2)^2 = 1 (-> another 2 solutions)
解决方案有点太乱了,不能在这里写下来,但它们很简单quadratic equations可以轻松解决。
然后你有 4个独特的向量,它们位于v3
周围的单位圆上(见图)。这4个向量只产生2条不同的线,但找到所有4个向量仍然是一个好主意(作为自检,并提高鲁棒性 - 可能存在一些边缘情况,其中一个向量是这样的喜欢灾难性取消。)
哪条线最适合您,当然取决于您的使用案例。
无论您选择什么解决方案,您当然应该始终验证是否
arccos(((v1-v2)·(v3-v4))/|v1-v2|) = a
应该如此。