Advertisement
Guest User

Untitled

a guest
Sep 20th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.79 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace RectangleMapper
  7. {
  8.      
  9.    
  10.     /// <summary>
  11.     /// Stores non-located 2D rectangle
  12.     /// </summary>
  13.     public class Box  
  14.     {
  15.         public int Width { get; set; }
  16.         public int Height { get; set; }
  17.         public object Tag { get; set; }
  18.         public Box(int w, int h)
  19.         {
  20.             Width = w;
  21.             Height = h;
  22.         }
  23.         public Box() : this(0, 0) { }
  24.     }
  25.     /// <summary>
  26.     /// Stores a location
  27.     /// </summary>
  28.     public class Point  
  29.     {
  30.         public int Left { get; set; }
  31.         public int Top { get; set; }
  32.         public Point(int x, int y)
  33.         {
  34.             Left = x;
  35.             Top = y;
  36.         }
  37.         public Point() : this(0, 0) { }
  38.     }
  39.     /// <summary>
  40.     /// Horizontal strip of similar boxes
  41.     /// </summary>
  42.     public class BoxStrip
  43.     {
  44.         public List<Box> Elements { get; private set; }
  45.         public int Width
  46.         {
  47.             get
  48.             {
  49.                 if (Elements.Count == 0)
  50.                     return 0;
  51.                 return Elements[0].Width * Elements.Count;
  52.             }
  53.         }
  54.         public int Height
  55.         {
  56.             get
  57.             {
  58.                 if (Elements.Count == 0)
  59.                     return 0;
  60.                 return Elements[0].Height * Elements.Count;
  61.             }
  62.         }
  63.         public BoxStrip()
  64.         {
  65.             Elements = new List<Box>();
  66.         }
  67.     }
  68.  
  69.     public class StripRectangle
  70.     {
  71.         public BoxStrip Size { get; private set; }
  72.         public Point Location { get; private set; }
  73.  
  74.         public bool Contains(Point p)
  75.         {
  76.             return ((p.Left >= Location.Left) && (p.Left < (Location.Left + Size.Width)) &&
  77.                 (p.Top >= Location.Top) && (p.Top < (Location.Top + Size.Height)));
  78.         }
  79.         public bool Contains(int x, int y)
  80.         {
  81.             return ((x >= Location.Left) && (x < (Location.Left + Size.Width))
  82.                 && (y >= Location.Top) && (y < (Location.Top + Size.Height)));
  83.         }
  84.  
  85.         public StripRectangle(BoxStrip size, Point location)
  86.         {          
  87.             Size = size;
  88.             Location = location;
  89.         }
  90.     }
  91.  
  92.     public static class Extensions
  93.     {
  94.         public static List<BoxStrip> GetStrips(this List<Box> boxes)
  95.         {
  96.             List<BoxStrip> strips = new List<BoxStrip>();
  97.             foreach (var box in boxes)
  98.             {
  99.                 var strip = strips.Find(s => s.Elements[0].Height == box.Height);
  100.                 if (strip == null)
  101.                 {
  102.                     strip = new BoxStrip();
  103.                     strips.Add(strip);
  104.                 }
  105.                 strip.Elements.Add(box);
  106.             }
  107.             return strips;
  108.         }
  109.  
  110.         public static List<StripRectangle> GetRectangleMap(
  111.             this List<Box> boxes)
  112.         {
  113.             List<StripRectangle> output = new List<StripRectangle>();
  114.             List<BoxStrip> strips = boxes.GetStrips();
  115.  
  116.             if (strips.Count == 0)
  117.                 return output;
  118.  
  119.             strips.Sort((s1, s2) => s2.Height - s1.Height);
  120.  
  121.             int HMAX = strips[0].Height;
  122.             int cx = strips[0].Width;
  123.             output.Add(new StripRectangle(strips[0], new Point(0, 0)));
  124.             while (strips.Count > 0)
  125.             {
  126.                 int cy = 0;
  127.                 for (var coveringStrip = output.First(of => of.Contains(cx, cy));
  128.                     coveringStrip != null;
  129.                     coveringStrip = output.First(of=>of.Contains(cx,cy))
  130.                     )
  131.                     cy = coveringStrip.Location.Top + coveringStrip.Size.Height;
  132.                 int cy2 = HMAX - 1;
  133.                 for (var coveringStrip = output.First(of => of.Contains(cx, cy2));
  134.                     coveringStrip != null;
  135.                     coveringStrip = output.First(of => of.Contains(cx, cy2)))
  136.                     cy2 = coveringStrip.Location.Top - 1;
  137.                 if (cy2 < 0)
  138.                 {
  139.                     cx = (from os in output
  140.                           where os.Contains(cx, cy)
  141.                           select os.Location.Left + os.Size.Width).Min();
  142.                     continue;
  143.                 }
  144.                 int dh = 1 + cy2 - cy;
  145.                 BoxStrip selected = null;
  146.                 foreach(var s in strips)
  147.                     if (s.Height <= dh)
  148.                     {
  149.                         selected = s;
  150.                         break;
  151.                     }
  152.                 if (selected == null)
  153.                 {
  154.                     cx = (from os in output
  155.                           where os.Location.Left + os.Size.Width >= cx
  156.                           select os.Location.Left + os.Size.Width).Min();
  157.                     continue;
  158.                 }
  159.                 strips.Remove(selected);
  160.                 output.Add(new StripRectangle(selected, new Point(cx, cy)));
  161.             }
  162.             return output;
  163.         }
  164.     }
  165.  
  166.    
  167.      
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement