我有三个lat-lon坐标,它们构成两个线段A到B到C.我还发现了一个函数,它可以以-180到180的方式返回线段A-B或B-C的北轴承。但是,我很难确定一辆车何时从A到B,如果它向右或向左转到C继续。
答案 0 :(得分:9)
编辑:以前的回答是错误的。现在这是正确的
public Direction GetDirection(Point a, Point b, Point c)
{
double theta1 = GetAngle(a, b);
double theta2 = GetAngle(b, c);
double delta = NormalizeAngle(theta2 - theta1);
if ( delta == 0 )
return Direction.Straight;
else if ( delta == Math.PI )
return Direction.Backwards;
else if ( delta < Math.PI )
return Direction.Left;
else return Direction.Right;
}
private Double GetAngle(Point p1, Point p2)
{
Double angleFromXAxis = Math.Atan ((p2.Y - p1.Y ) / (p2.X - p1.X ) ); // where y = m * x + K
return p2.X - p1.X < 0 ? m + Math.PI : m ); // The will go to the correct Quadrant
}
private Double NormalizeAngle(Double angle)
{
return angle < 0 ? angle + 2 * Math.PI : angle; //This will make sure angle is [0..2PI]
}
答案 1 :(得分:3)
编辑修复超过180的问题,现在也支持U-Turns。
const int THRESHOLD = 0;
Direction TurnLeftOrRight(Point A, Point B, Point C)
{
int angle = ToAngle(B,C) - ToAngle(A,B);
if((angle > THRESHOLD && angle < 180 - THREASHOLD) || angle < -180 - THREASHOLD)
return Direction.Right;
else if ((angle < 0 - THREASHOLD && angle > -180 + THREASHOLD) || angle > 180 + THREASHOLD)
return Direction.Left;
else if (angle >= 0 - THREASHOLD && angle <= THREASHOLD)
return Direction.Straight
else
return Direction.UTurn;
}
您也可以在左右两侧之间进行公差,只需将第一个angle > 0
更改为angle > 45
,将第二个更改为angle < -45
答案 2 :(得分:3)
我认为如果你使用vector cross product,你的生活会更简单。
虽然严格来说,交叉产品仅针对3D矢量定义,但对于2D矢量 p =(px,py)和 q =(qx,qy),您可以想象他们的交叉积 p × q 和px qy - py qx。如果 p 从 q 顺时针方向,则后一个数字为正数;如果 p 从 q 逆时针方向,则为负数>。如果 p 且 q 平行,则为零,即指向相同或相反的方向。
在你的情况下,你正在使用(lat,lon)。 (x,y)坐标中的等价是(-lon,lat),所以如果你有两个向量(lat1,lon1)和(lat2,lon2),你想要计算(-lon1,lat1)×(-lon2, lat2),来自lat1 * lon2-lon1 * lat2。
如果此数字为零,您可以使用dot product判断方向是直的还是掉头。
所以你的代码看起来像这样,假设点和向量是用(lat,lon)形式写的(如果它们在x和y中,代码会有点不同):
public Direction GetTurnDirection(Point A, Point B, Point C)
{
Vector v1 = B - A ;
Vector v2 = C - B ;
double cross = v1.lat*v2.lon - v1.lon*v2.lat ;
if (cross > 0) { return Direction.Left ; }
if (cross < 0) { return Direction.Right ; }
double dot = v1.lat*v2.lat + v1.lon*v2.lon ;
if (dot > 0) { return Direction.Straight ; }
return Direction.UTurn ;
}
答案 3 :(得分:0)
如果AB是来自A的B的B,而B来自B的B的那个,那么 转角是余数(BC-AB,360.0); (假设学位)。如果这 转向正确是肯定的。在您的示例余数中(BC-AB,360.0) 余数(271,360)= -89。