三点给出了“轻微右转”的逻辑

时间:2015-04-20 19:22:55

标签: geometry mapping directions cross-product

给出三个共面(2D)点(X1,Y1),(X2,Y2)和(X3,Y3),它们代表(分别......)“1 =我在哪里,2 =我在哪里am,and 3 =我要去的地方,“我需要一个能告诉我的简单算法,例如

  • 向右转
  • 稍微左转
  • 向左转

换句话说,(a)是左转或右转; (b)转弯有多锐利(让我对此有所挑衅)。

对于第一部分,我已经了解了如何使用(参见维基百科:Graham Scan和问题#26315401)交叉产品,以确定转弯是左转还是转弯,具体取决于是否路径是逆时针的。

而且,我确信ATAN2()将成为确定转弯有多锐利的核心。

但我不能......完全围绕正确的数学运算,这将适用于所有方向。 (特别是当角度越过零线时(350度到10度的轴承是20度的间隙,而不是340度,。)

好吧,我已经累了。 [...我的头靠在墙上这个早上。]“每次我想我都知道了,我不确定“。所以,好的,是时候问......: - )

3 个答案:

答案 0 :(得分:3)

使用Atan2计算方向变化角度时,请不要担心绝对角度。您不必计算两个方位并减去它们 - Atan2可以在范围-Pi..Pi (-180..180)的第一个和第二个向量之间给出相对角度(范围可能取决于编程语言)。

x12 = x2-x1
x23 = x3-x2
y12 = y2-y1
y23 = y3-y2
DirChange = Atan2(x12*y23-x23*y12, x12*y12+x23*y23)

一些解释:我们可以通过叉积和矢量范数(|A| = Sqrt(A.x*A.x + A.y*A.y))来计算矢量矢量角的正弦值:

Sin(A_B) = (A x B) / (|A|*|B|)
通过点(标量)乘积和矢量范数的矢量矢量角的

和余弦:

Cos(A_B) = (A * B) / (|A|*|B|)

想象一下,Atan2用这个角度的正弦和余弦计算角度,不包括公分母(规范的乘积)

A_B = Atan2(Sin(A_B), Cos(A_B))

Delphi中的示例:

var
  P1, P2, P3: TPoint;
  x12, y12, x23, y23: Integer;
  DirChange: Double;
begin
  P1 := Point(0, 0);
  P2 := Point(1, 0);
  P3 := Point(2, 1);
  x12 := P2.X - P1.X;
  y12 := P2.Y - P1.Y;
  x23 := P3.X - P2.X;
  y23 := P3.Y - P2.Y;
  DirChange := MAth.ArcTan2(x12 * y23 - x23 * y12, x12 * y12 + x23 * y23);
  Memo1.Lines.Add(Format('%f radians   %f degrees',
    [DirChange, RadToDeg(DirChange)]));

输出: 0.79 radians 45.00 degrees(左转)

示例数据集(1,1),(3,2)和(6,3)

-0.20 radians -11.31 degrees(右转)

答案 1 :(得分:0)

已编辑 - 以下内容错误。 我的原始回复如下...

当我尝试使用您的回复时,我没有想出预期的答案。

让我们说这些点是:(1,1),(3,2)和(6,3)。一个温和的右转。

使用电子表格,我想出:X12 = 2,X23 = 3,Y12 = 1,Y23 = 3,ATAN2结果(以度为单位)是101.3。超过90度的急转弯。第2行的电子表格公式(列出X1,Y1,X2,Y2,X3,Y3,X12,X23,Y12,Y23和答案)为:

=DEGREES(ATAN2(G2*J2-H2*I2; G2*I2+H2*J2))

(电子表格,OpenOffice,将“X”列为ATAN2的第一个参数。)

你确定我的错字很突然吗?

并且,作为事实的事实(所以要说话),“是的,它是!”

(嘿,我实际上已经自己说过了。我刚刚没有想过,就像,直接交换它们一样。)

我的电子表格版本的ATAN2函数首先指定 X 参数。大多数编程语言(Delphi,Perl,PHP ...)首先指定 Y ,这就是给出(正确!)答案的方式。

当我编辑公式,反转参数以满足电子表格的定义时,问题就消失了,我能够从(已编辑)回复中重现这些值。这是修正后的公式,参数相反:

=DEGREES(ATAN2(G2*I2+H2*J2; G2*J2-H2*I2))
               ^^== X ==^^  ^^== Y ==^^

同样,公式的这种变化是必要的,因为 ATAN2的这个电子表格的实现是从大多数编程语言实现的实现回来的。最初给出的答案,首先列出Y,对于大多数编程语言都是正确的

答案 2 :(得分:0)

好吧,我似乎仍然遇到了一些问题。 。 。

如果这些点在几乎一条直线上彼此相距很远,我就会想出“大角度”。例如:

P1:(0.60644,0.30087).. P2:(0.46093,0.30378).. P3:(0.19335,0.30087)

X坐标增加但Y坐标几乎保持不变。

x12 = -0.145507 .. y12 = -0.00290698

x23 = -0.267578125 .. y23 = 0.002906976

(我将Y差异反转,因为坐标位于象限-IV,Y向下增加。)

x = -0.000354855 .. y = -0.00120083

ans = -106.462 (度)

由于这些点几乎是共线的,我希望答案非常小。如你所见,它超过106度。