Traktowanie struktury danych 1D jako siatki 2D

48

Pracuję z rodzimą klasą, która reprezentuje obraz 2D jako tablicę 1D. Jeśli chcesz na przykład zmienić jeden piksel, musisz teraz dowiedzieć się, jak uzyskać indeks ze x,ywspółrzędnych.

Powiedzmy, że mamy taką tablicę 1D array1d:

array1d = [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y ]

W kontekście naszego programu array1dreprezentuje siatkę 2D:

a b c d e
f g h i j
k l m n o
p q r s t
u v w x y

I chcemy wykonywać array1dtakie operacje , jak:

  • Uzyskaj wartość we x,ywspółrzędnych (w tym przykładzie 1,2dałoby l)
  • Uzyskaj dowolną podsiatkę za pomocą x,y,width,height( 1,2,2,2dałoby [l, m, q, r])
  • Ustaw wartość dla dowolnej x,ywspółrzędnej (itp.)

Jak to robimy?

GladstoneKeep
źródło
W Matlab, a zatem prawdopodobnych typach matematycznych (które przelewa się do CS), konwersja jednej macierzy na drugą (czy to 1x12 na 2x6 lub 2x6 na 3x4) jest znana jako „przekształcanie” mathworks.com/help/matlab/ ref / reshape.html
@MichaelT: OP nie przekształca siatki. Brak wzmianki o przekształceniu 5x5 w cokolwiek innego (co i tak nie miałoby sensu). :)
IAbstract
@Abstract to pytanie było jednak w wersji 1 .

Odpowiedzi:

86

2D / 1D - mapowanie jest dość proste. Biorąc pod uwagę x i y oraz rozmiary macierzy 2D width(dla kierunku x) i height(dla kierunku y), możesz obliczyć odpowiedni indeks iw przestrzeni 1D (w oparciu o zero) przez

i = x + width*y;

a operacja odwrotna to

x = i % width;    // % is the "modulo operator", the remainder of i / width;
y = i / width;    // where "/" is an integer division

Możesz to łatwo przedłużyć do 3 lub więcej wymiarów. Na przykład dla matrycy 3D o wymiarach „szerokość”, „wysokość” i „głębokość”:

i = x + width*y + width*height*z;

i odwróć:

x = i % width;
y = (i / width)%height;
z = i / (width*height);
Doktor Brown
źródło
@awashburn, który jest tradycyjnym sposobem na zrobienie tego, jest nawet wbudowany w kompilatory dla statycznych tablic 2D
maniak ratchet
@mtoast: Nie sądzę, to po prostu podstawowa matematyka liczb całkowitych.
Doc Brown,
Ten przykład jest zły dla 3D. Głębokość słowa w obliczeniach powinna wynosić wysokość.
jiggunjer
@jiggunjer: dzięki za poprawkę, odpowiednio zmieniłem moją odpowiedź.
Doc Brown
1
@makakas: to ćwiczenie pozostawiono czytelnikowi ;-). Wskazówka: musisz dodać / odjąć dolną granicę jako przesunięcie w odpowiednich miejscach. Ale zanim spróbujesz tego, wyjaśnij sobie, którą z dwóch tablic masz na myśli, tablicę 1D lub 2D.
Doc Brown,