これが単なる座標ベースであり、ポイントが存在する道路やパスを考慮する必要がないと仮定すると、内積を使用します。ポイントからセグメントを作成し、2つのセグメントの内積は、セグメントが整列している場合は正(ポイントは90度未満で同じ方向)、セグメントが反対方向を指している場合は負になります。
問題が道路またはパスを考慮する必要がある場合、道路/パスが曲がって目的地から遠ざかる可能性があるため、以下は機能しません。そのため、道路/パスの正しい方向は一時的に目的地までの距離を増やします(カラスが飛ぶ)。あなたの質問は、あなたが伝えたいように聞こえます。単一のユーザー位置から、XとYの値は、定義された道路のどの車線にあるかを示します。考えてみると、正確な情報がなければ、それは不可能です。道路/パス自体のジオメトリ。まったく曲がっていると判断できなくなります。考えてみてください。地面の任意の位置について、道路をいずれかの方向に曲げて、そのスポットをいずれかの車線に配置することができます...
しかし、時間の動きを表す2つの位置と、それらがどのレーンにあるかに関係なく前進しているという仮定により、その動きがポイントAに向かっているのかポイントBに向かっているのかを判断できます。
技術的には、2つのベクトルAとB
の内積AドットB = | A | x | B | x Cos(それらの間の角度))
したがって、これもまた、道路の形状や曲率を考慮する必要がないことを前提としています。1つはBからAに、もう1つはあるユーザー位置から次のユーザー位置に2つの有向セグメントを作成するだけです(ある有限の時間間隔での彼/彼女の動きを表します)、そしてこれらの2つのセグメントの内積を取ります。それが正の場合、彼は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;
}
}