【问题标题】:An algorithm for iterating over a rectangular area inside a 1 dimensional array (bitmapping)一种迭代一维数组内的矩形区域的算法(位图)
【发布时间】:2015-06-30 10:53:15
【问题描述】:

这是一个奇怪的问题,我很难为它写标题。

我正在处理像素(更具体地说是位图),但无法计算出实用访问每个数组单元格的(简单)数学。

我的画布是 [n16 x 16] 像素,n 始终为 1 或更大。

这是一张基本 n = 2 画布的照片:

http://i.imgur.com/mabwQfJ.png

我希望我的魔法算法从 0 运行到 495 而不触及浅灰色区域,然后从 16 运行到 512(实际上是 511 单元格,我的错)而不触及深灰色区域。

所以,从 0 到 15,跳过 16 到 31,然后是 32 到 47,等等。

对于 n = 3:

http://i.imgur.com/TqJMWl6.png

在这种情况下,0-735 会跳过较浅的灰色区域,16-751 会跳过两侧的区域,32-767 会跳过较深的灰色区域。

我尝试了什么:

这是我的代码的摘录,希望它有用并展示了我已经尝试过的内容。它是计算“idxpos”价值的部分。

// Let's say length = 3 for now.
for (int character = 0; character < length; ++character)
{
    // in case you're wondering, it grabs 16x16 characters from an ASCII spritesheet
    charpos = (string[character] - ' ') * 16 * 16;

    // Runs through the spritesheet character map
    // this is a huge 16x1520 bitmap.
    for (int pixel = 0; pixel < 16 * 16; ++pixel)
    {
        // ignore this, just me messing around with pixel tinting
        r = (((CharMap[charpos + pixel] >> 0) & 0xFF) + 255 - u);
        g = (((CharMap[charpos + pixel] >> 8) & 0xFF) + 255 - v);
        b = (((CharMap[charpos + pixel] >> 16) & 0xFF) + 255 - w);
        newcolour = RGB(r, g, b);

        // THIS is the part I am stuck on:
        idxpos = pixel + (character * 16 * 16);

        bitmap[idxpos] = CharMap[charpos + j];
    }
}

你可能明白了。对我来说这听起来很简单,但我想不通。

哦,我对可以为我处理所有位图内容的神奇库不感兴趣,我无法使用它。

【问题讨论】:

  • 始终以独占方式迭代范围 [0, 496):row = i/16;列 = i%16; gray_index = row * total_number_of_columns + current_gray * 16 + column;
  • 我无法理解“在这种情况下,0-735 会跳过较浅的灰色区域,16-751 会跳过两侧的区域,32-767 会跳过较深的灰色区域。”这是正确的吗?
  • 我喜欢上面的图片。这会让你从我这里得到一些额外的爱。

标签: c++ arrays algorithm bitmap


【解决方案1】:

如果我正确地回答了您的问题,您希望按照您提到的顺序访问它们。这是执行此操作的代码(给定您的 n):

for(int i = 0; i < n; i++) //which section we are going through
{
  for(int row = 0; row < size; row++) //size = 16, better use on of your constants
  { 
    for(int col = 0; col < size; col++)
    {
      int pixelIndex = size * (row * n) + col + size * i; 
      /*the last one is an offset - it moves the 
      index to the right as far as we need.
      If you need two coordinates (as in (x,y))
      instead of one number, it is: */
      int x = row, y = col + size * i;
      doSomethingWithPixel(pixelIndex);
    }
  }
}

希望这会有所帮助。

【讨论】:

  • 抱歉,row * (n - 1) 部分我自己弄错了。它应该是row * n
【解决方案2】:

它很简单。以n 作为矩形总宽度乘数,以bitmap 作为矩形数据:

for (int i = 0; i < 16*16; ++i) // 16*16 because you want a 16x16 area
{
    int x = i % 16;
    int y = i / 16;
    bitmap[x + y * 16 * n] = value;
}

现在说你想在第二个正方形,或索引square = 1的正方形:

for (int i = 0; i < 16*16; ++i)
{
    int x = i % 16;
    int y = i / 16;
    bitmap[x + y * 16 * n + 16 * square] = value;
}

您还可以对所有形状的位图使用更通用的函数,该函数采用矩形,并允许您修改位图中所需的任何矩形中的数据。它只需要位图width作为参考:

void bitmap_fill(int* bitmap, int width, int top, int left, int right, int bottom)
{
    for (; top <= bottom; ++top)
        for (int x = left; x <= right; ++x)
             bitmap[top * width + x] = value;
}

【讨论】:

    【解决方案3】:

    只需为每个精灵制作一个 x-y 循环

    for (int sprite_number=0; sprite_number<n; sprite_number++) {
        for (int y=0; y<height; y++) {
            for (int x=0; x<width; x++) {
                int final_x = sprite_number * width + x;
    
                ... use bitmap[y*bitmap_width + final_x] ...
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      以下应该有效:

      void fill(int n, int p[], int w, int h) {  // n: number of squares; p: data array; w: width; h: height
          for (int i = 0; i < n; ++i) {  // for the i-th square
              for (int j = 0, pos = i * w; j < h; ++j, pos += w * n) {
                  std::fill(p + pos, p + pos + w, 0);  // fill the j-th row of the i-th square
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-03-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-07
        • 2011-04-14
        • 1970-01-01
        • 2019-07-27
        • 2010-12-21
        • 1970-01-01
        相关资源
        最近更新 更多