Thread: Overloading + and - for Matrices..

  1. #1
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968

    Overloading + and - for Matrices..

    Okay, maybe I'm really bad at google searching, or maybe there just isn't much information on the subject because it is iffy, or maybe there isn't information because it is so elementary, but what am I missing?

    I understand that [1 1 1 1] + [1 1 1 1] = [2 2 2 2]

    but what about doing a 2 dimensional matrix?

    A[4][4] + B[4][4]

    I understand how to do this on paper, but in code?

    [1 1 1 1] [1 1 1 1] [2 2 2 2]
    [1 1 1 1] + [1 1 1 1] = [2 2 2 2]
    [1 1 1 1] [1 1 1 1] [2 2 2 2]
    [1 1 1 1] [1 1 1 1] [2 2 2 2]

    do we loop through rows then columns?

    or columns then rows?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  2. #2
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Would it yield different results either way?
    Sent from my iPadŽ

  3. #3
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Hm, no...

    And besides, I figured out that I'm just being inept at doing research...

    I have a matrix library here I got from gamedev, it didn't come with overloaded + and - operators. But I did notice it did come with some crazy reading and writing functions...

    I'll post it up

    Code:
    class Matrix4 
    {
    public:
    	Matrix4 (void) {}
    	
    	// When defining matrices in C arrays, it is easiest to define them with
    	// the column increasing fastest.  However, some APIs (OpenGL in particular) do this
    	// backwards, hence the "constructor" from C matrices, or from OpenGL matrices.
    	// Note that matrices are stored internally in OpenGL format.
    	void C_Matrix (scalar_t* initArray)
    	{ int i = 0; for (int y=0;y<4;++y) for (int x=0;x<4;++x) (*this)(x)[y] = initArray[i++]; }
    	void OpenGL_Matrix (scalar_t* initArray)
    	{ int i = 0; for (int x = 0; x < 4; ++x) for (int y=0;y<4;++y) (*this)(x)[y] = initArray[i++]; }
    	
    	// [] is to read, () is to write (const correctness)
    	// m[x][y] or m(x)[y] is the correct form
    	const scalar_t* operator[] (int i) const { return &e[i<<2]; }
    	scalar_t* operator() (int i) { return &e[i<<2]; }
    	
    	// Low-level access to the array.
    	const scalar_t* readArray (void) { return e; }
    	scalar_t* getArray(void) { return e; }
    
    	// Construct various matrices; REPLACES CURRENT CONTENTS OF THE MATRIX!
    	// Written this way to work in-place and hence be somewhat more efficient
    	void Identity (void) { for (int i=0;i<16;++i) e[i] = 0; e[0] = 1; e[5] = 1; e[10] = 1; e[15] = 1; }
    	inline Matrix4& Rotation (scalar_t angle, Vector4 axis);
    	inline Matrix4& Translation(const Vector4& translation);
    	inline Matrix4& Scale (scalar_t x, scalar_t y, scalar_t z);
    	inline Matrix4& BasisChange (const Vector4& v, const Vector4& n);
    	inline Matrix4& BasisChange (const Vector4& u, const Vector4& v, const Vector4& n);
    	inline Matrix4& ProjectionMatrix (bool perspective, scalar_t l, scalar_t r, scalar_t t, scalar_t b, scalar_t n, scalar_t f);
    	
    private:
    	scalar_t e[16];
    };
    After that I'm hoping you can understand why I was having trouble adding two of these objects together..

    Here is what it boils down to..

    Code:
    	for(int i = 0; i<16; i++)
    	{
    		m3.getArray()[i] = m1.readArray()[i] + m2.readArray()[i];
    		std::cout << m3.readArray()[i];
    	}
    Or you could do += the same way with only 2 matrices.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    another common approach:

    Code:
    Matrix4 &
    add(const Matrix4 & rhs)
    {
    	/* code */
    	return *this;
    }
    
    inline
    Matrix4 &
    operator += (const Matrix4 & rhs)
    {
    	return add(rhs);
    }
    
    inline
    Matrix4 
    plus(const Matrix4 & rhs)
    {
    	return Matrix4(*this).add(rhs);
    }
    
    inline
    Matrix4 
    operator + (const Matrix4 & rhs)
    {
    	return plus(rhs);
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Lol, trying to piece that code together without an example of usage is killing my 3am brain for order of operations...

    *dies*

    Lol, example of usage please?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    it just simplifies the amount of coding needed (since it can be adapted to just about any set of operators).
    the syntax would be just as you would use with an ordinary number, ie:

    Matrix4 x = (y + z);
    x += a;

    another useful trick is when coding the comparison operators:

    Code:
    friend
    int
    compare(const Matrix4 & lhs, const Matrix4 & rhs)
    {
    	/*
    	if lhs > rhs, return 1
    	else if rhs > lhs return -1
    	else return 0
    	*/
    }
    
    inline
    bool
    operator == (const Matrix4 & rhs)
    {
    	return compare(*this, rhs) == 0;
    }
    
    inline
    bool
    operator != (const Matrix4 & rhs)
    {
    	return compare(*this, rhs) != 0;
    }
    
    inline
    bool
    operator >= (const Matrix4 & rhs)
    {
    	return compare(*this, rhs) >= 0;
    }
    
    inline
    bool
    operator > (const Matrix4 & rhs)
    {
    	return compare(*this, rhs) > 0;
    }
    
    inline
    bool
    operator <= (const Matrix4 & rhs)
    {
    	return compare(*this, rhs) <= 0;
    }
    
    inline
    bool
    operator < (const Matrix4 & rhs)
    {
    	return compare(*this, rhs) < 0;
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    That is pretty nifty Sebastiani, I'll probably get to implementing that tomorrow...

    After I do that, and rework my renderer to pull the rotation and translation information from the combined matrix and use it to render a final picture out of a single 16 element array, I can hard code a scene!

    Sweet...

    Then I gotta manage the creation and destruction of scene nodes (scary topic to get into atm)
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

Popular pages Recent additions subscribe to a feed