Geometry “的逻辑;“轻微右转”;给三分

Geometry “的逻辑;“轻微右转”;给三分,geometry,mapping,directions,cross-product,Geometry,Mapping,Directions,Cross Product,给定三个共面(2D)点(X1,Y1),(X2,Y2)和(X3,Y3),分别表示“1=我在哪里,2=我在哪里,3=我要去哪里”,我需要一个简单的算法来告诉我,例如 右转 向左转 向左拐 换句话说,(a)是向左或向右转弯;(b)转弯有多急(让我随意说一下) 在第一部分中,我已经学习了如何使用叉积(参见维基百科:Graham Scan和这里的问题#26315401)根据路径是否逆时针确定转弯是向左还是向右 而且,我确信ATAN2()将是决定转弯有多快的核心 但是我不能。。相当地把我的头绕在正确的数

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

  • 右转
  • 向左转
  • 向左拐
换句话说,(a)是向左或向右转弯;(b)转弯有多急(让我随意说一下)

在第一部分中,我已经学习了如何使用叉积(参见维基百科:Graham Scan和这里的问题#26315401)根据路径是否逆时针确定转弯是向左还是向右

而且,我确信ATAN2()将是决定转弯有多快的核心

但是我不能。。相当地把我的头绕在正确的数学上,这将在所有方向上起作用。(尤其是当角度穿过零线时。(350度到10度的轴承是20度的间隙,而不是340度等)


好吧,我已经厌倦了。[…今早我的头撞在墙上了]“每次我想我得到了它,我都不确定。”所以,好吧,是时候问…:-)

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

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

通过点(标量)积和向量范数的向量角余弦:

Cos(A_B) = (A * B) / (|A|*|B|)
假设Atan2使用该角度的正弦和余弦计算角度,不包括公分母(范数的乘积)

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 * x23 + y12* y23);
  Memo1.Lines.Add(Format('%f radians   %f degrees',
    [DirChange, RadToDeg(DirChange)]));
输出:
0.79弧度45.00度
(左转)

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


-0.14弧度-8.13度
(右转)

编辑-以下是错误的。我最初的回答如下

当我试图使用你的回答时,我没有想到预期的答案

假设这些点是:(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)对于大多数编程语言都是正确的。

嗯,我似乎仍然有点问题

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

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度。

(作者注):这是一个地图应用程序情况。前两点确定了行驶方向;第三个是旅行者现在转向的地方。众所周知,这三点都是“明智的”。编程语言之间的差异没有问题。:-)现在,在我看来,你在计算两个“叉积”的ATAN2。我正在努力将数学形象化(因为我知道什么是ATAN2,等等)。你(或某人)能详细说明一下吗?为什么即使一个向量是“350º”,另一个是“10º”,这也会给我正确的答案?使用叉积计算ATAN2的两个输入的理由是什么?(我并不怀疑你,但“小灯泡”还没有完全打开。):-X第二项是标量积。请看添加的内容。谢谢。现在,请你澄清一下你在编辑后的回复中使用的各种标点符号,“为了花生画廊的利益”,也为了我。小写--“x”我猜是叉积,竖条不能(我猜)表示“绝对值”。。。然后,当我查看你的“Sin()”和“Cos()”方程,并尝试将它们与“DirChange=”的表达式进行比较时,我甚至没有看到使用过一次除法“/”运算符。另外:我知道也许是时候参考一个外部网页(由你选择)来温和地解释这些魔法了。。。M-A-N-Y谢谢!在Javascript中,我还得到了-11.31度(右转)。从(1,3)到(3,2)到(6,1)的点与A的量完全相同
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)]));
=DEGREES(ATAN2(G2*J2-H2*I2; G2*I2+H2*J2))
=DEGREES(ATAN2(G2*I2+H2*J2; G2*J2-H2*I2))
               ^^== X ==^^  ^^== Y ==^^