【问题标题】:given 3 vectors and angle, how to find the fourth vector so that 2 line segments are formed through all vectors给定 3 个向量和角度,如何找到第四个向量,以便通过所有向量形成 2 个线段
【发布时间】:2012-08-15 18:45:02
【问题描述】:

我有一个由两个向量组成的线段,比如说v1和v2,一个向量v3和一个角度a。如何在 Java 中编写方法(我也在使用 Apache Commons Math 来表示向量)这给了我一个向量 v4,因此线段 v1-v2 和 v3- v4 在角度 a? 有无限的 v4 元素,如果我可以给该方法一个大小,使线段 v3-v4 具有该大小,那就更好了。 (都是二维空间,角度可以是弧度也可以是度数,没关系)

编辑: 正如我所承诺的,我已经包含了我正在尝试解决的问题的图像。我有一个由 2 个向量定义的线段(线有点长,但没关系)、一个角度和第三个点。我需要绘制第二条线,它与第一条线以 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);
}

【问题讨论】:

  • 使用点积和 arccos 看起来很简单。
  • 二维还是三个?还是更多?
  • @Beta 必须是 2D 的,否则问题没有明确定义。
  • @Ali:为什么会这样?他意识到可能有多种解决方案,他只想要其中一种。
  • @BlueRaja-DannyPflughoeft 在 3D 中,解向量位于圆锥上。在 2D 中,方向是明确定义的。

标签: java math 2d


【解决方案1】:

我不知道 Apache Commons Math,所以我用伪代码编写。让vxvy 分别表示向量vxy 分量。

r=v1-v2s=v3-v4。你有 2 个未知数(即 sxsy; 和 v4=v3-s)所以你需要 2 个方程。这些应该是:

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

第一个方程在sxsy 中都是线性的。让我们从第一个等式中消除sy(假设ry 不为零)

 sy = (1/ry)*(sqrt(rx^2+ry^2)*cos a - rx*sx)

并将sy 代入第二个等式。你在sy 中得到一个二次方程(我不想在这里写,因为它很复杂),它有两个解。您可以通过将sy 值代入(假设rx 不为零)得到相应的sx

 sx = (1/rx)*(sqrt(rx^2+ry^2)*cos a - ry*sy).

最后,v4=v3-sv4 有 2 个解,一个二次方程的每个解。 (我的回答中忽略了退化的情况,例如 r 是一个空向量。)

【讨论】:

  • -1:鉴于 OP 的可能级别,这个答案包含的背景太少了。总共有 4 个解决方案 - 也许您是这个意思,但不清楚您是否这样做。
  • +1:因为它是一个很好的解决方案,在我看来不值得 -1。不过,我同意@RodyOldenhuis 的观点,即关于 OP 的(假设的)知识水平,答案可以稍微扩展。
  • @RodyOldenhuis 非常感谢您以 -1 奖励我的努力。
  • 很抱歉,努力本身并没有回报。结果的质量是......
  • 啊,现在肯定有所改善!仍然:您得到 4 个解(见我的图片),因为,您得到 2 个二次方程 - 一个用于 sx,一个用于 sy。
【解决方案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-component 等。有了这个,微不足道的替换给了我们

( (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

应该如此。

【讨论】:

  • 您可以“编写”方程式。没有直接的 LaTeX 插件或类似的东西(不幸的是),但你可以使用谷歌图表 API。 See this question on meta.。但这对 biep 来说很痛苦。也许网上有一些LaTeX->Google API url的工具。
  • @brimborium 哇...有一点是肯定的:我永远不会使用它 :) 方程似乎确实适用于 SE 数学或 SE 物理 - 你知道为什么 SO 不使用同一组扩展?很少使用它(与 SE 数学相比,不太常见),但这不应该成为借口......
  • -1 只有 2 个解决方案。您的答案比它必须的要复杂。这 2 个虚假的解决方案可能是无害的,因为它们可能给出正确的行,只是 v3-v4 向量的符号相反。
  • @Ali 有 4 种解决方案——参见图片。我没有把它弄得太复杂。 太简单了。
  • @Ali:仅供参考;我可以举几个例子,人们已经死亡,和/或遭受了巨大的经济损失,这一切都是因为程序员忘记或忽略了减号。 始终考虑所有解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 1970-01-01
  • 2015-06-30
  • 2018-08-18
  • 1970-01-01
相关资源
最近更新 更多