Jump to content
  • Advertisement
Sign in to follow this  
Headkaze

[.net] Calculating a Rectangle around an array of Rectangles

This topic is 3814 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Sounds simple enough. How do you calculate a Rectangle around a List<Rectangle> of Rectangle's? I thought this would be quite easy until I realised Rectangle.Left, Rectangle.Top, Rectangle.Bottom and Rectangle.Right are read only. What is the most efficient way to calculate this? Ie. What does the following method look like.. Rectangle CalcRectangle(List<Rectangle>);

Share this post


Link to post
Share on other sites
Advertisement

public Rectangle CalcRectangle(List<Rectangle> rect_list)
{
int top = int.MaxValue;
int left = int.MaxValue;
int right = int.MinValue;
int bottom = int.MinValue;

foreach (Rectangle rect in rect_list)
{
if (rect.Top < top)
top = rect.Top;

if (rect.Left < left)
left = rect.Left;

if (rect.Right > right)
right = rect.Right;

if (rect.Bottom > bottom)
bottom > rect.Bottom;
}

Rectangle out_rect = new Rectangle(top, left, right - left, bottom - top);
return out_rect;
}



The only way I could think of was a brute force method. But that should do it for you.

theTroll

Share this post


Link to post
Share on other sites

public Rectangle CalcRectangle(List<Rectangle> rect_list)
{
Rectangle union=rect_list[0];
rect_list.Remove(0);
foreach (Rectangle rect in rect_list)
{
union=Rectangle.Union(union,rect);
}
return union;
}




see if this works,
possibly less efficient than trolls solution though

also,
am i blind or does List really have no pop method?

Share this post


Link to post
Share on other sites

public Rectangle CalcRectangle(List<Rectangle> rect_list)
{
Rectangle out_rect;
if(rect_list == null || rect_list.Count == 0)
{
out_rect = new Rectangle(0,0,0,0); // or an exception
}
else
{
out_rect = rect_list[0];
for(int i = 1; i < rect_list.Count; i++)
{
out_rect = Rectangle.Union(out_rect, rect_list);
}
}
return out_rect;
}


Share this post


Link to post
Share on other sites
I doubt you want to use the Union method. Every time you call that Union method, you're going to be creating a new Rectangle object. Now, memory allocation in .NET is pretty fast, but it's not free, and it's more work than we have to be doing. TheTroll's solution should be sufficient, though I would modify it slightly;

public static Rectangle CreateBoundingBox(IEnumberable<Rectangle> rectangles)
{
if(rectangles != null)
{
int left = int.MaxValue, right = int.MinValue, top = int.MaxValue, bottom = int.MinValue;
bool good = false;
foreach(Rectangle rect in rectangles)
{
left = Math.Min(left, rect.Left);
right = Math.Max(right, rect.Right);
top = Math.Min(top, rect.Top);
bottom = Math.Max(bottom, rect.Bottom);
good = true;
}
if(good)
return new Rectangle(left, top, right - left, bottom - top);
}
return Rectangle.Empty;
}



Share this post


Link to post
Share on other sites
Quote:
Original post by capn_midnight
I doubt you want to use the Union method. Every time you call that Union method, you're going to be creating a new Rectangle object. Now, memory allocation in .NET is pretty fast, but it's not free, and it's more work than we have to be doing. TheTroll's solution should be sufficient, though I would modify it slightly;
*** Source Snippet Removed ***


[ edit - *grumble* sorry - jumped the gun... I forgot that IEnumerable doesn't have an implicit Count member in it... if the input was something like List<Rectangle> or another type where you can get the count of the item.... ]

I'd have to modify that slightly to get rid of the boolean "good"... :


//
// Bad code - don't use this... see the "edit" above....
//
public static Rectangle CreateBoundingBox(IEnumberable<Rectangle> rectangles)
{
if((rectangles != null) && (rectangles.Count > 0))
{
int left = int.MaxValue, right = int.MinValue, top = int.MaxValue, bottom = int.MinValue;
foreach(Rectangle rect in rectangles)
{
left = Math.Min(left, rect.Left);
right = Math.Max(right, rect.Right);
top = Math.Min(top, rect.Top);
bottom = Math.Max(bottom, rect.Bottom);
}
return new Rectangle(left, top, right - left, bottom - top);
}
return Rectangle.Empty;
}




just my 2c. ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by DJHoy
[ edit - *grumble* sorry - jumped the gun... I forgot that IEnumerable doesn't have an implicit Count member in it... if the input was something like List<Rectangle> or another type where you can get the count of the item.... ]

I'd have to modify that slightly to get rid of the boolean "good"... :

*** Source Snippet Removed ***

just my 2c. ;)


well, it's probably safe to assume an array of rectangles, since that is what the OP said he was using, but the only way to support both arrays and List<T>s would be to use IEnumberable<T>.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!