Алгоритм грубой силы ...
Сначала проверьте, находится ли прямоугольник слева или справа от конечных точек линии:
- Установите крайние левые и крайние правые значения X конечных точек линии: XMIN и XMAX
- Если Rect.Left> XMAX, то пересечения нет.
- Если Rect.Right ‹XMIN, то пересечения нет.
Затем, если вышеуказанного было недостаточно, чтобы исключить пересечение, проверьте, находится ли прямоугольник выше или ниже конечных точек линии:
- Установите самые верхние и самые нижние значения Y конечных точек линии: YMAX и YMIN
- Если Rect.Bottom> YMAX, то пересечения нет.
- Если Rect.Top ‹YMIN, то пересечения нет.
Затем, если вышеуказанного было недостаточно, чтобы исключить пересечение, вам нужно проверить уравнение линии y = m * x + b
, чтобы увидеть, находится ли прямоугольник над линией:
- Установите значение Y линии в положениях Rect.Left и Rect.Right: LINEYRECTLEFT и LINEYRECTRIGHT
- Если Rect.Bottom> LINEYRECTRIGHT && Rect.Bottom> LINEYRECTLEFT, то пересечения нет.
Затем, если вышеуказанного было недостаточно, чтобы исключить пересечение, вам нужно проверить, находится ли прямоугольник ниже линии:
- Если Rect.Top ‹LINEYRECTRIGHT && Rect.Top‹ LINEYRECTLEFT, то пересечения нет.
Тогда, если вы попадете сюда:
N.B. Я уверен, что есть более элегантное алгебраическое решение, но геометрическое выполнение этих шагов ручкой и бумагой несложно.
Некоторый непроверенный и некомпилированный код для этого:
public struct Line
{
public int XMin { get { ... } }
public int XMax { get { ... } }
public int YMin { get { ... } }
public int YMax { get { ... } }
public Line(Point a, Point b) { ... }
public float CalculateYForX(int x) { ... }
}
public bool Intersects(Point a, Point b, Rectangle r)
{
var line = new Line(a, b);
if (r.Left > line.XMax || r.Right < line.XMin)
{
return false;
}
if (r.Top < line.YMin || r.Bottom > line.YMax)
{
return false;
}
var yAtRectLeft = line.CalculateYForX(r.Left);
var yAtRectRight = line.CalculateYForX(r.Right);
if (r.Bottom > yAtRectLeft && r.Bottom > yAtRectRight)
{
return false;
}
if (r.Top < yAtRectLeft && r.Top < yAtRectRight)
{
return false;
}
return true;
}
person
Johann Gerell
schedule
01.04.2011