分割矩形时出现差一错误

问题描述 投票:0回答:1

我试图将一个矩形分割成相同大小的桶,如果边界没有足够的空间,则调整桶的大小。

为了确定 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

c# indexoutofboundsexception
1个回答
0
投票

确定分区 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);
© www.soinside.com 2019 - 2024. All rights reserved.