static bool intersection(PointF a1, PointF a2, PointF b1, PointF b2, ref PointF ans)
{
float x = ((a1.X*a2.Y - a1.Y*a2.X)*(b1.X - b2.X) - (a1.X - a2.X)*(b1.X*b2.Y - b1.Y*b2.X)) / ((a1.X - a2.X)*(b1.Y - b2.Y) - (a1.Y - a2.Y)*(b1.X - b2.X));
float y = ((a1.X*a2.Y - a1.Y*a2.X)*(b1.Y - b2.Y) - (a1.Y - a2.Y)*(b1.X*b2.Y - b1.Y*b2.X)) / ((a1.X - a2.X)*(b1.Y - b2.Y) - (a1.Y - a2.Y)*(b1.X - b2.X));
if(x == float.NaN || x == float.PositiveInfinity || x == float.NegativeInfinity || y == float.NaN || y == float.PositiveInfinity || y == float.NegativeInfinity)
{ // the lines are equal or never intersect
return false;
}
ans.X = x;
ans.Y = y;
return true;
}
static void extend(Rectangle bounds, ref PointF start, ref PointF end)
{
List<PointF> ansFinal = new List<PointF>();
PointF ansLeft = new PointF();
bool hitLeft = intersection(start, end, new PointF(bounds.X, bounds.Y), new PointF(bounds.X, bounds.Y + bounds.Height), ansLeft);
if(hitLeft && (ansLeft.Y < bounds.Y || ansLeft.Y > bounds.Y + bounds.Height)) hitLeft = false;
if(hitLeft) ansFinal.Add(ansLeft);
PointF ansTop = new PointF();
bool hitTop = intersection(start, end, new PointF(bounds.X, bounds.Y), new PointF(bounds.X + bounds.Width, bounds.Y), ansTop);
if(hitTop && (ansTop.X < bounds.X || ansTop.X > bounds.X + bounds.Width)) hitTop = false;
if(hitTop) ansFinal.Add(ansTop);
PointF ansRight = new PointF();
bool hitRight = intersection(start, end, new PointF(bounds.X + bounds.Width, bounds.Y), new PointF(bounds.X + bounds.Width, bounds.Y + bounds.Height), ansRight);
if(hitRight && (ansRight.Y < bounds.Y || ansRight.Y > bounds.Y + bounds.Height)) hitRight = false;
if(hitRight) ansFinal.Add(ansRight);
PointF ansBottom = new PointF();
bool hitBottom = intersection(start, end, new PointF(bounds.X, bounds.Y + bounds.Height), new PointF(bounds.X + bounds.Height, bounds.Y + bounds.Height), ansBottom);
if(hitBottom && (ansBottom.X < bounds.X || ansBottom.X > bounds.X + bounds.Width)) hitBottom = false;
if(hitBottom) ansFinal.Add(ansBottom);
if(!hitLeft && !hitTop && !hitRight && !hitBottom)
{
throw new Exception("No interections");
}
/*
// IF YOU HAD LINQ
PointF[] ans = ansFinal.Distinct().ToArray();
if(ans.Length < 2)
{
throw new Exception("Corner case *wink*");
}
start.X = ans[0].X; start.Y = ans[0].Y;
end.X = ans[1].X; end.Y = ans[1].Y;
*/
// the following is sufficient to cull out corner to corner, one corner
for(int x=ansFinal.Count-1; x>=1; x--)
if(ansFinal[x] == ansFinal[x-1])
ansFinal.RemoveAt(x);
if(ansFinal.Count < 2)
{
throw new Exception("Corner case *wink*");
}
start.X = ansFinal[0].X; start.Y = ansFinal[0].Y;
end.X = ansFinal[1].X; end.Y = ansFinal[1].Y;
}
РЕДАКТИРОВАТЬ Я написал это в браузере, так что может быть несколько синтаксических ошибок ...
Суть в том, что вы тестируете, используя пересечение между линиями с каждой стороныпрямоугольникЕсли пересечение существует, убедитесь, что оно находится в границах стороны прямоугольников (отрезок).