我即将提出或正在寻找这个微不足道的问题的方程式:
好吧,更多的是关于根据用户的地理位置了解用户前进的方向。
正如您在下面看到的,用户的第一个坐标在point x
一两分钟后出现,用户的坐标发生了变化,现在位于point y
给定用户的坐标x
和y
,交点point A
以及Point B
如何得出一个公式来告诉我用户是在右车道(从point B
到point A
)还是在左车道(从point A
到 point B
)。
我即将提出或正在寻找这个微不足道的问题的方程式:
好吧,更多的是关于根据用户的地理位置了解用户前进的方向。
正如您在下面看到的,用户的第一个坐标在point x
一两分钟后出现,用户的坐标发生了变化,现在位于point y
给定用户的坐标x
和y
,交点point A
以及Point B
如何得出一个公式来告诉我用户是在右车道(从point B
到point A
)还是在左车道(从point A
到 point B
)。
假设这只是基于坐标,并且不需要考虑点所在的道路或路径,请使用点积。从点创建线段,如果线段对齐(点是相同方向且小于 90 度),则两条线段的点积为正,如果线段指向相反方向,则为负。
如果问题需要考虑道路或路径,则以下内容将不起作用,因为道路/路径有时可能会向后弯曲并远离目的地,因此道路/路径上的正确方向将暂时增加到目的地的距离(如乌鸦飞)。正如您的问题所用的那样,听起来您希望能够从单个用户位置 X 和 Y 值中判断他们所在的已定义道路的哪条车道。如果您考虑一下,如果不知道确切的位置,那根本不可能道路/路径本身的几何形状。如果它完全弯曲,则无法确定。想想看。对于地面上的任何给定位置,您可以单向或另一向弯曲道路,以使该点位于任一车道...
但是有两个位置代表时间上的运动,并且假设他们在他们所在的任何车道上向前移动,您可以确定该运动是更朝向 A 点还是朝向 B 点。
从技术上讲,两个向量 A 和 B 的点积
A dot 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;
}
}