Feedback

C# - CellMatrix

Veröffentlicht von am 22.12.2007
(2 Bewertungen)
Diese Klasse ermöglicht eine zweidimensionale Matrix eines bestimmten Typs. Die Werte können dann mit dem XY-Koordinatensystem angesprochen werden.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace ViperBytes.Collections
{
    /// <summary>
    /// CellMatrix is a two-dimensional matrix where you can get a type per xy-coordinate system.
    /// </summary>
    public class CellMatrix<T>
    {
        #region private fields
        /// <summary>
        /// Contains the values of type T
        /// </summary>
        private List<List<T>> data = new List<List<T>>();

        /// <summary>
        /// Contains width and height of matrix
        /// </summary>
        private Size size = new Size(0, 0);

        /// <summary>
        /// Specifyes, wheather values larger then size - 1 will start from zero
        /// example: x = width -> x = 0, x = -1 -> x = width - 1
        /// </summary>
        private bool infinite = false;
        #endregion

        #region properties
        /// <summary>
        /// Returns a value
        /// </summary>
        /// <param name="x">X-coordinate</param>
        /// <param name="y">Y-coordinate</param>
        /// <returns>Specifyed value</returns>
        public T this[int x, int y]
        {
            get
            {
                if (Infinite)
                {
                    while (x < 0)
                        x += this.size.Width;
                    while (x >= this.size.Width)
                        x -= this.size.Width;
                    while (y < 0)
                        y += this.size.Height;
                    while (y >= this.size.Height)
                        y -= this.size.Height;
                }

                return this.data[y][x];
            }
            set
            {
                if (Infinite)
                {
                    while (x < 0)
                        x += this.size.Width;
                    while (x >= this.size.Width)
                        x -= this.size.Width;
                    while (y < 0)
                        y += this.size.Height;
                    while (y >= this.size.Height)
                        y -= this.size.Height;
                }

                this.data[y][x] = value;
            }
        }

        /// <summary>
        /// Specifyes size of the matrix
        /// </summary>
        public Size Size
        {
            get
            {
                return this.size;
            }
            set
            {
                if (this.size != value)
                {
                    this.size = value;
                    Refresh();
                }
            }
        }

        /// <summary>
        /// Specifyes, wheather indexes larger then width-1 will start at zero
        /// </summary>
        public bool Infinite
        {
            get
            {
                return this.infinite;
            }
            set
            {
                if (this.infinite != value)
                {
                    this.infinite = value;
                }
            }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// The constructor
        /// </summary>
        public CellMatrix()
        { }

        /// <summary>
        /// The constructor
        /// </summary>
        /// <param name="width">Width of matrix</param>
        /// <param name="height">Height of matrix</param>
        public CellMatrix(int width, int height)
        {
            this.size = new Size(width, height);
            Refresh();
        }
        #endregion

        #region public members
        /// <summary>
        /// This will flip the matrix
        /// </summary>
        /// <param name="hor">Specifyes, wheather a horizontal flip will happen</param>
        /// <param name="ver">Specifyes, wheather a vertical flip will happen</param>
        public void Flip(bool hor, bool ver)
        {
            if ((!hor) && (!ver))
                return;

            List<List<T>> tmp = new List<List<T>>();

            for (int y = 0; y < this.size.Height; y++)
            {
                int y2 = (ver) ? 0 : tmp.Count;
                tmp.Insert(y2, new List<T>());
                for (int x = 0; x < this.size.Width; x++)
                {
                    int x2 = (hor) ? 0 : tmp[y2].Count;
                    tmp[y2].Insert(x2, this.data[y][x]);
                }
            }

            this.data = tmp;
        }
        #endregion

        #region private members
        /// <summary>
        /// That will adjust the two dimensional list to the size values
        /// </summary>
        private void Refresh()
        {
            if (this.data.Count < this.size.Height)
            {
                int diff = this.size.Height - this.data.Count;
                for (int i = 0; i < diff; i++)
                    this.data.Add(new List<T>());
            }
            else if (this.data.Count > this.size.Height)
            {
                int diff = this.data.Count - this.size.Height;
                for (int i = 0; i < diff; i++)
                    this.data.RemoveAt(this.data.Count - 1);
            }
            for (int y = 0; y < this.size.Height; y++)
            {
                if (this.data[y].Count < this.size.Width)
                {
                    int diff = this.size.Width - this.data[y].Count;
                    for (int i = 0; i < diff; i++)
                        this.data[y].Add((T)new object());
                }
                else if (this.data[y].Count > this.size.Width)
                {
                    int diff = this.data[y].Count - this.size.Width;
                    for (int i = 0; i < diff; i++)
                        this.data[y].RemoveAt(this.data[y].Count - 1);
                }
            }
        }
        #endregion
    }
}

1 Kommentare zum Snippet

Günther Foidl schrieb am 01.10.2008:
Viel Aufwand um die Arrays neu zu "definieren".
T[,] entspricht auch dem. Nur der Zugriff erfolgt über Indizes statt über Koordinaten und das Stürzen wird als Transponieren bezeichnet.
 

Logge dich ein, um hier zu kommentieren!