public Rectangle ComputeMaximumRectangle(List<Rectangle> rectanglesList) { if (rectanglesList == null) throw new ArgumentNullException(); if (rectanglesList.Count == 0) throw new ArgumentException("Empty rectangles list"); k = (int)(rectanglesList.Count * 0.75); RectangleContainer container = new RectangleContainer(); rects = new RectanglesList(rectanglesList); rectangle = rects.GetLargestRect(); container.InsertRectangle(rectangle, Rectangle.Orientation.Vertical); Rectangle bestWithShapeCondition = null; if(IsShapeConditionValid(rectangle.SideA, rectangle.SideB)) bestWithShapeCondition = rectangle; Rectangle w; while (!rects.IsEmpty() && running) { w = container.MaxCorrectRect; if (IsShapeConditionValid(w.SideA, w.SideB)) bestWithShapeCondition = w; Rectangle n = rects.GetLongestRect(w.LongerSide); if (n == null) break; bool simpleMendDone = false; bool addingToLeft = true; if (w.RectangleOrientation.Equals(Rectangle.Orientation.Vertical)) { n.Move(new Point(w.RightDown.X, 0)); if (!n.RectangleOrientation.Equals(w.RectangleOrientation)) n.Rotate(); } else { addingToLeft = false; if (!n.RectangleOrientation.Equals(w.RectangleOrientation)) n.Rotate(); n.Move(new Point(0, w.RightDown.Y)); } container.InsertRectangle(n); if (container.IsCorrectRectangle) continue; //k-ty krok to SimpleMend czyli proste zalepianie int pathWidth = n.ShorterSide; for (int i = 0; i < k - 1; i++) { Rectangle t = rects.PeekSmallestNotShorterThan(pathWidth); if (t == null) break; //jeœli jest wiêkszy ni¿ puste, przejdŸmy od razu do k-tego kroku zalepiania if (t.Area >= container.EmptyFieldsArea) { if (SimpleMend(container, t)) { simpleMendDone = true; break; } } //uwzgledniamy czy ostatnio dodany prostok¹t by³ doklejany z boku czy z dolu // z boku Point nLT; if (addingToLeft) { if (!t.RectangleOrientation.Equals(Rectangle.Orientation.Horizontal)) t.Rotate(); nLT = new Point(n.RightDown.X - t.SideA, n.RightDown.Y); } else { if (!t.RectangleOrientation.Equals(Rectangle.Orientation.Vertical)) t.Rotate(); nLT = new Point(n.RightDown.X, n.RightDown.Y - t.SideB); } if (nLT.X >= 0 && nLT.Y >= 0) { t.Move(nLT); container.InsertRectangle(t); rects.RemoveRectangle(t); n = t; } } if (!simpleMendDone) SimpleMend(container); if (!container.IsCorrectRectangle) break; } rectangle = container.MaxCorrectRect; if (!IsShapeConditionValid(rectangle.SideA, rectangle.SideB)) { //Console.WriteLine("Najlepsze znalezione rozwi¹zanie " + rectangle + " nie spe³nia warunku 2:1"); if (bestWithShapeCondition == null) { int bestIndex = -1, largestArea = 0; int i = 0; foreach (Rectangle rec in rectanglesList) { if (IsShapeConditionValid(rec.SideA, rec.SideB) && largestArea < rec.Area) { bestIndex = i; largestArea = rec.Area; } i++; } if (bestIndex > 0) bestWithShapeCondition = rectanglesList[bestIndex]; } rectangle = bestWithShapeCondition; //Console.WriteLine("Za rozwi¹zanie przyjmujê " + rectangle); } //rectangle = resultRectangle; return rectangle; }