ОБНОВЛЕНИЕ 2:
public bool AreLinesVisible(Point[] p, int width, Rectangle rect)
{
for (var i = 1; i < p.Length; i++)
if (IsLineVisible(p[i - 1], p[i], width, rect))
return true;
return false;
}
ОБНОВЛЕНИЕ для включения толщины / ширины.
Это полностью непроверенный код, но он должен даватьВы базовая идея для сверхбыстрого решения без дорогих вызовов фреймворка:
public bool IsLineVisible(Point p1, Point p2, int width, Rectangle rect)
{
var a = Math.Atan2(p1.Y - p2.Y, p1.X - p2.X) + Math.PI/2;
var whalf = (width + 1)*0.5;
var dx = (int) Math.Round(whalf*Math.Sin(a));
var dy = (int) Math.Round(whalf*Math.Cos(a));
return IsLineVisible( new Point(p1.X - dx, p1.Y - dy), new Point(p2.X - dx, p2.Y - dy), rect)
|| IsLineVisible( new Point(p1.X + dx, p1.Y + dy), new Point(p2.X + dx, p2.Y + dy), rect);
}
public bool IsLineVisible(Point p1, Point p2, Rectangle rect)
{
if (p1.X > p2.X) // make sure p1 is the leftmost point
return IsLineVisible(p2, p1, rect);
if (rect.Contains(p1) || rect.Contains(p2))
return true; // one or both end-points within the rect -> line is visible
//if both points are simultaneously left or right or above or below -> line is NOT visible
if (p1.X < rect.X && p2.X < rect.X)
return false;
if (p1.X >= rect.Right && p2.X >= rect.Right)
return false;
if (p1.Y < rect.Y && p2.Y < rect.Y)
return false;
if (p1.Y >= rect.Bottom && p2.Y >= rect.Bottom)
return false;
// now recursivley break down the line in two part and see what happens
// (this is an approximation...)
var pMiddle = new Point((p1.X + p2.X)/2, (p1.Y + p2.Y)/2);
return IsLineVisible(p1, new Point(pMiddle.X - 1, pMiddle.Y), rect)
|| IsLineVisible(new Point(pMiddle.X + 1, pMiddle.Y), p2, rect);
}