如何分辨给定点的方向

时间:2012-10-20 07:56:47

标签: google-maps math routing comparison coordinates

我现在正在或正在寻找这个微不足道的问题的公式:

嗯,更多的是根据用户的地理位置了解用户的行进方向。

如下所示,用户的第一个坐标位于point x后一两分钟,用户的坐标发生了变化,现在位于point y

根据用户的坐标xy,交叉点point APoint B 我如何提出一个公式,告诉我用户是否在正确的车道(从point Bpoint A) 或位于左侧车道(从point Apoint B)。

see image http://s18.postimage.org/lwzj7sf8p/rap2.png

1 个答案:

答案 0 :(得分:3)

假设这只是基于坐标,并且不需要考虑点所在的道路或路径,请使用点积。如果段对齐(点是相同的方向,小于90度),则从点创建段并且两个段的点积为正,如果段指向相反的方向,则为负。

如果问题需要考虑道路或路径,那么下面将无法工作,因为道路/路径有时可能会向后弯曲并远离目的地,因此道路/路径上的正确方向将暂时增加距离目的地(如乌鸦飞)。正如你的问题所表明的那样,你希望能够从一个用户的位置X和Y值告诉他们所处的定义道路的哪条车道。如果你仔细想想,如果不知道确切的话,这是不可能的。道路/路径本身的几何形状。如果它完全弯曲,则无法确定。想一想。对于地面上的任何给定位置,你可以以某种方式弯曲道路以使该位置在任何一条车道上......

但是有两个位置代表时间上的移动,并且假设它们在它们所处的任何车道上向前移动,您可以确定该移动是更多地朝向A点还是朝向B点。

技术上,两个向量A和B的点积   点B = | A | x | B | x Cos(它们之间的角度))

所以,再说一遍,假设您不需要考虑道路的形状或曲率,您只需制作两个定向段,一个从B到A,另一个从一个用户位置到后续用户位置(代表他/她在某个有限时间间隔内的运动),并取这两个段的点积。如果它是积极的,那么他正朝着A走,如果是负面的,他会向B走。

(此代码已简化)

public struct Point
{
    public double X { get; set; }
    public double Y { get; set; }

    private Point(double xValue, double yValue)
    { X = xValue; Y = yValue; }
    public static Point Make(double x, double y)
    { return new Point(x, y); }
}


public class Segment
{
    public Point StartPoint { get; set; }
    public Point EndPoint { get; set; }

    #region ctor / factories
    protected Segment(Point startPoint, Point endPoint)
        : base(startPoint, (endPoint.Y - startPoint.Y) /
                            (endPoint.X - startPoint.X))
    {
       StartPoint = startPoint;
       EndPoint = endPoint;
    }
    public static new Segment Make(Point startPoint, Point endPoint)
    {
        if (startPoint == endPoint)
            throw new Exception(
                "You must use two different points to define a segment.");
        return new Segment(startPoint, endPoint);
    }
    public static new Segment Make(double ax, double ay, double px, double py)
    { return Make(Point.Make(ax, ay), Point.Make(px, py)); }

    public static Segment NullSegment { get { return new Segment(); } }
    #endregion ctor / factories

    public double Length
    {
        get
        {
            return Math.Sqrt(
                Math.Pow(EndPoint.Y - StartPoint.Y, 2) +
                Math.Pow(EndPoint.X - StartPoint.X, 2));
        }
    }

    public double DotProduct(Segment seg, bool normalize = false)
    {
        double
            dAx = EndPoint.X - StartPoint.X,
            dAy = EndPoint.Y - StartPoint.Y,
            dBx = seg.EndPoint.X - seg.StartPoint.X,
            dBy = seg.EndPoint.Y - seg.StartPoint.Y;

        var dP = dAx * dBx + dAy * dBy;

        return normalize? dP / Length / seg.Length : dP;
    }
}