/// <summary> /// Calculates the number of offcuts needed to achieve the area to keep, and returns a collection of those offcuts as tiles. /// </summary> /// <param name="areaToKeep">The area that we need to tile; everything else will be waste.</param> /// <returns>A collection of offcuts, as tiles.</returns> public List<Tile> CutPartialTile(Area areaToKeep) { Tile partialTile = new Tile(Width, Length); var offCuts = new List<Tile>(); if (areaToKeep.Width < Width) { offCuts.Add(new Tile(partialTile.Width - areaToKeep.Width, Length)); partialTile.Width = areaToKeep.Width; } if (areaToKeep.Length < Length) { offCuts.Add(new Tile(partialTile.Width, partialTile.Length - areaToKeep.Length)); partialTile.Length = areaToKeep.Length; } return offCuts; }
public Tile FindMatchingOffcut(Area requiredArea) { Tile selectedOffcut = null; foreach (Tile offcut in Offcuts) { if (offcut.Width >= requiredArea.Width & offcut.Length >= requiredArea.Length) { selectedOffcut = offcut; break; } if (offcut.Length >= requiredArea.Width & offcut.Width >= requiredArea.Length) { offcut.Rotate(); selectedOffcut = offcut; break; } } Offcuts.Remove(selectedOffcut); return selectedOffcut; }
public void Area__ComputedArea_Returns_100_When_Tile_Is_Created_With_10_By_10() { var area = new Area(10, 10); Assert.AreEqual(100, area.ComputedArea); }
/// <summary> /// Calculates the number of whole tiles used, along with the number of cuts /// and the total waste percentage. /// </summary> /// <returns>An instance of CalculatorResult.</returns> public CalculatorResult Calculate(Room room, Tile tile, double groutThickness) { Room = room; Tile = tile; GroutThickness = groutThickness; CalculatorResult result = new CalculatorResult(Tile); bool roomComplete = false; Point origin = new Point(0, 0); while (roomComplete == false) { // can a whole tile be placed? Point destination = new Point(origin.X + Tile.Width, origin.Y + Tile.Length); if (destination.X <= Room.Width & destination.Y <= Room.Length) { result.WholeTilesUsed++; origin.X += Tile.Width + GroutThickness; } // there is not enough room in width, a tile has to be cut else if (destination.X > Room.Width & destination.Y <= Room.Length) { Area availableArea = new Area(Room.Width - origin.X, Tile.Length); // look for an offcut var foundTile = result.FindMatchingOffcut(availableArea); if (foundTile == null) { foundTile = Tile; result.WholeTilesUsed++; } foundTile.CutPartialTile(availableArea).ForEach(o => result.Offcuts.Add(o)); origin.X = 0; origin.Y += Tile.Length + GroutThickness; } // there is not enough room in length, a tile has to be cut else if (destination.X <= Room.Width & destination.Y > Room.Length) { Area availableArea = new Area(Tile.Width, Room.Length - origin.Y); // look for an offcut var foundTile = result.FindMatchingOffcut(availableArea); if (foundTile == null) { foundTile = Tile; result.WholeTilesUsed++; } foundTile.CutPartialTile(availableArea).ForEach(o => result.Offcuts.Add(o)); origin.X += Tile.Width + GroutThickness; } // there is not enough room in length or width, a tile has to be cut twice else if (destination.X > Room.Width & destination.Y > Room.Length) { Area availableArea = new Area(Room.Width - origin.X, Room.Length - origin.Y); // look for an offcut var foundTile = result.FindMatchingOffcut(availableArea); if (foundTile == null) { foundTile = Tile; result.WholeTilesUsed++; } foundTile.CutPartialTile(availableArea).ForEach(o => result.Offcuts.Add(o)); origin.X += Tile.Width + GroutThickness; origin.Y += Tile.Length + GroutThickness; } if (destination.X >= Room.Width & destination.Y >= Room.Length) { roomComplete = true; } } return result; }