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

时间:2012-08-09 19:43:08

标签: java math 2d

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

编辑按照承诺,我已经包含了我正在尝试解决的问题的图像。我有一个由2个向量定义的线段(线条有点长但无关紧要),角度和第三个点。我需要绘制第二条线,它与第一条线相交,角度为 a 。由于Javafx中的所有行(我在这里使用)是通过定义两个点来绘制的,所以我需要找到红点(或任何可能的点)。 visual representation of the problem

编辑:使用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);
}

2 个答案:

答案 0 :(得分:2)

我不知道Apache Commons Math,所以我用伪代码编写。让vxvy分别表示向量x的{​​{1}}和y组件。

允许vr=v1-v2。您有2个未知数(即s=v3-v4sx;以及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

应该如此。

situation sketch