1

给定三个共面 (2D) 点 (X1, Y1)、(X2, Y2) 和 (X3, Y3),它们分别表示(...)“1=我在哪里,2=我在哪里,并且3=我要去哪里,”我需要一个简单的算法来告诉我,例如

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

换句话说,(a) 是向左转或向右转;和 (b) 转弯有多尖锐(让我对此有任意性)。

对于第一部分,我已经学习了如何使用(参见维基百科:Graham Scan,以及此处的问题#26315401)叉积来确定转向是向左还是向右,基于路径是否是逆时针。

而且,我确信 ATAN2() 将是确定转弯幅度的核心。

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

好吧,我累了。[......今天早上我的头撞在墙上。]“每次我认为我明白了,我不确定。” 所以,好吧,是时候问了...... :-)

4

3 回答 3

3

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

x12 = x2-x1
y12 = y2-y1
x23 = x3-x2
y23 = y3-y2
DirChange = Atan2(x12*y23-x23*y12, x12*x23+y12*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))

德尔福的例子:

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 * x23 + y12* 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.14 radians -8.13 degrees(右转)

于 2015-04-21T03:00:24.140 回答
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 )对于大多数编程语言都是正确的。

于 2015-04-21T18:26:43.863 回答
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 差异,因为坐标位于第四象限,其中 Y 向下增加。)

x=-0.000354855 .. y=-0.00120083

ans= -106.462 (度)

由于这些点几乎是共线的,我预计答案会非常小。如您所见,它超过 106 度。

于 2015-04-28T19:41:11.333 回答