2015-04-22 13 views
9

Questa è una domanda strana per la quale ho avuto difficoltà a scrivere un titolo.Un algoritmo per iterare su un'area rettangolare all'interno di un array monodimensionale (bitmapping)

Sto lavorando con pixel (bitmap, più specificamente) e non riesco a capire la (semplice) matematica per accedere pragmaticamente a ogni cella di matrice.

La tela è [n16 x 16] pixel, n è sempre 1 o maggiore.

Ecco una foto di un n base = 2 tela:

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

enter image description here

Quello che voglio il mio algoritmo magico da fare è eseguire 0-495 senza toccare quella zona grigia più leggero passare da 16 a 512 (che in realtà è la cella 511, la mia cattiva) senza toccare l'area grigio scuro.

Quindi, da 0 a 15, passare da 16 a 31 seguita da 32 a 47, ecc

E per n = 3:

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

enter image description here

In questo caso sarebbe 0-735 saltando le aree più chiare di grigio, 16-751 saltando le aree su ciascun lato e 32-767 saltando le aree di grigio più scuro.

quello che ho provato:

Ecco un estratto dal mio codice, speriamo che sia utile e dimostra quello che ho provato già. È la parte che identifica il valore di '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]; 
    } 
} 

Probabilmente hai un'idea. Mi sembra semplice, ma non riesco a capirlo.

Oh, e non mi interessa una libreria magica in grado di gestire tutte le mie risorse bitmap per me, non sono in una posizione in cui posso usarne una.

+0

iterazione sempre nell'intervallo [0, 496) esclusivamente: row = i/16; column = i% 16; gray_index = row * total_number_of_columns + current_gray * 16 + column; –

+0

Non riesco a capire questo "In questo caso sarebbe 0-735 saltare le aree grigie più chiare, 16-751 saltare le aree su ciascun lato e 32-767 saltare le aree di grigio più scuro." È corretto? – ANjaNA

+0

Mi piacciono le foto qui sopra. Questo ti porta un po 'di amore in più da parte mia. –

risposta

2

Se ricevo correttamente la tua domanda, vuoi visitarli nell'ordine che hai menzionato. Ecco il codice che lo fa (dato il vostro 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); 
    } 
    } 
} 

Spero che questo aiuti.

+0

Mi dispiace, mi sono sbagliato con la parte 'row * (n - 1)'. Dovrebbe essere 'row * n' invece. –

+0

Funziona perfettamente! http://puu.sh/hn5zh/455ab22cae.png – Southclaws

2

È abbastanza semplice. Prendendo n come il rettangolo totale moltiplicatore larghezza e bitmap come i dati rettangolo:

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

Ora dicono che si vuole fare sul secondo quadrato, o quadrato dell'indice 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; 
} 

È inoltre possibile avere una funzione più generica per tutte le forme di bitmap che prendono un rect e consentono di modificare i dati in qualsiasi rettangolo che si desidera all'interno della bitmap.Ha bisogno solo la bitmap width come riferimento:

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

Il seguente dovrebbe funzionare:

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

Basta fare un ciclo xy per ogni sprite

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] ... 
     } 
    } 
} 
Problemi correlati