2015-04-22 6 views
9

To jest dziwne pytanie, na które trudno mi było napisać tytuł.Algorytm do iteracji na prostokątnym obszarze wewnątrz tablicy jednowymiarowej (bitmapping)

Pracuję z pikselami (mapy bitowe, bardziej szczegółowo) i nie mogę obliczyć (prostych) matematyki dla pragmatycznego dostępu do każdej komórki macierzy.

Moje płótno ma wymiary [n16 x 16] pikseli, n oznacza zawsze 1 lub więcej.

Oto zdjęcie podstawowego n = 2 płótno:

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

enter image description here

Co chcę mój magiczny algorytm zrobić to uruchomić od 0 do 495, bez dotykania że zapalniczki szarej strefie następnie przejdź od 16 do 512 (co jest w rzeczywistości komórką 511, moja zła) bez dotykania ciemnoszarego obszaru.

więc 0 do 15 przejść 16 do 31, a następnie przez 32 do 47 itd

i dla n = 3:

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

enter image description here

W tym przypadku jest będzie 0-735 pomijając jaśniejsze szare obszary, 16-751 pomijając obszary po obu stronach i 32-767 pomijając ciemniejsze szare obszary.

Co próbowałem:

Oto wyciąg z mojego kodu, mam nadzieję, że jest to przydatne i pokazuje, co już próbowałem. Jest to część, która określa wartość "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]; 
    } 
} 

Prawdopodobnie wpadłeś na pomysł. Brzmi dla mnie prosto, ale nie mogę tego rozgryźć.

Aha, i nie jestem zainteresowany jakąś magiczną biblioteką, która poradzi sobie z wszystkimi moimi bitmapowymi rzeczami, nie jestem w sytuacji, w której mógłbym użyć jednego.

+0

Zawsze iteracji z przedziału [0, 496) wyłącznie: row = i/16; column = i% 16; gray_index = wiersz * liczba_sumowanych_kolumn + zmienna_główna * 16 + kolumna; –

+0

Nie mogę tego zrozumieć "W tym przypadku byłoby 0-735 pomijanie jaśniejszych szarych obszarów, 16-751 pomijanie obszarów po obu stronach i 32-767 pomijanie ciemniejszych szarości." Czy to prawda? – ANjaNA

+0

Podoba mi się zdjęcia powyżej. To daje mi dodatkową miłość. –

Odpowiedz

2

Jeśli dobrze odpowiem na twoje pytanie, chcesz je odwiedzić w podanej kolejności. Oto kod, który robi to (biorąc pod uwagę swoją 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); 
    } 
    } 
} 

nadzieję, że to pomaga.

+0

Niestety, myliłem się sam z częścią 'row * (n - 1)'. Powinien to być 'row * n'. –

+0

Działa idealnie! http://puu.sh/hn5zh/455ab22cae.png – Southclaws

2

Jest to dość proste. Biorąc n jako prostokąt Szerokość całkowita mnożnika i bitmap jako dane prostokąta:

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

teraz, że chcesz to zrobić na drugim placu lub placu indeksu 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; 
} 

można również mają bardziej ogólną funkcję dla wszystkich kształtów map bitowych, które pobierają prostokąty i pozwalają modyfikować dane w dowolnym prostokącie, który chcesz umieścić w bitmapie.To tylko potrzebuje bitmapę width jako odniesienie:

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

Poniższy powinno działać:

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

prostu zrobić pętlę xy dla każdej ikonki

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] ... 
     } 
    } 
} 
Powiązane problemy