} //end GetRects() /// <summary> /// Returns a new DynamicGrid whose state is the same as this one's /// </summary> /// <returns></returns> public DynamicGrid GetCopy() { DynamicGrid result = new DynamicGrid(Bounds); result.cols.Clear(); result.rows.Clear(); result.cells.Clear(); // NumCols, NumRows, RectCount result.NumCols = NumCols; result.NumRows = NumRows; result.RectCount = RectCount; // cols, rows, cells foreach (Column col in cols) { result.cols.Add(new Column(col.Width)); } foreach (Row row in rows) { result.rows.Add(new Row(row.Height)); } for (int col = 0; col < NumCols; col++) { List <Cell> newRow = new List <Cell>(); for (int row = 0; row < NumRows; row++) { newRow.Add(new Cell(cells[col][row])); } result.cells.Add(newRow); } return(result); }
/// <summary> /// Finds the optimal arrangement of items in rects List within a bounding rectangle whose /// aspect ratio is the same as that of the application window. /// /// Starts with a bounding rectangle whose height is the sum of the heights of the items in rects, /// places them with a topmost-row-of-leftmost-column algorithm, and repeatedly shrinks the size /// of the bounding rectangle and re-places the Rects until an attempt to place the Rects fails. /// /// The placement algorithm is a modified version of the one outlined here: /// https://www.codeproject.com/Articles/210979/Fast-optimizing-rectangle-packing-algorithm-for-bu /// /// Post: grid's state represents the optimal arrangements of the items in rects and /// images within the bounds of the application window. /// </summary> private void ArrangeRects() { double heightSum = 0.0; foreach (Rect r in rects) { heightSum += r.Height; } double aspect = MainCanvas.ActualWidth / MainCanvas.ActualHeight; // bounds can't be smaller than canvas Rect bounds = (heightSum < MainCanvas.ActualHeight) ? new Rect(0.0, 0.0, MainCanvas.ActualWidth, MainCanvas.ActualHeight) : new Rect(0.0, 0.0, heightSum * aspect, heightSum); // PLACE RECTS VIA THE TOPMOST ROW OF LEFTMOST COL ALGORITHM // guaranteed to work the first time grid = new DynamicGrid(bounds); DynamicGrid optimalArrangement = null; while (PlaceRects()) { optimalArrangement = grid.GetCopy(); if (!grid.ShrinkBounds()) { break; } grid = new DynamicGrid(grid.Bounds); } if (optimalArrangement == null) { Console.WriteLine("ArrangeRects(): Error - optimalArrangement is null"); return; } grid = optimalArrangement.GetCopy(); }//end ArrangeRects()