public CalculatorResult(Tile tile)
        {
            Tile = tile;
            Offcuts = new ObservableCollection<Tile>();

            Offcuts.CollectionChanged += Offcuts_CollectionChanged;
        }
Example #2
0
        /// <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;
        }
Example #3
0
        public void Can_Rotate_Tile()
        {
            Tile tile = new Tile(10, 20);
            tile.Rotate();

            Assert.AreEqual(20, tile.Width);
            Assert.AreEqual(10, tile.Length);
        }
Example #4
0
        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");
        }
Example #5
0
        /// <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;
        }
Example #6
0
 public void TileArea_Returns_100_When_Tile_Is_Created_With_10_By_10()
 {
     var tile = new Tile(10, 10);
     Assert.AreEqual(100, tile.Area);
 }
Example #7
0
        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;
        }