#region License Information /* HeuristicLab * Copyright (C) 2002-2015 Joseph Helm and Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using HeuristicLab.Problems.BinPacking.Interfaces; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; using HeuristicLab.Problems.BinPacking.Dimensions; namespace HeuristicLab.Problems.BinPacking.Shapes { [Item("RectangularPackingShape", "Represents the rectangular measures (width, height) of a two-dimensional bin-packing object.")] [StorableClass] public abstract class RectangularPackingShape : PackingShape, IRegularPackingShape, IComparable { #region Properties /// /// Describes the size on the Y-axis /// [Storable] public int Height { get; set; } /// /// Describes the size on the X-axis /// [Storable] public int Width { get; set; } #endregion #region Helpers public override TwoDimensionalPacking Origin { get { return new TwoDimensionalPacking(0, 0, 0); } } public override int MultipliedMeasures { get { return Height * Width; } } public override bool EnclosesPoint(TwoDimensionalPacking myPosition, TwoDimensionalPacking checkedPoint) { return (myPosition.X <= checkedPoint.X && (myPosition.X + (myPosition.Rotated ? Height : Width) - 1) >= checkedPoint.X && myPosition.Y <= checkedPoint.Y && (myPosition.Y + (myPosition.Rotated ? Width : Height) - 1) >= checkedPoint.Y); } public override bool Encloses(TwoDimensionalPacking checkedPosition, PackingShape checkedShape) { return Encloses(checkedPosition, (RectangularPackingShape)checkedShape); } private bool Encloses(TwoDimensionalPacking checkedPosition, RectangularPackingShape checkedShape) { return Encloses(new RectangleDiagonal(this), new RectangleDiagonal(checkedPosition, checkedShape)); } private bool Encloses(RectangleDiagonal r1, RectangleDiagonal r2) { return ( r1.x1 <= r2.x1 && r1.x2 >= r2.x2 && r1.y1 <= r2.y1 && r1.y2 >= r2.y2); } public override bool Overlaps(TwoDimensionalPacking myPosition, TwoDimensionalPacking checkedPosition, PackingShape checkedShape) { return Overlaps(myPosition, checkedPosition, (RectangularPackingShape)checkedShape); } private bool Overlaps(TwoDimensionalPacking myPosition, TwoDimensionalPacking checkedPosition, RectangularPackingShape checkedShape) { return Overlaps(new RectangleDiagonal (myPosition, this),new RectangleDiagonal (checkedPosition, checkedShape)); } private bool Overlaps(RectangleDiagonal r1, RectangleDiagonal r2) { return !(r1.x1 > r2.x2 || r1.y1 > r2.y2 || r1.x2 < r2.x1 || r1.y2 < r2.y1); } public void ApplyHorizontalOrientation() { if (Width < Height) { var aux = Width; Width = Height; Height = aux; } } #endregion public RectangularPackingShape(int width, int height) : base () { this.Height = height; this.Width = width; } public override void InitializeFromMeasures(int[] measures) { if (measures.Length != 2) throw new InvalidOperationException("Nr of measures does not fit shape-dimension."); this.Width = measures[0]; this.Height = measures[1]; } public override int[] ToArray() { return new int[] { Width, Height }; } [StorableConstructor] protected RectangularPackingShape(bool deserializing) : base(deserializing) { } protected RectangularPackingShape(RectangularPackingShape original, Cloner cloner) : base(original, cloner) { this.Width = original.Width; this.Height = original.Height; } public RectangularPackingShape() : base() {} public override string ToString() { return String.Format("RectangularPackingShape ({0}, {1})", this.Width, this.Height); } #region IComparable Members public int CompareTo(RectangularPackingShape other) { int result = 0;// this.MultipliedMeasures.CompareTo(other.MultipliedMeasures); if (result == 0) { result = this.Width.CompareTo(other.Width); if (result == 0) result = this.Height.CompareTo(other.Height); } return result; } public int CompareTo(object obj) { if (obj.GetType().Equals(this.GetType())) return this.CompareTo((RectangularPackingShape)obj); else return 0; } #endregion private struct RectangleDiagonal { public int x1; public int y1; public int x2; public int y2; public RectangleDiagonal(RectangularPackingShape myShape) : this(new TwoDimensionalPacking(0, 0, 0), myShape) { } public RectangleDiagonal(TwoDimensionalPacking myPosition, RectangularPackingShape myShape) { x1 = myPosition.X; y1 = myPosition.Y; x2 = myPosition.X + (myPosition.Rotated ? myShape.Height : myShape.Width) - 1; y2 = myPosition.Y + (myPosition.Rotated ? myShape.Width : myShape.Height) - 1; } } } }