如何计算转弯方向

时间:2010-08-05 21:32:10

标签: c# geometry navigation geolocation gis

我有三个lat-lon坐标,它们构成两个线段A到B到C.我还发现了一个函数,它可以以-180到180的方式返回线段A-B或B-C的北轴承。但是,我很难确定一辆车何时从A到B,如果它向右或向左转到C继续。

4 个答案:

答案 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。