【问题标题】:Rotate byte array counter clockwise逆时针旋转字节数组
【发布时间】:2017-01-29 17:08:55
【问题描述】:

有一个给定的字节数组,它代表一个大写的“A”,它位于正确的位置。 (source)

预期的结果是逆时针旋转字节数组以获得站立的“A”。

我将给定数组转换为旋转版本的尝试是有效的,但效果不佳。我的代码中的某些内容在位移和计算部分的“loop()”中不正确。出于这个原因,我不得不分别处理 x==5 和 x==6。

如何在 c 中以更通用的方式逆时针旋转字节数组?

最后,阵列显示在 Arduino 上的 8x8 LED 矩阵上。请参阅下面的代码和输出。

代码:

#include "LedControl.h"
LedControl lc=LedControl(12,11,10,4);

void setup(){
  for (int addr=0; addr<lc.getDeviceCount(); addr++){
    lc.shutdown(addr,false);
    lc.setIntensity(addr,0);
    lc.clearDisplay(addr);
  }
}

void loop(){
  // given
  byte a[5]={B01111110,B00010001,B00010001,B01111110,B00000000};

  // expected
  byte a2[8]={B01100000,B10010000,B10010000,B10010000,B11110000,B10010000,B10010000,B00000000};

  // rotated
  byte a3[8];
  byte row;
  for (int x = 0; x < 8; x++){
    row = B00000000;
    for (int y = 0; y < 5; y++){
      if (x==0 || x==1 || x==2 || x==3 || x==4) {
        row |= (a[y] & B00000001 << x) << 7-x-y;
      }
      if (x==5) {
        row |= (a[0] & B00100000) << 2;
        row |= (a[1] & B00100000) << 1;
        row |= (a[2] & B00100000);
        row |= (a[3] & B00100000) >> 1;
      }
      if (x==6) {
        row |= (a[0] & B01000000) << 1;
        row |= (a[1] & B01000000);
        row |= (a[2] & B01000000) >> 1;
        row |= (a[3] & B01000000) >> 2;
      }
    }
    a3[x] = row;
  }

  // output
  for(int i=0; i<8; i++){
    lc.setRow(0,i,a[i]); // given
    lc.setRow(1,i,a2[i]); // expected
    lc.setRow(2,i,a3[i]); // rotated
    delay(100);
  }
}

输出 LED:

given a            expected a2
                   rotated a3

_ o o o o o o _    _ o o _ _ _ _ _
_ _ _ o _ _ _ o    o _ _ o _ _ _ _
_ _ _ o _ _ _ o    o _ _ o _ _ _ _
_ o o o o o o _    o _ _ o _ _ _ _
_ _ _ _ _ _ _ _    o o o o _ _ _ _
_ _ _ _ _ _ _ _    o _ _ o _ _ _ _
_ _ _ _ _ _ _ _    o _ _ o _ _ _ _
_ _ _ _ _ _ _ _    _ _ _ _ _ _ _ _

【问题讨论】:

    标签: c arrays arduino bit-shift


    【解决方案1】:

    您的代码看起来确实有些过头了。您可以使用嵌套循环迭代任何可能的源数据位并相应地设置目标数据(基本上交换索引),例如:

    #include <stdio.h>
    
    typedef unsigned char byte;
    
    void printCharacter(const byte* data, size_t length)
    {
      for (size_t i = 0; i < length; ++i)
      {
        for (size_t j = 0; j < 8; ++j)
        {
          const unsigned char mask = 1 << j;
          printf("%c ", data[i] & mask ? 'o' : '-');
        }
        printf("\n");
      }
    }
    
    void rotate(const byte* source, byte* dest, size_t length)
    {
      /* for each bit position starting from first */
      for (size_t j = 0; j < 8; ++j)
      {
        /* this is the mask of the i-th bit in source data */
        const unsigned char mask = 1 << j;
    
        /* for each row in source data (which will become column) */
        for (size_t i = 0; i < length; ++i)
        {
          /* if j-th bit of i-th row set */
          if (source[i] & mask)
          /* then set i-th bit of j-th row */
            dest[j] |= 1 << i;
        }
      }
    }
    
    int main() {
      byte a[5]= { 0b01111110,0b00010001,0b00010001,0b01111110,0b00000000 };
      byte b[8]= { 0 };
      printCharacter(a, 5);
      rotate(a, b, 5);
      printCharacter(b, 8);
      return 0;
    }
    

    现在这个输出

    - o o o o o o - 
    o - - - o - - - 
    o - - - o - - - 
    - o o o o o o - 
    - - - - - - - - 
    
    - o o - - - - - 
    o - - o - - - - 
    o - - o - - - - 
    o - - o - - - - 
    o o o o - - - - 
    o - - o - - - - 
    o - - o - - - - 
    - - - - - - - - 
    

    这不是您要找的,但您只需要根据您想要的旋转调整掩码/索引以从第一个/最后一个位开始。

    【讨论】:

    • 在您的解决方案中,源和目标可能不会重叠。
    • @PaulOgilvie:那么重点在哪里?只需在创建新数组后使用memcpy。 OP 不需要避免使用临时数据,那么为什么在不需要辅助临时数组的情况下让你的生活变得更加复杂呢?没有理由这样做,因为没有理由投反对票。
    • 杰克,你是对的。仍然值得注意(部分是由const 指令)。一旦我注意到它不是必需的,就撤消了否决。
    • 是的,值得一提,我只是假设这不是必需的(也因为memcpy 之后没有任何奇怪的副作用,除非指定)
    • @Jack:谢谢,但您的代码在旋转时似乎反映了字母(这对于 A 来说并不明显),但对于“J”,您会看到:byte j[5] = {B00110000 , B01000000, B01000001, B00111111, B00000000};
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多