私はここから数学を持ち上げました、
さて、各ポイントには4つの「基本光線」があります。光線は2つのポイント間を通過する無限の線です。
// A line in the form Ax+By=C from 2 points
public struct Ray
{
public readonly float A;
public readonly float B;
public readonly float C;
public Ray(PointF one, PointF two)
{
this.A = two.y - one.y;
this.B = one.x - two.x;
this.C = (this.A * one.x) + (this.B * two.x);
}
}
枢機卿を取得するために私たちは拡張することができますPointF
private readonly SizeF NS = new SizeF(0.0F, 1.0F);
private readonly SizeF EW = new SizeF(1.0F, 0.0F);
private readonly SizeF NESW = new SizeF(1.0F, 1.0F);
private readonly SizeF NWSE = new SizeF(-1.0F, 1.0F);
public static IEnumerable<Ray> GetCardinals(this PointF point)
{
yield return new Ray(point + NS, point - NS);
yield return new Ray(point + EW, point - EW);
yield return new Ray(point + NESW, point - NESW);
yield return new Ray(point + NWSE, point - NWSE);
}
2つの光線の交差点を見つけるために私たちができること
static PointF Intersection(Ray one, Ray two)
{
var delta = (one.A * two.B) - (two.A * one.B);
if (delta == 0.0F)
{
//Lines are parallel
return PointF.Empty;
}
else
{
var x = ((two.B * one.C) - (one.B * two.C)) / delta;
var y = ((one.A * two.C) - (two.A * one.C)) / delta;
return new PointF(x, y);
}
}
したがって、2点の枢機卿の交点を取得するには、
public static IEnumerable<PointF> GetCardinalIntersections(
this PointF point,
PointF other);
{
return point.GetCardianls().SelectMany(other.GetCardinals(), Intersection)
.Where(i => !i.IsEmpty());
}
これにより、
public static IEnumerable<PointF> GetCardinalIntersections(
this PointF point,
IEnumerable<PointF> others);
{
return others.SelectMany((o) => point.GetCardinalIntersections(o));
}
その後、この機能をこのように使用できます。
var point = new PointF(1.0F, 1.0F);
var others = new [] { new PointF(2.0F, 5.0F), new PointF(-13.0F, 32.0F) };
var intersections = point.GetCardinalIntersections(others);
明らかに、ここには多くの反復があります。私はこれをコンパイルまたはテストしていませんが、その核心で、数学はかなり効率的であるように思われるので、私はパフォーマンスについて楽観的です。