Представление трехмерного массива в виде одномерного
От: Javaec  
Дата: 07.12.13 20:19
Оценка:
Всем привет.

Пишу класс для хранения трехмерного массива в линейном и реализации всех возможных операций.

Странно, что мне не помог ни гугл ни stackoverflow.

Есть множество объектов в трехмерном пространстве. У каждого объекта целочисленные координаты, хранятся в Vector3(x,y,z).
Множество объектов мы получаем постепенно, т.е. сначала 0 объектов, потом 1, потом еще 1...

Допустим, все объекты будем хранить в трехмерном массиве.
Индексы массива начинаются с 0, значит будем сохранять минимальные координаты и максимальные. По этой паре векторов будет определяться размер массива и смещение координат в нем.

Иногда массив нужно будет ресайзить. Но увеличиваться он будет до определенного размера.

Элемент с определенным индексом в массиве имеет координаты зависящие от индекса и сохраненных Min Max векторов.

И теперь, самое сложное. Множество объектов "скроллится". Т.е. данные, например по -x,-y,z становятся неактуальными их нужно удалить, сместив все элементы внутри массива по этим осям на 1.
А в x,y,-z тут же будут записаны новые, актуальные элементы. И Min Max векторы нужно будет пересчитывать.


И наконец, ожидается огромное количество итераций, значит, ради экономии времени, хранить всё будем в одномерном массиве.

Начал писать класс, но уже есть проблемы. Несколько элементов, занесенных в массив в самом начале методом AddOrReplace когда еще Size == (1,1,1), после самого первого ресайза, "теряются".
Кроме того, иногда вылетает OutOfBounds на T val = oldArr[(...

Очень прошу помощи, любой, от кода до совета. И подскажите, есть ли готовые классы для решения моей задачи.



public class Arr3D<T> {

private T[] arr;
private Vector3 min, max;
private Vector3 size;

public Arr3D() 
{
    arr = new T[0];
}

public void AddOrReplace(T obj, Vector3 pos) 
{
    Vector3 newMin = Vector3.Min(min, pos); // ( Min(x1,x2), Min(y1,y2), ...
    Vector3 newMax = Vector3.Max(max, pos+Vector3.one); // +(1,1,1)

    if(newMin != min || newMax != max) 
    {
        Resize(newMin, newMax);
    }

    Set(obj, pos);
}

public void Set(T obj, Vector3 pos) 
{
    Set(obj, pos.x, pos.y, pos.z);
}

public void Set(T obj, int x, int y, int z) 
{
    arr[ (y-min.y)*size.x*size.y  +  (z-min.z)*size.x + (x-min.x) ] = obj;
}

private void Resize(Vector3 newMin, Vector3 newMax) 
{
    Vector3 oldMin = min;
    Vector3 oldMax = max;
    T[] oldArr = arr;
    Vector3 oldSize = size;

    min = newMin;
    max = newMax;
    size = newMax - newMin;
    arr = new T[size.z*size.y*size.x];

    for(int x=oldMin.x; x<oldMax.x; x++) 
    {
        for(int y=oldMin.y; y<oldMax.y; y++) 
        {
            for(int z=oldMin.z; z<oldMax.z; z++) 
            {
                T val = oldArr[(y-oldMin.y)*oldSize.x*oldSize.y  +  (z-oldMin.z)*oldSize.x + (x-oldMin.x)];
                Set(val, x, y, z);
            }
        }
    }

}

public T Get(int x, int y, int z) 
{
    return arr[(y-min.y)*size.x*size.y  +  (z-min.z)*size.x + (x-min.x)];
}
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.