Made the scoring influence of wasted area for the "cygon" packer configurable

git-svn-id: file:///srv/devel/repo-conversion/nusu@24 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2007-05-22 17:57:20 +00:00
parent 116fb53b0a
commit dbc1da27a8
2 changed files with 35 additions and 3 deletions

View File

@ -41,6 +41,28 @@ namespace Nuclex.Support.Packing {
/// </remarks> /// </remarks>
public class CygonRectanglePacker : RectanglePacker { public class CygonRectanglePacker : RectanglePacker {
/// <summary>By how much the wasted area influences a placement's score</summary>
/// <remarks>
/// <para>
/// The score of a potential position for a new rectangle is how far the
/// rectangle is from the lower end of the packing area. The lower the
/// score, the better the position.
/// </para>
/// <para>
/// Often, however, it's better to choose a position that's farther from
/// the lower end of the packing area to not block a gap in which a future
/// rectangle might still fit in. To account for this fact, the packer
/// calculates a "wasted area factor", which is the amount of area that
/// would forever go to waste in relation of the area the rectangle has.
/// </para>
/// <para>
/// This value controls the weighting of this wasted area factor in the
/// potential position's score. Finding a value that works well for typical
/// packing problems is a matter of trial and error, as it seems :)
/// </para>
/// </remarks>
private const int WastedAreaScoreWeight = 3;
#region class SliceStartComparer #region class SliceStartComparer
/// <summary>Compares the starting position of height slices</summary> /// <summary>Compares the starting position of height slices</summary>
@ -106,6 +128,9 @@ namespace Nuclex.Support.Packing {
int rectangleWidth, int rectangleHeight, out Point placement int rectangleWidth, int rectangleHeight, out Point placement
) { ) {
// Total surface area of the rectangle
int rectangleArea = rectangleWidth * rectangleHeight;
// Slice index, vertical position and score of the best placement we could find // Slice index, vertical position and score of the best placement we could find
int bestSliceIndex = -1; // Slice index where the best placement was found int bestSliceIndex = -1; // Slice index where the best placement was found
int bestSliceY = 0; // Y position of the best placement found int bestSliceY = 0; // Y position of the best placement found
@ -137,7 +162,7 @@ namespace Nuclex.Support.Packing {
int score = highest; int score = highest;
// WASTED AREA CALCULATION -------------------------------------------------- // WASTED AREA CALCULATION --------------------------------------------------
// Calculate the amount of space that would go to waste if the rectangle // Calculate the amount of space that would go to waste if the rectangle
// would be placed at this location // would be placed at this location
int wastedArea = 0; int wastedArea = 0;
@ -152,8 +177,14 @@ namespace Nuclex.Support.Packing {
this.heightSlices[rightSliceIndex - 1].X this.heightSlices[rightSliceIndex - 1].X
); );
score += (int)Math.Sqrt((double)wastedArea) / 10; // Limit wasted area to the area taken up by the rectangle. This prevents
// a "build-up" of wasted area that become more expensive the higher the packing
// area is filled.
wastedArea = Math.Min(wastedArea, rectangleArea);
// Alter the score by the amount of wasted area in relation to
score += (wastedArea * WastedAreaScoreWeight / rectangleArea);
// WASTED AREA CALCULATION -------------------------------------------------- // WASTED AREA CALCULATION --------------------------------------------------
if(score < bestScore) { if(score < bestScore) {

View File

@ -78,6 +78,7 @@ namespace Nuclex.Support.Packing {
this.lineHeight = rectangleHeight; this.lineHeight = rectangleHeight;
return true; return true;
} }
/// <summary>Current packing line</summary> /// <summary>Current packing line</summary>