我有一个包含对象的数组。每个类都有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; }
}
所以输出必须是
垂直物体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.
...............
元素之间可以有空闲空间。
答案 0 :(得分:1)
只需计算每个Top
的{{1}}和Bottom
值。
使用MyClass
变量,将其初始化为Boundary
。
选择一个身高最高的元素(0
- Bottom
),其Top
= Top
。如果某些元素是ax equo(相同Boundary
,相同的高度),请选择左边的元素。
将此元素移位(设置)Top
到Boundary
(这可确保您选择的下一个元素不会与此元素重叠)。
转到Bottom
。
横向移动时,只需使用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; }
}
}