A library to manipulate 2D arrays, and output them to an LED Dot Matrix Display. The display must be wired up using a shift register combined with a nor latch.

Matrix.h

Committer:
EricWieser
Date:
2012-02-13
Revision:
1:44819562ea31
Parent:
0:1deae5ffe9ed

File content as of revision 1:44819562ea31:

#include <cassert> 
#include "Locations.h"

#ifndef Matrix_H
#define Matrix_H
template <class T> class Matrix {
  private:
    //Internal data
    T* _data;
    int _width;
    int _height;
    
    //Unsafe cell accessors
    const T& item(int x, int y) const { return _data[y*_width + x]; }
          T& item(int x, int y)       { return _data[y*_width + x]; }
    
    //Initializer
    void init() { _data = new T[_width*_height]; }
  public:
    //Construct an empty matrix
    Matrix(int width, int height) : _width(width), _height(height) { init(); }
    
    //Construct a matrix from a 2D array
    template <int w, int h>
    Matrix(T (&array)[h][w]) : _width(w), _height(h) {
        init();
        
        for(int x = 0; x < w; x++)
            for(int y = 0; y < h; y++)
                item(x, y) = array[y][x];
    }
    
    //Copy constructor
    Matrix(const Matrix<T> &that) : _width(that._width), _height(that._height) {
        init();
       
        for(int i = 0; i < _width; i++)
            for(int j = 0; j < _height; j++)
                this->item(i, j) = that.item(i, j);
    }
    
    //Destructor - clean up pointers
    ~Matrix() { delete [] _data; }
    
    //Size accessors
    int getWidth()  const { return _width; }
    int getHeight() const { return _height; }
    
    //Bounds checking
    bool contains(int x, int y) const {
        return x >= 0 && x < _width && y >= 0 && y < _height;
    }
    bool containsRect(int x, int y, int w, int h) const {
        return x >= 0 && x + w <= _width && y >= 0 && y + h <= _height;
    }
    
    //Safe cell accessors
    const T& operator() (int x, int y) const { assert(contains(x, y)); return item(x, y); }
          T& operator() (int x, int y)       { assert(contains(x, y)); return item(x, y); }
    const T& operator[] (const Location<int> &p) const { return (*this)(p.x, p.y); }
          T& operator[] (const Location<int> &p)       { return (*this)(p.x, p.y); }
    
    //Row and column accessors
    T* column(int x) const {
        assert(x >= 0 && x <= _width);
        T* col = new T[_height];
        for(int j = 0; j < _height; j++) {
            col[j] = this->item(x, j);
        }
        return col;        
    }
    T* row(int y) const {
        assert(y >= 0 && y <= _height);
        T* row = new T[_width];
        for(int i = 0; i < _width; i++) {
            row[i] = this->item(i, y);
        }
        return row;        
    }
    
    //Cut out a rectangle from an existing matrix
    Matrix<T> slice(int x, int y, int w, int h) const {
        assert(containsRect(x, y, w, h));
        
        Matrix<T> m = Matrix<T>(w, h);
        
        for(int i = 0; i < w; i++)
            for(int j = 0; j < h; j++)
                m.item(i, j) = this->item(x + i, y + j);
                
        return m;
    }
    
    //Copy the data in the rectangle (sx, sy, w, h) from "that" to "this" at (dx, dy)
    void overlay(const Matrix<T> &that, int sx, int sy, int w, int h, int dx, int dy) {
        assert(containsRect(dx, dy, w, h) && that.containsRect(sx, sy, w, h));
        
        for(int x = 0; x < w; x++) {
            for(int y = 0; y < h; y++) {
                this->item(dx + x, dy + y) = that.item(sx + x, sy + y);
            }
        }
    }
    
    //Empty the matrix
    void clear() {
        for(int x = 0; x < _width; x++)
            for(int y = 0; y < _height; y++)
                this->item(x, y) = T();
    }
};
#endif