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:
parent
116fb53b0a
commit
dbc1da27a8
|
@ -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
|
||||||
|
@ -152,7 +177,13 @@ 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 --------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user