Вручну
Якщо пам’ять не дуже рідкий ресурс, я вважаю, що я працюю в більших розмірах.
Ось псевдокод.
class Chunk {
Chunk new(int size) {...}
void setPixel(int x, int y, int value) {...}
int getPixel(int x, int y) {...}
}
class Grid {
Map<int, Map<Chunk>> chunks;
Grid new(int chunkSize) {...}
void setPixel(int x, int y, int value) {
getChunk(x,y).setPixel(x % chunkSize, y % chunkSize, value);//actually the modulo could be right in Chunk::setPixel and getPixel for more safety
}
int getPixel(int x, int y) { /*along the lines of setPixel*/ }
private Chunk getChunk(int x, int y) {
x /= chunkSize;
y /= chunkSize;
Map<Chunk> row = chunks.get(y);
if (row == null) chunks.set(y, row = new Map<Chunk>());
Chunk ret = row.get(x);
if (ret == null) row.set(x, ret = new Chunk(chunkSize));
return ret;
}
}
Ця реалізація досить наївна.
Для одного він створює шматки в getPixel (в основному було б добре просто повернути 0 або близько того, якби для цієї позиції не було визначено жодних фрагментів). По-друге, це ґрунтується на припущенні, що ви маєте досить швидку та масштабовану реалізацію Map. Наскільки мені відомо, кожна гідна мова має її.
Також вам доведеться пограти з розміром шматка. Для щільних растрових зображень хороший великий розмір, для розріджених растрових зображень - менший розмір шматка. Насправді, для дуже рідких, "розмір шматка" 1 є найкращим, що робить "шматки" самими застарілими і зменшує структуру даних до int-карти int-карти пікселів.
З полиці
Іншим рішенням може бути перегляд деяких графічних бібліотек. Вони насправді непогано малюють один 2D буфер в інший. Це означатиме, що ви просто виділите більший буфер і матимете оригінал у ньому за координатами.
Як загальна стратегія: Якщо у вас є "блок, що динамічно зростає, пам'ять", це гарна ідея виділити їх кілька, як тільки він буде використаний. Це досить інтенсивна пам'ять, але значно скорочує витрати на розподіл та копіювання . Більшість реалізацій вектора виділяють удвічі більший розмір, коли його перевищують. Отже, особливо якщо ви використовуєте рішення, що не перебуває на полиці, не розширюйте буфер лише на 1 піксель, оскільки запитувався лише один піксель. Виділена пам'ять дешева. Перерозподіл, копіювання та випуск коштує дорого.