Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am trying to see if an imagebox interacts with an e graphics line. my current code:

e.Graphics.DrawLine(SystemPens.ButtonShadow, a, b);

if (pictureBox1.Bounds.IntersectsWith(e.GraphicsLine.Bounds))
{
    dead();
}

I am unsure how to do this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
286 views
Welcome To Ask or Share your Answers For Others

1 Answer

To test for intersection of a rectangle and a line you can either use one of the many methods from the Wikipedia article or use a GDI+ trick involving GraphicsPaths and Regions..:

using System.Drawing.Drawing2D;
..

bool Intersects(Point a, Point b, Rectangle r)
{
    if (Math.Min(a.X, b.X) > r.Right)  return false;   // *
    if (Math.Max(a.X, b.X) < r.Left)   return false;   // *
    if (Math.Min(a.Y, b.Y) > r.Bottom) return false;   // *
    if (Math.Max(a.Y, b.Y) < r.Top)    return false;   // *

    if (r.Contains(a)) return true;   // **
    if (r.Contains(b)) return true;   // **

    using (GraphicsPath gp = new GraphicsPath())
    using (Pen pen = new Pen(Color.Empty, 0.5f))
    using (Region reg = new Region(r))
    using (Graphics g = CreateGraphics())
    {
        gp.AddLine(a,b);
        gp.Widen(pen);   // we need to widen the line path just a little
        reg.Intersect(gp);
        if (reg.IsEmpty(g)) return false;
    }
    return true;
}

Here is a small test result:

enter image description here

Since Region.IsEmpty is probably not very fast I have prepended the call with a few trivial tests for better speed. For a discussion of performance issues with Region see here. From this I guess one can conclude that testing with a simple rectangle will in fact still be reasonably fast..

For a truely fast test you may need to implement a real clipping method. This looks nice..

But the GDI+ trick with the region has one big advantage over the analytical methods: I will work with any shapes you can put into a GraphicsPath, including circles, ellipes, polygons, all sorts of combinations and also complex tracing paths. And since the Region supports all set operations, your imagination is the limit..

This allows you to test complex shapes of spaceships or monsters; and with a few extra tricks you can even test rotated shapes.

Note that if you go for testing complex shapes you will want to:

  • pass in the GraphicsPath
  • use its bounding rectangle (gp.GetBounds()) for the first four tests (*)
  • remove the other two tests (**) since the bounding rectangle will not work now; in fact they only work with rectangles; I had to remove them for the following ellipse demo.

Here is the same example, simply replacing the rectangle with an ellipse:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...