Есть ли способ сократить количество требуемых поисков?
Как минимум, вам нужно будет выполнить минимум 1 поиск на воксел. Поскольку это минимум, то любой алгоритм, который выполняет только один поиск на воксел, будет соответствовать вашим требованиям.
Одна упрощенная идея состоит в том, чтобы инициализировать массив для хранения счетчика для каждого вокселя, затем посмотреть на каждый воксел и увеличить число соседей этого вокселя в массиве.
Псевдо C может выглядеть примерно так:
#define MAXX 100
#define MAXY 100
#define MAXZ 100
int x, y, z
char countArray[MAXX][MAXY][MAXZ];
initializeCountArray(MAXX, MAXY, MAXZ); // Set all array elements to 0
for(x=0; x<MAXX; x++)
for(y=0;y<MAXY;y++)
for(z=0;z<MAXZ;z++)
if(VoxelExists(x,y,z))
incrementNeighbors(x,y,z);
Вам нужно написать initializeCountArray, чтобы он устанавливал все элементы массива в 0.
Что еще более важно, вам также нужно будет написать incrementNeighbors, чтобы он не увеличивался вне массива. Небольшое увеличение скорости здесь состоит в том, чтобы выполнить вышеуказанный алгоритм только для всех вокселей во внутренней части, а затем выполнить отдельный запуск для всех вокселей внешнего края с измененной процедурой incrementNeighbrs, которая понимает, что на одной стороне не будет соседей.
Этот алгоритм приводит к 1 поиску на воксел и не более 26 байтов на каждый воксел. Если ваше воксельное пространство редкое, это приведет к очень небольшому (относительному) добавлению. Если ваше пространство вокселей очень плотное, вы можете подумать об обратном алгоритме - инициализировать массив значением 26 для каждой записи, а затем уменьшить число соседей, когда воксел не существует.
Результаты для данного вокселя (т. Е. Сколько у меня соседей?) Находятся в массиве. Если вам нужно узнать, сколько соседей имеет воксел 2,3,5, просто посмотрите на байт в countArray [2] [3] [5].
Массив будет потреблять 1 байт на воксель. Вы можете использовать меньше места и, возможно, немного увеличить скорость, упаковав байты.
Существуют лучшие алгоритмы, если вы знаете подробности о ваших данных. Например, очень разреженное пространство вокселей значительно выиграет от октри, где вы можете пропускать большие блоки поиска, когда вы уже знаете, что внутри нет заполненных вокселей. Однако для большинства этих алгоритмов по-прежнему требуется по крайней мере один поиск для каждого вокселя, чтобы заполнить их матрицу, но если вы выполняете несколько операций, они могут выиграть больше, чем эта одна операция.