2016-03-20 5 views
0

Я ищу реализацию трехмерного кругового буфера в C# .NET, который позволяет мне извлекать фрагменты буфера.Трехмерный круговой буфер

Я пробовал многомерный массив, но он не позволяет мне получить определенный кусок буфера.

Я также попытался реализовать версию с использованием jagged массива, но у меня есть некоторые проблемы в понимании того, как инициализировать матрицу, а также в извлечении срезов.

Спасибо за помощь.

[РЕДАКТИРОВАТЬ 1] Буфер будет использоваться для хранения данных от датчиков reltime, он будет фиксирован по ширине, а глубина (время, которое является круговой частью) будет определяться пользователем.

Ломтики, которые мне нужны, будут матрицей фиксированного размера (ширина и высота с данными заданного времени).

[EDIT 2] Единственная реализация, которую я мог бы реализовать, работает. С неровными массива я все еще застряли в декларации (я нахожу это хаотическое)

public class CircularBufferMatrix<T> 
{ 
    private readonly T[,,] _buffer; 

    public CircularBufferMatrix(int width, int height, int depth) 
    { 
     Width = width; 
     Height = height; 
     Depth = depth; 
     _buffer = new T[width, height, depth]; 
    } 

    public T this[int x, int y, int z] 
    { 
     set { _buffer[x, y, z%Depth] = value; } 
     get { return _buffer[x, y, z%Depth]; } 
    } 

    #region Getters 

    public int Width { get; } 

    public int Height { get; } 

    public int Depth { get; } 

    #endregion 
} 
+0

Хммм, я думаю, вам нужно быть более точным в ваших требованиях! Являются ли срезы, которые вы хотите извлечь, всегда одного размера и содержат одни и те же данные? – Skizz

+0

@Skizz Привет, я обновил вопрос, спасибо за помощь –

+0

Добро пожаловать в SO. Любой код для показа? – MickyD

ответ

1

Я бы разделил их на два класса. Вы хотите что-то вроде класса CircularBuffer, который обрабатывает чтение и запись. Другой может быть реализация 2D-массива, который вы хотите сохранить. Причина их разделения состоит в том, что вы хотите отдельно читать/записывать кадры.

Например:


Круговая реализация буфера:

public class CircularBuffer<T> 
{ 
    private T[] _buffer; 

    private int IncRollover(int value) 
    { 
     value++; 
     if (value >= _buffer.Length) 
      value = 0; 

     return value; 
    } 

    public CircularBuffer(int count) 
    { 
     _buffer = new T[count]; 
    } 

    public bool Write(T element) 
    { 
     // if the writeindex (after increasing) equals the readindex, the buffer is full 
     var newWriteIndex = IncRollover(WriteIndex); 
     if (newWriteIndex == ReadIndex) 
      return false; 

     _buffer[WriteIndex] = element; 

     WriteIndex = newWriteIndex; 
     return true; 
    } 

    public bool TryRead(out T element) 
    { 
     if (ReadIndex == WriteIndex) 
     { 
      element = default(T); 
      return false; 
     } 

     element = _buffer[ReadIndex]; 
     ReadIndex = IncRollover(ReadIndex); 

     return true; 
    } 

    public IEnumerable<T> ReadAll() 
    { 
     T element; 
     while (TryRead(out element)) 
      yield return element; 
    } 


    public int ReadIndex { get; private set; } 
    public int WriteIndex { get; private set; } 
} 

Это будет заботиться о чтении и записи 'кадры Вашему индивидуальному'/ломтиков. Вы можете расширить этот класс, если хотите читать по индексу.

примечание: запись будет возвращать ложь, если буфер заполнен


Это может быть реализация 2d буферов, хранящихся в кольцевом буфере:

public class MyWhateverBuffer<T> 
{ 
    private CircularBuffer<T[,]> _buffer; 

    public int Width { get; private set; } 
    public int Height { get; private set; } 
    public int Depth { get; private set; } 

    public MyWhateverBuffer(int width, int height, int depth) 
    { 
     Width = width; 
     Height = height; 
     Depth = depth; 
     _buffer = new CircularBuffer<T[,]>(depth); 
    } 

    public T[,] New() 
    { 
     return new T[Width, Height]; 
    } 

    public bool Add(T[,] buffer) 
    { 
     return _buffer.Write(buffer); 
    } 

    public bool TryRead(out T[,] buffer) 
    { 
     return _buffer.TryRead(out buffer); 
    } 

    public IEnumerable<T[,]> ReadAll() 
    { 
     return _buffer.ReadAll(); 
    } 
} 

Этот класс может использоваться как:

MyWhateverBuffer<double> myBuffer = new MyWhateverBuffer<double>(100, 100, 100); 

var oneSlice = myBuffer.New(); 

oneSlice[10, 10] = 3.5; 
oneSlice[50, 10] = 23.5; 
oneSlice[10, 20] = 43.5; 

myBuffer.Add(oneSlice); 

var anotherSlice = myBuffer.New(); 

anotherSlice[10, 10] = 13.5; 
anotherSlice[50, 10] = 23.5; 
anotherSlice[10, 20] = 43.5; 

var result = myBuffer.Add(anotherSlice); 

if(!result) 
{ 
    // the buffer was full.. 
} 

// Read the results from the buffer. 
foreach(var slice in myBuffer.ReadAll()) 
{ 
    Trace.WriteLine(slice[10, 10]); 
} 

Вы всегда должны проверить, можно ли добавить буфер. Вы не хотите потерять информацию.


Примечание стороны:

Наиболее получает прибыль с круговым буфером декларирует те элементы. Как большие массивы будут использоваться каждый раз.

0

Если я правильно понимаю ваши требования правильно, вы хотите, кольцевой буфер, состоящий из элементов, которые являются двумерными массивами данных и данных из одного предмета никогда не повторяется в других пунктах. C# не имеет Создание кольцевых типа буфера, но вы всегда можете создать самостоятельно: -

public class CircularBuffer <T> // make it generic 
{ 
    public class Iterator 
    { 
    public void MoveForward(); 
    public void MoveBackward(); 
    public T Item { get { } }; 

    CicrcularBuffer <T> m_container; 
    LinkedListNode <T> m_current_item; 
    } 

    public void Add (T item); 
    public Iterator GetIterator(); 

    LinkedList<T> m_data; 
} 

Затем создайте класс, чтобы содержать свои данные: -

public class SensorData 
{ 
    // contains the two dimension data 
} 

И использовать его как: -

var buffer = new CircularBuffer <SensorData>(); 
var iterator = buffer.GetIterator(); 
var item = iterator.Item; 
iterator.MoveForward(); 

Очевидно, что есть много, чтобы его заполнили, но он должен вас начать.

Смежные вопросы