Her şeyin aynı boyutta küplerden oluştuğu ve tüm küplerin aynı türden olduğu küp tabanlı bir dünya (Minecraft, Trove veya Cube World gibi) düşünün .
Amaç, en az sayıda dikdörtgen kutu ile dünyayı temsil etmektir (küpleri birleştirerek, ancak dışbükey şekli koruyarak (yani, dikdörtgen kutu şekli). Algoritmam bunu başardı, ancak performansı amaçlanan amaç için çok yavaş. Daha hızlı algoritmalar var mı?
Algoritmamın sözde-C # kodu temelde:
struct Coordinate { int x,y,z; }; //<-- integer based grid
HashSet<Coordinate> world; // <-- contains all the cubes
//width, height, and length represent how many cubes it spans
struct RectangularBox { Coordinate coord; int width,height,length; }
void Begin()
{
List<RectangularBox> fewestBoxes = new List<RectangularBox>();
while(world.Count > 0)
{
RectangularBox currentLargest = ExtractLargest();
fewestBoxes.Add(currentLargest);
world.RemoveRange(currentLargest.ContainedCubes());
}
//done; `fewestBoxes` contains the fewest rectangular boxes needed.
}
private RectangularBox ExtractLargest()
{
RectangularBox largestBox = new RectangularBox();
foreach (Coordinate origin in world)
{
RectangularBox box = FindMaximumSpan(origin);
if (box.CalculateVolume() >= largestBox.CalculateVolume())
largestBox = box;
}
return largestBox;
}
private RectangularBox FindMaximumSpan(Coordinate origin)
{
int maxX, maxY,maxZ;
while (world.Contains(origin.Offset(maxX, 0, 0))) maxX++;
while (world.Contains(origin.Offset(0, maxY, 0))) maxY++;
while (world.Contains(origin.Offset(0, 0, maxZ))) maxZ++;
RectangularBox largestBox;
for (int extentX = 0; extentX <= maxX; extentX++)
for (int extentY = 0; extentY <= maxY; extentY++)
for (int extentZ = 0; extentZ <= maxZ; extentZ++)
{
int lengthX = extentX + 1;
int lengthY = extentY + 1;
int lengthZ = extentZ + 1;
if (BoxIsFilledWithCubes(origin, lengthX, lengthY, lengthZ))
{
int totalVolume = lengthX * lengthY * lengthZ;
if (totalVolume >= largestBox.ComputeVolume())
largestBox = new RectangularBox(origin, lengthX, lengthY, lengthZ);
}
else
break;
}
return largestBox;
}
private bool BoxIsFilledWithCubes(Coordinate coord,
int lengthX, int lengthY, int lengthZ)
{
for (int gX = 0; gX < lengthX; gX++)
for (int gY = 0; gY < lengthY; gY++)
for (int gZ = 0; gZ < lengthZ; gZ++)
if (!world.Contains(coord.Offset(gX, gY, gZ)))
return false;
return true;
}
Esasen, dünyadaki her blok için, ilk olarak üç pozitif boyutun (+ X, + Y, + Z) her birinde kaç tane blok blok bulunduğunu bulur. Ve sonra bu hacmi sel doldurur ve herhangi bir blok eksik olmayan en büyük dolgu olanı kontrol eder.
Güncelleme: Bunun bir oyunun render motoru için olduğunu ima ettiğimden, açıklığa kavuşturmak istiyorum, bu bir oyunun render motoru için değil; bir dosya dönüştürücü içindir; GUI yok.