2016-03-20 14 views
0

私はバッファのスライスを抽出できるC#.NETの3次元循環バッファの実装を探しています。3次元循環バッファ

多次元配列を試しましたが、バッファの特定のスライスを取得できません。

私はまた、ジャグ配列を使用したバージョンを実装しようとしましたが、私は行列をinitialzieする方法を理解する上で、また、スライス抽出にいくつかの問題を見つけることがあります。

ありがとうございました。

[編集1] バッファはreltimeセンサーからのデータを格納するために使用され、幅の高さが固定され、深さ(円形部分である時間)はユーザーによって定義されます。私が必要

スライスは、固定サイズの行列(所与の時間のデータと幅とheigh)であろう。

[EDIT 2] 私が動作する実装することができる唯一の実装。ジャグ配列で、私はまだ私が正しくあなたの要件を理解していれば、あなたは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

ようこそ。表示するコードは? – MickyD

答えて

1

私はこれらを2つのクラスに分割します。 CircularBufferクラスのような、読み取りと書き込みを処理するクラスが必要です。もう1つは、保存したい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; } 
} 

これはinduvidual 'フレーム' /スライスを読み書きの世話をします。このクラスを展開すると、インデックスを読むことができます。

注:

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(); 
    } 
} 

:バッファこれは循環バッファ内に格納された2Dバッファの実装可能性があり


いっぱいになった場合、書き込みはfalseを返しますこのクラスは次のように使用できます:

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#がcicularバッファタイプを持っていますが、常に1つを自分で作成することができません。 - その後、あなたのデータを格納するためのクラスを作成

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(); 

明らかに、記入する必要がありますが、開始する必要があります。