public CalculatorResult(Tile tile) { Tile = tile; Offcuts = new ObservableCollection<Tile>(); Offcuts.CollectionChanged += Offcuts_CollectionChanged; }
/// <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 virtual CalculatorResult Calculate(Room room, Tile tile, double groutThickness) { Room = room; Tile = tile; GroutThickness = groutThickness; CalculatorResult result = new CalculatorResult(Tile); // determine how many whole tiles will be used to tile the floor. int wholeTilesUsedAlongWidth = (int)Math.Floor(Room.Width / (Tile.Width + GroutThickness)); int wholeTilesUsedAlongLength = (int)Math.Floor(Room.Length / (Tile.Length + GroutThickness)); // add them to the sum of tiles result.WholeTilesUsed = wholeTilesUsedAlongWidth * wholeTilesUsedAlongLength; // determine if the 'width' require partial tiles // if yes, add as many partial tiles to the sum of tiles as there are whole tiles in the 'length' // add the offcuts to the collection for later use and waste calculation bool requiresIncompleteTileForWidth = false; double remainingWidth = Room.Width % (Tile.Width + GroutThickness); if (remainingWidth > 0) { requiresIncompleteTileForWidth = true; result.WholeTilesUsed += wholeTilesUsedAlongLength; for (int i = 1; i <= wholeTilesUsedAlongLength; i++) { result.Offcuts.Add(new Tile(Tile.Width - remainingWidth, Tile.Length)); } } // determine if the 'length' require partial tiles // if yes, add as many partial tiles to the sum of tiles as there are whole tiles in the 'width' // add the offcuts to the collection for later use and waste calculation bool requiresIncompleteTileForLength = false; double remainingLength = Room.Length % (Tile.Length + GroutThickness); if (remainingLength > 0) { requiresIncompleteTileForLength = true; result.WholeTilesUsed += wholeTilesUsedAlongWidth; for (int i = 1; i <= wholeTilesUsedAlongWidth; i++) { result.Offcuts.Add(new Tile(Tile.Length - remainingLength, Tile.Width)); } } // if partials were required for both width and length, then one tile must be cut twice to fill the last corner. // add the offcuts to the collection for later use and waste calculation if (requiresIncompleteTileForWidth && requiresIncompleteTileForLength) { result.WholeTilesUsed++; // TODO this is not ideal: it does not take into account that the second cut has a different length/width result.Offcuts.Add(new Tile(Tile.Length, Tile.Width - remainingWidth)); result.Offcuts.Add(new Tile(Tile.Length - remainingLength, Tile.Width)); } return result; }
public void Can_Rotate_Tile() { Tile tile = new Tile(10, 20); tile.Rotate(); Assert.AreEqual(20, tile.Width); Assert.AreEqual(10, tile.Length); }
private void btnCalculate_Click(object sender, EventArgs e) { var room = new Room(double.Parse(txtRoomWidth.Text), double.Parse(txtRoomLength.Text)); var tile = new Tile(double.Parse(txtTileWidth.Text), double.Parse(txtTileLength.Text)); var groutThickness = double.Parse(txtGroutThickness.Text); IPattern pattern = (IPattern)cmbPattern.SelectedItem; var result = pattern.Calculate(room, tile, groutThickness); txtTotalTilesUsed.Text = result.WholeTilesUsed.ToString(); txtTotalCuts.Text = result.TotalCuts.ToString(); txtWaste.Text = result.WastePercentage.ToString("P2"); }
/// <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 void TileArea_Returns_100_When_Tile_Is_Created_With_10_By_10() { var tile = new Tile(10, 10); Assert.AreEqual(100, tile.Area); }
public void Tile_CutPartialTile_Can_Create_Single_Offcut() { var tile = new Tile(12, 12); var offCuts = tile.CutPartialTile(new Area(10, 12)); Assert.AreEqual(1, offCuts.Count); Assert.AreEqual(2, offCuts[0].Width); Assert.AreEqual(12, offCuts[0].Length); }
/// <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; }