Java 给定3个矢量和角度,如何找到第四个矢量,以便通过所有矢量形成2条线段

Java 给定3个矢量和角度,如何找到第四个矢量,以便通过所有矢量形成2条线段,java,math,2d,Java,Math,2d,我有一条线段,由两个向量组成,比如v1和v2,一个向量v3和一个角度a。我如何用Java编写一个方法(我也在使用Apache Commons Math来表示一个向量)给我一个向量v4,这样线段v1-v2和v3-v4就成了角度a?有无限的v4元素,如果我能为该方法指定一个大小,使线段v3-v4具有该大小,那就更好了。(全部在2d空间中,角度可以是弧度或度数,无所谓) 编辑:正如我承诺的那样,我已经包含了我试图解决的问题的图像。我有一个线段,由两个向量(直线有点长,但没关系)、一个角度和第三个点定义

我有一条线段,由两个向量组成,比如v1和v2,一个向量v3和一个角度a。我如何用Java编写一个方法(我也在使用Apache Commons Math来表示一个向量)给我一个向量v4,这样线段v1-v2和v3-v4就成了角度a?有无限的v4元素,如果我能为该方法指定一个大小,使线段v3-v4具有该大小,那就更好了。(全部在2d空间中,角度可以是弧度或度数,无所谓)

编辑:正如我承诺的那样,我已经包含了我试图解决的问题的图像。我有一个线段,由两个向量(直线有点长,但没关系)、一个角度和第三个点定义。我需要画第二条线,它与第一条线以a角相交。由于Javafx(我在这里使用)中的所有线条都是通过定义两点来绘制的,所以我需要找到红点(或任何可能的点)。

编辑:使用阿里的答案,我得到了以下方法,满足了我的需要:

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);
}
public Pair calculatefurthpoint(vector2dv1、vector2dv2、vector2dv3、双角度索引){
向量2d r=v1减去(v2);
双rx=r.getX();
双y=r.getY();
双角度=环面(角度指数);
双a=功率(rx,2)+功率(ry,2);
双b=2*sqrt(功率(rx,2)+功率(ry,2))*cos(角度)*rx;
双c=功率(rx,2)*功率(cos(角度),2)+功率(ry,2)*功率(cos(角度),2)-功率(ry,2);
双判别式=sqrt(pow(b,2)-(4*a*c));
双sx1=(-b+判别式)/(2*a);
双sx2=(-b-判别式)/(2*a);
双sy1=sqrt(1-功率(sx1,2));
双sy2=sqrt(1-功率(sx2,2));
Vector2D s1=新的Vector2D(sx1,sy1);
vector2ds2=新的Vector2D(sx2,sy2);
向量2d v4_1=v3.减法(s1);
向量2d v4_2=v3.减法(s2);
返回新对(v4\u 1、v4\u 2);
}

我不懂Apache Commons的数学,所以我用伪代码编写。让
vx
vy
分别表示向量
v
x
y
分量

r=v1-v2
s=v3-v4
。你有两个未知数(即
sx
sy
;和
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
代入第二个等式。你可以在sy中得到一个二次方程(我不想在这里写它,因为它很复杂),它有两个解。通过将
sy
值代入(假设
rx
不为零),可以得到相应的
sx


最后,
v4=v3-s
您可以得到v4的两个解,二次方程的每个解一个。(退化情况,例如
r
为空向量,在我的回答中被忽略。)

我不懂Apache Commons数学,所以我用伪代码编写。让
vx
vy
分别表示向量
v
x
y
分量

r=v1-v2
s=v3-v4
。你有两个未知数(即
sx
sy
;和
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
代入第二个等式。你可以在sy中得到一个二次方程(我不想在这里写它,因为它很复杂),它有两个解。通过将
sy
值代入(假设
rx
不为零),可以得到相应的
sx


最后,
v4=v3-s
您可以得到v4的两个解,二次方程的每个解一个。(退化情况,例如
r
为空向量,在我的回答中被忽略。)

遗憾的是,我们不能在这里建立乳胶式方程(或者我们可以?我不知道,从来没有在这里做过…),但这里是:

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

所以,在两个未知数中有两个方程。现在,为了简单起见

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) 
解决方案有点凌乱,无法写在这里,但它们很简单,很容易解决

然后,您就有了4个唯一的向量,它们位于
v3
周围的一个单位圆上(见图)。这4个向量只产生2条不同的线,但找到所有4个向量仍然是一个好主意(作为自检,并提高稳健性——可能存在一些边缘情况,其中一个向量会发生灾难性抵消)

哪一行最适合您,当然取决于您的用例

无论您选择什么解决方案,您当然应该始终验证

arccos(((v1-v2)·(v3-v4))/|v1-v2|) = a
应该如此


可惜我们不能在这里做乳胶式方程式(或者我们可以吗?我不知道,从来没有在这里做过…),但这里是这样的:

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

所以,在两个未知数中有两个方程。现在,为了简单起见

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) 
解决方案有点太混乱了