X3

RedSky

导航

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

 

posted on 2023-06-05 17:29  HotSky  阅读(118)  评论(0编辑  收藏  举报