2017-01-29 3 views
0

Mit einem gegebenen Byte-Array, das ein großes "A" darstellt, das auf der rechten Seite liegt. (source)Byte-Array gegen den Uhrzeigersinn drehen

Das erwartete Ergebnis ist das Drehen des Byte-Arrays gegen den Uhrzeigersinn für ein stehendes "A".

Mein Versuch, das angegebene Array in eine gedrehte Version zu konvertieren, funktioniert, aber nicht nett. Etwas in meinem Code ist in "loop()" im Bitverschiebungs- und Berechnungsteil nicht korrekt. Aus diesem Grund musste ich separat mit x == 5 und x == 6 umgehen.

Wie kann ich ein Byte-Array gegen den Uhrzeigersinn in einer allgemeineren Weise in c drehen?

Schließlich wird das Array bei einer 8x8 LED-Matrix auf Arduino angezeigt. Siehe Code und Ausgabe unten.

Code:

#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); 
    } 
} 

Output LEDs:

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 _ _ _ _ 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

Antwort

1

Ihr Code scheint wirklich übertrieben. Sie können eine verschachtelte Schleife verwenden, die entsprechend jeder jeden möglichen Bit der Quelldaten und stellen dest Daten iteriert (was im Grunde tauscht Indizes), so etwas wie:

#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; 
} 

nun diese Ausgänge

- 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 - - - - 
- - - - - - - - 

was nicht genau das, was Sie suchen, aber Sie müssen nur die Maske/den Index anpassen, um vom ersten/letzten Bit entsprechend der gewünschten Rotation zu beginnen.

+0

In Ihrer Lösung dürfen sich die Quelle und das Ziel nicht überschneiden. –

+0

@PaulOgilvie: Also, wo ist der Punkt? Verwenden Sie einfach "memcpy", nachdem das neue Array erstellt wurde. Das OP muss nicht vermeiden, temporäre Daten zu verwenden, also warum würden Sie Ihr Leben viel komplizierter machen, ohne ein zusätzliches temporäres Array zu benötigen? Es gibt keinen Grund, dies zu tun, da es keinen Grund zum Ablehnen gab. – Jack

+0

Jack, du hast Recht. Es ist immer noch bemerkenswert (teilweise durch die "const" -Richtlinie). Der Downvote wurde rückgängig gemacht, sobald ich bemerkte, dass es keine Voraussetzung war. –

Verwandte Themen