Skip to content

Instantly share code, notes, and snippets.

@LukaHorvat
Last active January 3, 2016 10:49
Show Gist options
  • Save LukaHorvat/8452144 to your computer and use it in GitHub Desktop.
Save LukaHorvat/8452144 to your computer and use it in GitHub Desktop.
public static void PackRectanglesModify(List<PackedRectangle> rectangles)
{
rectangles.Sort
(
Comparing.CreateComparer<PackedRectangle, double>
(
rect => rect.Rectangle.Size.X * rect.Rectangle.Size.Y
)
);
rectangles.Reverse();
var possibleSpots = new List<AARectangle>();
possibleSpots.Add
(
new AARectangle
(
new Vector2d(0, 0),
new Vector2d(double.MaxValue, double.MaxValue)
)
);
var placedRectangles = new List<AARectangle>();
foreach (var rect in rectangles)
{
possibleSpots.Sort
(
Comparing.CreateComparer<AARectangle, double>
(spot =>
Math.Max
(
spot.Position.X + rect.Rectangle.Size.X,
spot.Position.Y + rect.Rectangle.Size.Y
)
)
);
var bestSpot = possibleSpots.First
(spot =>
spot.Size.X >= rect.Rectangle.Size.X &&
spot.Size.Y >= rect.Rectangle.Size.Y
);
rect.Rectangle.Position = bestSpot.Position;
placedRectangles.Add(rect.Rectangle);
possibleSpots.Remove(bestSpot);
var toRemove = new List<AARectangle>();
foreach (var spot in possibleSpots)
{
FitRectangle(spot, rect.Rectangle);
if (spot.Size.X <= 0 || spot.Size.Y <= 0)
{
toRemove.Add(spot);
}
}
toRemove.ForEach(x => possibleSpots.Remove(x));
possibleSpots.Add
(
new AARectangle
(
rect.Rectangle.Position.X + rect.Rectangle.Size.X,
rect.Rectangle.Position.Y,
bestSpot.Size.X - rect.Rectangle.Size.X,
bestSpot.Size.Y
)
);
possibleSpots.Add
(
new AARectangle
(
rect.Rectangle.Position.X,
rect.Rectangle.Position.Y + rect.Rectangle.Size.Y,
bestSpot.Size.X,
bestSpot.Size.Y - rect.Rectangle.Size.Y
)
);
}
}
private static void FitRectangle(AARectangle toFit, AARectangle other)
{
if (other.Position.X >= toFit.Position.X &&
IntervalsIntersect
(
toFit.Position.Y,
toFit.Position.Y + toFit.Size.Y,
other.Position.Y,
other.Position.Y + other.Size.Y
))
{
toFit.Size.X = Math.Min(other.Position.X - toFit.Position.X, toFit.Size.X);
}
if (other.Position.Y >= toFit.Position.Y &&
IntervalsIntersect
(
toFit.Position.X,
toFit.Position.X + toFit.Size.X,
other.Position.X,
other.Position.X + other.Size.X
))
{
toFit.Size.Y = Math.Min(other.Position.Y - toFit.Position.Y, toFit.Size.Y);
}
}
private static bool IntervalsIntersect(double x1, double y1, double x2, double y2)
{
return Math.Min(y1 - x2, y2 - x1) > 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment