我试图将一个矩形分割成相同大小的桶,如果边界没有足够的空间,则调整桶的大小。
为了确定 Bucket 的数量,我使用
int partitionsX = Math.Max((textureWidth / PartitionSize),1);
int partitionsY = Math.Max((textureHeight / PartitionSize), 1);
SampleBucket[] buckets = new SampleBucket[(partitionsX * partitionsY)];
for(int x=0; x < partitionsX; ++x)
{
for(int y = 0;y < partitionsY; ++y)
{
int idx = x + (y * partitionsX);
var bucketX = x * PartitionSize;
var bucketY = y * PartitionSize;
var bucketWidth = PartitionSize;
var bucketHeight = PartitionSize;
bucketWidth = Math.Min(bucketX + bucketWidth, (int)textureWidth) - bucketX;
bucketHeight = Math.Min(bucketY + bucketHeight, (int)textureHeight) - bucketY;
Debug.Assert(bucketWidth > 0);
Debug.Assert(bucketHeight > 0);
buckets[idx] = new SampleBucket()
{
X = bucketX,
Y = bucketY,
W = bucketWidth,
H = bucketHeight,
SampleLocations = Enumerable.Repeat(new SampleLocation() { Index = NOOP}, bucketWidth * bucketHeight).ToArray()
};
}
}
当我尝试用数据填充存储桶时,就会出现问题。
foreach(var l in sampleLocations)
{
int bucketX = (int)(l.PixelX / PartitionSize); // PixelX/PixelY is absolute within the original texture/rectangle
int bucketY = (int)(l.PixelY / PartitionSize);
int bucketIdx = bucketX + bucketY * partitionsX;
Debug.Assert(bucketIdx < buckets.Length);
var bucket = buckets[bucketIdx]; // OOB occurs here, but I don't know where my mistake is
var locations = bucket.SampleLocations;
var sampleX = l.PixelX - bucket.X;
var sampleY = l.PixelY - bucket.Y;
var sampleIdx = sampleX + sampleY * bucket.W;
Debug.Assert(sampleIdx < locations.Length);
locations[sampleIdx] = l;
}
当textureWidth = 416、textureHeight = 452和SampleLocation位于PixelX = 51和PixelY = 448时,当PartitionSize为32时,我收到一个越界桶。 我检查了三次数学,但看在上帝的份上,我找不到我的错误在哪里。
带有崩溃用例的演示: https://dotnetfiddle.net/VKYvpP
确定分区 X 和 Y 的行使用整数数学。当(可能的)小数部分低于 0.5 时,这会导致存储桶少于所需数量。
要解决该问题,请取
size / partitionSize
的上限。
int partitionsX = Math.Max((int)Math.Ceiling(textureWidth / (float)PartitionSize),1);
int partitionsY = Math.Max((int)Math.Ceiling(textureHeight / (float)PartitionSize), 1);