-1

I'm stuck on a problem I have a list filled with multiple rectangles and I need to check if any of those rectangles overlap each other, since the list keeps changing using a foreach loop wil return an error. are there any other ways to check for collision?


Code from Comments

for (var x = 0; x < Water.Count(); x++ ) 
{ 
  Rectangle rect = Water[x]; 
  if(rect.Y < 699)
  { 
    rect.Y++;; 
  }
  Water[x] = rect; 
  frameGraphics.FillRectangle(new SolidBrush(Color.Red), Water[x]); 
} 

This is my code to make the rectangles fall down and check if y < 699 now i need to check if one of those rectangles in this list collide with each other

Thanks!

Mark Hall
  • 53,938
  • 9
  • 94
  • 111
  • What did you try so far? Could you please post your code where you stuck? – Oleksii Aza May 10 '14 at 15:09
  • I tried using a foreach loop to loop through the list and check for collision with intersects with but that didn't work because the list is being edited. – Stijn Bernards May 10 '14 at 15:09
  • Does the list change because you are for example removing intersecting rectangles or is it changing for external reasons? – Daniel Brückner May 10 '14 at 15:10
  • I'm adding new rectangles when I click – Stijn Bernards May 10 '14 at 15:12
  • Are you running on multiple threads? If not, you should not be able to execute the click event handler and looking for intersecting rectangles at the same time therefore the problem should be elsewhere. – Daniel Brückner May 10 '14 at 15:15
  • The for each loop is executed in a different class the click does only add a rectangle to the list. – Stijn Bernards May 10 '14 at 15:16
  • for (var x = 0; x < Water.Count(); x++ ) { Rectangle rect = Water[x]; if(rect.Y < 699){ rect.Y++;; } Water[x] = rect; frameGraphics.FillRectangle(new SolidBrush(Color.Red), Water[x]); } this is my code to make the rectangles fall down and check if y < 699 now i need to check if one of those rectangles in this list collide with each other. – Stijn Bernards May 10 '14 at 15:16
  • But is it on the same thread? Are you doing everything in the UI thread or do you have several threads? Are you using timers? – Daniel Brückner May 10 '14 at 15:17
  • I'm using a timer to add rectangles it is all done on the same thread. – Stijn Bernards May 10 '14 at 15:20
  • couldent i use a list to store wich x,y coords are filled with a rectangle and use that static list to check for collision – Stijn Bernards May 10 '14 at 15:21

1 Answers1

3

You should either synchronize access to the list which you are iterating over using a lock or a concurrent collection of some sort or make a copy of the collection before doing the check for intersection.

You can check for intersection by using Rect.Intersect?

Here's an example (copied from msdn)

private Rect intersectExample2()
{
    // Initialize new rectangle.
    Rect myRectangle = new Rect();

    // The Location property specifies the coordinates of the upper left-hand  
    // corner of the rectangle. 
    myRectangle.Location = new Point(10, 5);

    // Set the Size property of the rectangle with a width of 200 
    // and a height of 50.
    myRectangle.Size = new Size(200, 50);

    // Create second rectangle to compare to the first.
    Rect myRectangle2 = new Rect();
    myRectangle2.Location = new Point(0, 0);
    myRectangle2.Size = new Size(200, 50);

    // Intersect method finds the intersection between the specified rectangles and  
    // returns the result as a Rect. If there is no intersection then the Empty Rect  
    // is returned. resultRectangle has a size of 190,45 and location of 10,5. 
    Rect resultRectangle = Rect.Intersect(myRectangle, myRectangle2);

    return resultRectangle;

}

Here's some code which checks if ALL multiple rectangles intersect.

bool CheckIfAllIntersect(IEnumerable<Rect> rectangles)
{
    return rectangles.Aggregate(rectangles.FirstOrDefault(), Rect.Intersect) != Rect.Empty;
}

If you would like ANY rectangle to intersect, you can use the following

bool CheckIfAnyInteresect(IEnumerable<Rect> rectangles) 
{
    return rectangles.Any(rect => rectangles.Where(r => !r.Equals(rect)).Any(r => r.IntersectsWith(rect)));
}
Tejas Sharma
  • 3,420
  • 22
  • 35
  • Yes I have but I need to check on multiple rectangles and can't use a for loop due to the list being changed on click wich throws an exception. – Stijn Bernards May 10 '14 at 15:19
  • 1
    Well if the list is changing, you should probably synchronize access to the list or make a copy of the list before checking. You can then make a new method which accepts an IEnumerable and internally uses Rect.Intersect. – Tejas Sharma May 10 '14 at 15:22
  • List Water2 = Water; foreach (Rectangle check in Water2) { if (check.IntersectsWith(Water[x])) { intersect = true; } } I have tried this but it always returns true? I think it is because it checks if the rectangle collides with itself. – Stijn Bernards May 10 '14 at 15:29
  • Water2 = Water is just a reference copy. You need a "new" list here. var Water2= new List(Water); – Tejas Sharma May 10 '14 at 15:38
  • 1
    can whoever downvoted the answer leave an explanation please? IMO, my answer answers the question. If it doesn't, I would like to improve it. – Tejas Sharma May 10 '14 at 15:41
  • Thanks alot I fixed it sorry that I can't upvote you my rep is too low thanks! – Stijn Bernards May 10 '14 at 15:45
  • The questions is about searching in a mutating list. Not about recangles. – H H May 10 '14 at 15:45
  • The question's clearly about both. "I need to check if any of those rectangles overlap each other, since the list keeps changing using a foreach loop wil return an error" Especially due to the lack of code in the original question, it's not a bad assumption to make that the OP didn't know how to check for intersection. Also looking at his fragment of code in the comments to this answer, it's apparent he was doing the intersection check wrong. Anyway, thanks for atleast leaving a comment. – Tejas Sharma May 10 '14 at 15:49
  • Imho, if your answer mentioned both, it would get marked up. – Surfbutler May 10 '14 at 16:06
  • Well I've mentioned some common techniques people use to deal with concurrency issues. Without code specific to the OP's question, I can't address specifically his issue but hopefully it helps. – Tejas Sharma May 10 '14 at 16:07