如何找到两个向量上距离相等的点,距离为X。

3

我有一个令我感到困惑的问题,涉及编程。我有两个向量在某一点相交。这些向量可能来自不同的角度,就像以下两幅图像所示:

Example 1 Example 2

交点也被称为交叉积,其计算方法可以从this中得到。向量的起点和终点也已知。现在我有一条长度为X的线段,并想知道该线段在这两个向量之间的确切位置,以及来自向量的这些点的坐标。我认为这张图片更好地描述了它:

Example 3 Example 4

当然,一条长度为X的直线可以以多种不同的方式适配两个向量。例如,下面的两幅图像展示了线X在向量A和B之间的不同位置,其中线的长度相同,但位置和角度不同:

Example 3 again Example 5

如果可能的话,我希望位置差由向量的长度决定。因此,如果向量B的长度是向量A的五倍,S点与线触及向量B处的距离应该是S点与线触及向量A处距离的5倍。就像上面右边的图片,S点与线触及向量B处的距离比S点与线触及向量A处的距离要大得多。
最好的方法是找到这条直线的位置在哪里?所以线在向量A上的起点和在向量B上的终点在哪里?我想在C++中实现这个,但计算两个向量上每个点之间的距离并检查是否相等似乎非常耗费时间,并且使用浮点数也很困难。
编辑:解决方案已找到。下面我将给出一个小例子。
  • 假设角度c(向量A和向量B之间的夹角)为90度。
  • 比例为1:2(因此B的长度是A的两倍)。
  • 最后,C边长为30。
