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;
}
}