ลองจินตนาการถึงโลกตามก้อน (เช่น Minecraft, Trove หรือ Cube โลก) ที่ทุกอย่างถูกสร้างขึ้นจากก้อนขนาดเดียวกันและก้อนทั้งหมดเป็นของเดียวกันชนิด
เป้าหมายคือการเป็นตัวแทนของโลกที่มีกล่องสี่เหลี่ยมจำนวนน้อยที่สุด (โดยรวมก้อน แต่ยังคงรูปร่างนูน (aka รูปร่างกล่องสี่เหลี่ยม)) อัลกอริทึมของฉันประสบความสำเร็จในสิ่งนี้ แต่ประสิทธิภาพของมันช้าเกินไปสำหรับวัตถุประสงค์ที่ตั้งใจไว้ มีอัลกอริทึมเร็วขึ้นหรือไม่
หลอก -C # -code สำหรับอัลกอริทึมของฉันเป็นพื้น:
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;
}
โดยพื้นฐานแล้วสำหรับทุก ๆ บล็อกในโลกนั้นจะค้นพบว่ามีบล็อกที่ขัดแย้งกันจำนวนมากในแต่ละมิติสามมิติ (+ X, + Y, + Z) จากนั้นก็เติมน้ำท่วมปริมาณและตรวจสอบซึ่งเป็นบรรจุที่ใหญ่ที่สุดที่ไม่ได้หายไปบล็อกใด ๆ
อัปเดต: เนื่องจากฉันดูเหมือนจะบอกเป็นนัย ๆ ว่านี่เป็นของเอ็นจิ้นการเรนเดอร์เกมฉันแค่ต้องการชี้แจงนี่ไม่ใช่สำหรับเอ็นจิ้นการเรนเดอร์ของเกม มันเป็นตัวแปลงไฟล์ ไม่มี GUI