C#将矩形平铺在大的矩形内,支持旋转调整
public static List<Rect> TileRects(Size rect, Size container) { List<Rect> result = new List<Rect>(); if (rect.Width > container.Width && rect.Width > container.Height || rect.Height > container.Height && rect.Height > container.Width) return null; int angle = 0; int count = 0; if(container.Width >= rect.Width && container.Height >= rect.Height) { int h = (int)Math.Floor(container.Width / rect.Width); int v = (int)Math.Floor(container.Height / rect.Height); count = h * v; for (int i = 0; i < v; i++) { for (int j = 0; j < h; j++) { result.Add(new Rect(j * rect.Width, i * rect.Height, rect.Width, rect.Height, angle)); } } //如果有剩余区域可以填充旋转后的rect, //右侧区域填充是否占用底部区域 bool coverBottom = false; //填充右侧剩余区域 if (container.Width % rect.Width >= rect.Height) { var l = TileRects(new Size(rect.Width, rect.Height), new Size(container.Width % rect.Width, container.Height)); if (l != null) { double left = h * rect.Width; l.ForEach(f => result.Add(new Rect(left, f.Top, f.Width, f.Height, f.Angle))); if (container.Height % rect.Width > 0) coverBottom = true; } } //填充底部剩余区域 if (container.Height % rect.Height >= rect.Width) { var l = TileRects(new Size(rect.Width, rect.Height), new Size(coverBottom ? container.Width - rect.Height : container.Width, container.Height % rect.Height)); double top = v * rect.Height; l?.ForEach(f => result.Add(new Rect(f.Left, top, f.Width, f.Height, f.Angle))); } } else { angle = rect.Width > container.Width ? -90 : 90; int h = (int)Math.Floor(container.Width / rect.Height); int v = (int)Math.Floor(container.Height / rect.Width); count = h * v; for (int i = 0; i < v; i++) { for (int j = 0; j < h; j++) { result.Add(new Rect(j * rect.Height, i * rect.Width, rect.Height, rect.Width, angle)); } } } return result; } public struct Size { public double Width { get; set; } public double Height { get; set; } public Size(double w = 0, double h = 0) { Width = w; Height = h; } } public struct Rect { public double Left { get; set; } public double Top { get; set; } public double Width { get; set; } public double Height { get; set; } public int Angle { get; set; } public Rect(double w = 0, double h = 0) : this(0, 0, w, h) { } public Rect(double l, double t, double w, double h, int a = 0) { Left = l; Top = t; Width = w; Height = h; Angle = a; } }