你需要做的是为向量A和B的长度编造数字。我在this网站上发现,无论你填入4和8作为边A和B,还是填入8和16或任何其他具有1:2比例的数字,角a在所有情况下都是相同的,角b也是如此。因此,要计算角a和b,只需使用例如5和10。你首先要做的(或者至少我是这样做的)是使用以下公式计算边C、角c和边A和B:sqrt(sideA * sideA + sideB * sideB - 2 * sideA * sideB * cos(degreesToRadian(angleC)));。请注意,这不是给出的边C,而是用于计算角度的边。
之后,您可以使用以下公式计算角度a:radianToDegrees(acos((sideB * sideB + sideC * sideC - sideA * sideA) / (2 * sideB * sideC))) 现在您已经找到了角度 a,就可以得出三角形中的所有角度。因为您已经知道角度 c,所以您刚刚计算出了 a 和 b = 180 - a - c。最后一件事是使用以下公式计算边 A 和边 B,使用角度 c、角度 a 和给定的边 C:sideB * sin(degreesToRadian(angleA)) / sin(degreesToRadian(angleB))
当您将所有内容放在一个函数中作为参数传入时:(float angleC,float ratioB,float sideC)。在我们的例子中是 (90, 0.5, 30)。然后进行如下计算:
    float fakeSideA = 10;
    float fakeSideB = fakeSideA * ratioB;
    float fakeC = sqrt(fakeSideA * fakeSideA + fakeSideB * fakeSideB - 2 * fakeSideA * fakeSideB * cos(degreesToRadian(angleC)));

    float angleA = radianToDegrees(acos((fakeSideB * fakeSideB + fakeC * fakeC - fakeSideA * fakeSideA) / (2 * fakeSideB * fakeC)));
    float sideA = sideC * sin(degreesToRadian(angleA)) / sin(degreesToRadian(angleC));

    std::cout << "SideA: " << sideA << ", AngleA: " << angleA << ", SideC: " << sideC << ", AngleC: " << angleC << std::endl;`

输出应该像这样:SideA: 26.8328,AngleA: 63.435,SideC: 30,AngleC: 90。这是正确的。知道sideA是S和线段X与向量A相交的点之间的长度,您可以计算出那个点的坐标。

1
这句话的意思是“该直线沿着向量B的方向延伸5倍远”。 - Rakete1111
@Rakete1111,S点与直线触碰向量B的位置之间的距离应该是S点与直线触碰向量A的位置之间距离的五倍。希望这样解释更清楚了,我会进行编辑。 - JohnCake
那很有道理,谢谢 :) - Rakete1111
你是说你有两条线线段在一个点相交吗?向量没有相交的概念。 - user253751
圆圈有帮助吗?圆是所有点都位于相同距离的位置。 - Thomas Matthews
一条直线有无限多个点。 - gpasch
2个回答

2
您可以使用余弦定理这里有一个应用该定理解决问题的示例。 接下来,您需要注意矢量A与矢量B的大小比率,以便在图中将a转换为b。从那里开始,C就已知了,而A = 180度 - C - B。
您有六个变量:a、b、c、A、B和C,两个约束条件(A = 180 - C - B和a = ratio * b),以及一个形式为C的常数。
现在,您可以选择其中两个变量中的三个,即a或b、A或B或c。使用正弦定理将此变量等同于其相应的伴侣。这样做会留下一个未知数,您可以使用wolfram页面上的相应公式来解决它(或者只需从页面上的某个公式推导出来)。
另外,请注意您需要将从这些公式找到的角度转换/映射回原始方向/坐标系。

我觉得我在这里漏掉了什么,但我似乎无法将其缩小到一个未知数。现在我有“b ^ 2 =(比率* b)^ 2 + c ^ 2-2 (比率 b)* c * cos(180-A-C)”。c是我知道长度的线段,角C是可计算的,留下未知数b和A。不确定如何继续。 - JohnCake
你现在有:a b c A B C。你知道 c 和 C。你现在需要的是 a b A B。b = a / ratio。B = 180 - C - A。你现在需要得到 b 和 A,因为你只有一个公式却有两个未知数,这意味着你有无限种可能的答案组合。因此,选择一个变量(我会选择一个具有一定意义的变量,但你也可以选择一个随机值),并使用它来解决最终的未知数。基本上由于你有两个未知数和一个公式,所以你的系统缺乏定义,你需要定义另一个变量才能解决该系统。 - Shawn
很抱歉,但我真的不明白。如果我只填入一个随机值,最终的未知数总是不同的,90% 的时间甚至无法计算,所以我真的很困惑,因为它不应该不同,对吧? - JohnCake
例如,如果比率为2(意味着b是a的两倍长),C为90度,c为32,您能否向我展示如何计算这些值? - JohnCake
请原谅我的愚蠢,但我仍然看不到它。我们如何找到A?在你的答案中,我仍然卡在两个未知数a和A上。我已经写了十遍,但我似乎无法得出答案 = /。您能否展示整个过程和最终的值/答案? - JohnCake
显示剩余3条评论

1

假设已知线段A、线段B和交点S,找到A和B的标准化方向向量(在计算交点时可能已经找到了)

dA = (A1.X - A0.X, A1.Y - A0.Y) / Length(A)
dB = (B1.X - B0.X, B1.Y - B0.Y) / Length(B)

以及比例kBA

kBA = Length(B) / Length(A)

沿着B的新线段的末端应该是S的kBA倍远

EA = S - t * dA
EB = S - t * kBA * dB

现在编写EA-EB线段长度的方程

 LenX^2 = (EA.X - EB.X)^2 + (EA.Y - EB.Y)^2

解决未知参数t,并找到点EA和EB(如果有解,它们存在于A和B线段的范围内)
Denom = (kBA * dB.x - dA.x)^2 + (kBA * dB.y - dA.y)^2
if Denom = 0 then segments are parallel and there is no solution
else
t = +/- sqrt(Len^2 / Denom) 

finally 
EA.X = S.X - t * dA.X
and so on...

我认为应该是 EB = S - t * kBA * dB(而不是 dA),最后的方程式简化为 t = sqrt(Len^2 / ((kBA * dB.x - dA.x)^2 + (kBA * dB.y - dA.y)^2)),如果我没有漏掉任何步骤的话... - Bob__
对于dB - 是的,复制粘贴错误。对于最后一个方程式 - 是的,一切都正确(+-解是可能的,并且平行线的零除数)。 - MBo
这里有很多未知数,比t还要多;EA是两个数字(x,y),而不是一个数字,EB也是如此;因此,您需要将其详细说明,否则它就是一个无法解决的系统。 - gpasch
@gpasch,您说得不对。t是唯一未知的变量。EA.X和EA.Y都是通过已知坐标和t计算出来的。 - MBo
显然,您的表述存在一些谬误;您暗示该段仅适用于两个位置,这是不正确的;我感觉谬误在于将归一化的dA与未归一化的S混合。 - gpasch
是的,只有两个位置-请看作者倒数第二段-这就是为什么我引入了kBA比率。 - MBo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接