得到最大的不重叠对象算法(x,y,宽度,高度)

时间:2011-08-11 20:14:45

标签: c# algorithm

我有一个包含对象的数组。每个类都有x,y,width,height属性。 需要在垂直方向和水平方向上获得所有最大的不重叠。 我已经解决了这个问题,但我的算法很慢且非常难看。 我怎么能解决这个优雅?如果有可能,请告诉我一些代码 不只是数学的东西。

public class MyClass
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

enter image description here


所以输出必须是

垂直物体1,4,8

水平对象0,1,2

示例

___________
var 0 = new MyClass(X:0, Y:0, Width:10, Height:3);
var 1 = new MyClass(X:10, Y:0, Width:10, Height:5);
var 2 = new MyClass(X:20, Y:0, Width:10, Height:2);

pick 1 because
0.Height < 1.Height

var 3 = new MyClass(X:0, Y:3, Width:10, Height:6);
var 4 = new MyClass(X:0, Y:5, Width:10, Height:3);
var 5 = new MyClass(X:0, Y:2, Width:10, Height:8);

pick 4 because
3 and 5 are overlapping with 1.
...............

元素之间可以有空闲空间。

2 个答案:

答案 0 :(得分:1)

只需计算每个Top的{​​{1}}和Bottom值。

使用MyClass变量,将其初始化为Boundary

  1. 选择一个身高最高的元素(0 - Bottom),其Top = Top。如果某些元素是ax equo(相同Boundary,相同的高度),请选择左边的元素。

  2. 将此元素移位(设置)TopBoundary(这可确保您选择的下一个元素不会与此元素重叠)。

  3. 转到Bottom

  4. 横向移动时,只需使用1代替Left等。

    鉴于你的要求(“它们总是很好地融合在一起,就像你拥有它一样吗?” - 你回复“是的它总是能够融合在一起”)它会像你描述的那样工作:1,4,8。

    编辑:好的。然后我们选择一个Top大于或等于前一个元素的Bottom的元素。

    有些事情:

    Top

答案 1 :(得分:1)

我“画”它得到可见尺寸

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
class Program
{
    static void Main(string[] args)
    {
        List<myClass> data = new List<myClass>();
        StringBuilder sb = new StringBuilder();
        data.Add(new myClass() { Height = 3, Width = 10, X = 0, Y = 0, Id = 1 });
        data.Add(new myClass() { Height = 5, Width = 10, X = 10, Y = 0, Id = 2 });
        data.Add(new myClass() { Height = 2, Width = 10, X = 20, Y = 0, Id = 3 });
        data.Add(new myClass() { Height = 6, Width = 10, X = 0, Y = 3, Id = 4 });
        data.Add(new myClass() { Height = 3, Width = 10, X = 0, Y = 5, Id = 5 });
        data.Add(new myClass() { Height = 8, Width = 10, X = 0, Y = 2, Id = 6 });

        List<myClass> result = GetVisualRegions(data);

        var dataSortW = from item in result
                        orderby item.Width descending
                        select item;
        var dataSortH = from item in result
                        orderby item.Height descending
                        select item;
        Console.WriteLine("Data sorted by Width");
        foreach (var item in dataSortW)
            Console.WriteLine(item.Id);
        Console.WriteLine("Data sorted by Height");
        foreach (var item in dataSortH)
            Console.WriteLine(item.Id);
        Console.ReadLine();

    }

    private static List<myClass> GetVisualRegions(List<myClass> data)
    {
        int maxX = data.Max(obj => obj.X + obj.Width);
        int maxY = data.Max(obj => obj.Y + obj.Height);
        int[,] dataOverlapping = new int[maxX, maxY];
        List<myClass> result = new List<myClass>();
        foreach (var item in data)
        {
            myClass tmpItem = new myClass();
            bool yColected = false;
            int xdata = item.X + item.Width;
            int ydata = item.Y + item.Height;
            int id = item.Id;
            tmpItem.Id = item.Id; ;
            for (int posY = item.Y; posY < ydata; posY++)
            {
                int width = 0;
                for (int posX = item.X; posX < xdata; posX++)
                {
                    if (dataOverlapping[posX, posY] <= 0)
                    {
                        dataOverlapping[posX, posY] = id;

                        width += 1;
                        if (yColected == false)
                        {
                            yColected = true;
                            tmpItem.Height += 1;
                        }
                    }
                }
                yColected = false;

                if (tmpItem.Width < width)
                    tmpItem.Width = width;
            }
            if ((tmpItem.Height > 0) && (tmpItem.Width > 0))
                result.Add(tmpItem);
        }
        return result;
    }
}
public class myClass
{
    public int Id { get; set; }
    public int X { get; set; }
    public int Y { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

}