/// <summary> /// Fit rectangles into a given width. Total height required is returned /// </summary> public int AlgFillByStripes(int binWidth, Rectangle[] rects) { // Sort by height. var bestRects = (Rectangle[])rects.Clone(); Array.Sort(bestRects, new HeightComparer()); // Make variables to track and record the best solution. var isPositioned = new bool[bestRects.Length]; var numUnpositioned = bestRects.Length; // Fill by stripes. int maxY = 0; for (int i = 0; i <= rects.Length - 1; i++) { // See if this rectangle is positioned. if (!isPositioned[i]) { // Start a new stripe. numUnpositioned -= 1; isPositioned[i] = true; bestRects[i].X = 0; bestRects[i].Y = maxY; FillBoundedArea( bestRects[i].Width, binWidth, maxY, maxY + bestRects[i].Height, ref numUnpositioned, ref bestRects, ref isPositioned); if (numUnpositioned == 0) break; maxY += bestRects[i].Height; } } // Save the best solution. Array.Copy(bestRects, rects, rects.Length); return maxY; }
// Start the recursion. public void AlgFillByStripes(int bin_width, Rectangle[] rects) { // Sort by height. Rectangle[] best_rects = (Rectangle[])rects.Clone(); Array.Sort(best_rects, new HeightComparer()); // Make variables to track and record the best solution. bool[] is_positioned = new bool[best_rects.Length]; int num_unpositioned = best_rects.Length; // Fill by stripes. int max_y = 0; for (int i = 0; i <= rects.Length - 1; i++) { // See if this rectangle is positioned. if (!is_positioned[i]) { // Start a new stripe. num_unpositioned -= 1; is_positioned[i] = true; best_rects[i].X = 0; best_rects[i].Y = max_y; FillBoundedArea( best_rects[i].Width, bin_width, max_y, max_y + best_rects[i].Height, ref num_unpositioned, ref best_rects, ref is_positioned); if (num_unpositioned == 0) break; max_y += best_rects[i].Height; } } // Save the best solution. Array.Copy(best_rects, rects, rects.Length); }
static void CreateFromLayer(XmlTextWriter xtw, Layer layer, Rectangle extents) { ProjFourWrapper src = null; ProjFourWrapper dst = null; Rectangle queryExtents = extents.Clone(); try { if (!string.IsNullOrEmpty(layer.Projection) && layer.Projection != ProjFourWrapper.WGS84) { src = new ProjFourWrapper(layer.Projection); dst = new ProjFourWrapper(ProjFourWrapper.WGS84); queryExtents = new Rectangle(dst.Transform(src, queryExtents.Min), dst.Transform(src, queryExtents.Max)); } xtw.WriteStartElement("Folder"); xtw.WriteElementString("name", layer.Id); xtw.WriteElementString("visibility", layer.Visible ? "1" : "0"); foreach (Feature f in layer.Data.GetFeatures(queryExtents, layer.ThemeField, layer.LabelField)) { CreateFromFeature(xtw, layer, f, src, dst); } xtw.WriteEndElement(); // Folder } finally { if (src != null) { src.Dispose(); dst.Dispose(); } } }
// Fill the unbounded area, trying to the smallest maximum Y coordinate. // Set the following for the best solution we find: // xmin, xmax, etc. - Bounds of the rectangle we are trying to fill. // num_unpositioned - The number of rectangles not yet positioned in this solution. // Used to control the recursion. // rects() - All rectangles for the problem, some positioned and others not. // Initially this is the partial solution we are working from. // At end, this is the best solution we could find. // is_positioned() - Indicates which rectangles are positioned in this solution. // max_y - The largest Y value for this solution. private void FillUnboundedArea( int xmin, int xmax, int ymin, ref int num_unpositioned, ref Rectangle[] rects, ref bool[] is_positioned) { if (num_unpositioned <= 0) return; // Save a copy of the solution so far. int best_num_unpositioned = num_unpositioned; Rectangle[] best_rects = (Rectangle[])rects.Clone(); bool[] best_is_positioned = (bool[])is_positioned.Clone(); // Currently we have no solution for this area. int best_max_y = int.MaxValue; // Loop through the available rectangles. for (int i = 0; i <= rects.Length - 1; i++) { // See if (this rectangle is not yet positioned and will fit. if (!is_positioned[i] && rects[i].Width <= xmax - xmin) { // It will fit. Try it. // ************************************************** // Divide the remaining area horizontally. int test1_num_unpositioned = num_unpositioned - 1; Rectangle[] test1_rects = (Rectangle[])rects.Clone(); bool[] test1_is_positioned = (bool[])is_positioned.Clone(); test1_rects[i].X = xmin; test1_rects[i].Y = ymin; test1_is_positioned[i] = true; // Fill the area on the right. FillBoundedArea(xmin + rects[i].Width, xmax, ymin, ymin + rects[i].Height, ref test1_num_unpositioned, ref test1_rects, ref test1_is_positioned); // Fill the area on the bottom. FillUnboundedArea(xmin, xmax, ymin + rects[i].Height, ref test1_num_unpositioned, ref test1_rects, ref test1_is_positioned); // Learn about the test solution. int test1_max_y = MaxY(test1_rects, test1_is_positioned); // See if (this is better than the current best solution. if ((test1_num_unpositioned == 0) && (test1_max_y < best_max_y)) { // The test is better. Save it. best_max_y = test1_max_y; best_rects = test1_rects; best_is_positioned = test1_is_positioned; best_num_unpositioned = test1_num_unpositioned; } // ************************************************** // Divide the remaining area vertically. int test2_num_unpositioned = num_unpositioned - 1; Rectangle[] test2_rects = (Rectangle[])rects.Clone(); bool[] test2_is_positioned = (bool[])is_positioned.Clone(); test2_rects[i].X = xmin; test2_rects[i].Y = ymin; test2_is_positioned[i] = true; // Fill the area on the right. FillUnboundedArea(xmin + rects[i].Width, xmax, ymin, ref test2_num_unpositioned, ref test2_rects, ref test2_is_positioned); // Fill the area on the bottom. FillUnboundedArea(xmin, xmin + rects[i].Width, ymin + rects[i].Height, ref test2_num_unpositioned, ref test2_rects, ref test2_is_positioned); // Learn about the test solution. int test2_max_y = MaxY(test2_rects, test2_is_positioned); // See if (this is better than the current best solution. if ((test2_num_unpositioned == 0) && (test2_max_y < best_max_y)) { // The test is better. Save it. best_max_y = test2_max_y; best_rects = test2_rects; best_is_positioned = test2_is_positioned; best_num_unpositioned = test2_num_unpositioned; } } // End trying this rectangle. } // End looping through the rectangles. // Return the best solution we found. is_positioned = best_is_positioned; num_unpositioned = best_num_unpositioned; rects = best_rects; }
// Start the recursion. public void AlgRecursiveDivision(int bin_width, Rectangle[] rects) { // Sort by height. Rectangle[] best_solution = (Rectangle[])rects.Clone(); Array.Sort(rects, new HeightComparer()); // Make variables to track and record the best solution. bool[] is_positioned = new bool[rects.Length]; int num_unpositioned = rects.Length; // Perform the recursion. FillUnboundedArea(0, bin_width, 0, ref num_unpositioned, ref best_solution, ref is_positioned); // Save the best solution. Array.Copy(best_solution, rects, rects.Length); }
// Use rectangles to fill the given sub-area. // Set the following for the best solution we find: // xmin, xmax, etc. - Bounds of the rectangle we are trying to fill. // num_unpositioned - The number of rectangles not yet positioned in this solution. // Used to control the recursion. // rects() - All rectangles for the problem, some positioned and others not. // Initially this is the partial solution we are working from. // At end, this is the best solution we could find. // is_positioned() - Indicates which rectangles are positioned in this solution. // max_y - The largest Y value for this solution. private void FillBoundedArea( int xmin, int xmax, int ymin, int ymax, ref int numUnpositioned, ref Rectangle[] rects, ref bool[] isPositioned) { // See if every rectangle has been positioned. if (numUnpositioned <= 0) return; // Save a copy of the solution so far. int bestNumUnpositioned = numUnpositioned; Rectangle[] bestRects = (Rectangle[])rects.Clone(); bool[] bestIsPositioned = (bool[])isPositioned.Clone(); // Currently we have no solution for this area. double bestDensity = 0; // Some rectangles have not been positioned. // Loop through the available rectangles. for (int i = 0; i <= rects.Length - 1; i++) { // See if this rectangle is not position and will fit. if ((!isPositioned[i]) && (rects[i].Width <= xmax - xmin) && (rects[i].Height <= ymax - ymin)) { // It will fit. Try it. // ************************************************** // Divide the remaining area horizontally. int test1NumUnpositioned = numUnpositioned - 1; Rectangle[] test1Rects = (Rectangle[])rects.Clone(); bool[] test1IsPositioned = (bool[])isPositioned.Clone(); test1Rects[i].X = xmin; test1Rects[i].Y = ymin; test1IsPositioned[i] = true; // Fill the area on the right. FillBoundedArea(xmin + rects[i].Width, xmax, ymin, ymin + rects[i].Height, ref test1NumUnpositioned, ref test1Rects, ref test1IsPositioned); // Fill the area on the bottom. FillBoundedArea(xmin, xmax, ymin + rects[i].Height, ymax, ref test1NumUnpositioned, ref test1Rects, ref test1IsPositioned); // Learn about the test solution. double test1Density = SolutionDensity( xmin + rects[i].Width, xmax, ymin, ymin + rects[i].Height, xmin, xmax, ymin + rects[i].Height, ymax, test1Rects, test1IsPositioned); // See if this is better than the current best solution. if (test1Density >= bestDensity) { // The test is better. Save it. bestDensity = test1Density; bestRects = test1Rects; bestIsPositioned = test1IsPositioned; bestNumUnpositioned = test1NumUnpositioned; } // ************************************************** // Divide the remaining area vertically. int test2NumUnpositioned = numUnpositioned - 1; Rectangle[] test2Rects = (Rectangle[])rects.Clone(); bool[] test2IsPositioned = (bool[])isPositioned.Clone(); test2Rects[i].X = xmin; test2Rects[i].Y = ymin; test2IsPositioned[i] = true; // Fill the area on the right. FillBoundedArea(xmin + rects[i].Width, xmax, ymin, ymax, ref test2NumUnpositioned, ref test2Rects, ref test2IsPositioned); // Fill the area on the bottom. FillBoundedArea(xmin, xmin + rects[i].Width, ymin + rects[i].Height, ymax, ref test2NumUnpositioned, ref test2Rects, ref test2IsPositioned); // Learn about the test solution. double test2Density = SolutionDensity( xmin + rects[i].Width, xmax, ymin, ymax, xmin, xmin + rects[i].Width, ymin + rects[i].Height, ymax, test2Rects, test2IsPositioned); // See if this is better than the current best solution. if (test2Density >= bestDensity) { // The test is better. Save it. bestDensity = test2Density; bestRects = test2Rects; bestIsPositioned = test2IsPositioned; bestNumUnpositioned = test2NumUnpositioned; } } // End trying this rectangle. } // End looping through the rectangles. // Return the best solution we found. isPositioned = bestIsPositioned; numUnpositioned = bestNumUnpositioned; rects = bestRects; }