⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix.h

📁 一个纹理地形渲染器
💻 H
📖 第 1 页 / 共 2 页
字号:
        /// determine if matrix is invertible.
        /// note: only checks 3x3 sub matrix determinant.

	    bool invertible() const
	    {
		    return !Float::equal(determinant(),0);
	    }

        /// calculate inverse of matrix.

	    Matrix inverse() const
	    {
		    Matrix matrix;
		    inverse(matrix);
		    return matrix;
	    }

        /// calculate inverse of matrix and write result to parameter matrix.

        void inverse(Matrix &inverse) const
        {
		    const float determinant = this->determinant();

		    assert(!Float::equal(determinant,0));

	        float k = 1.0f / determinant;

	        inverse.m11 = (m22*m33 - m32*m23) * k;
	        inverse.m12 = (m32*m13 - m12*m33) * k;
	        inverse.m13 = (m12*m23 - m22*m13) * k;
	        inverse.m21 = (m23*m31 - m33*m21) * k;
	        inverse.m22 = (m33*m11 - m13*m31) * k;
	        inverse.m23 = (m13*m21 - m23*m11) * k;
	        inverse.m31 = (m21*m32 - m31*m22) * k;
	        inverse.m32 = (m31*m12 - m11*m32) * k;
	        inverse.m33 = (m11*m22 - m21*m12) * k;

	        inverse.m14 = -(inverse.m11*m14 + inverse.m12*m24 + inverse.m13*m34);
	        inverse.m24 = -(inverse.m21*m14 + inverse.m22*m24 + inverse.m23*m34);
	        inverse.m34 = -(inverse.m31*m14 + inverse.m32*m24 + inverse.m33*m34);

	        inverse.m41 = m41;
	        inverse.m42 = m42;
	        inverse.m43 = m43;
	        inverse.m44 = m44;
        }

        /// calculate transpose of matrix.

	    Matrix transpose() const
	    {
		    Matrix matrix;
		    transpose(matrix);
		    return matrix;
	    }

        /// calculate transpose of matrix and write to parameter matrix.

	    void transpose(Matrix &transpose) const
        {
            transpose.m11 = m11;
            transpose.m12 = m21;
            transpose.m13 = m31;
            transpose.m14 = m41;
            transpose.m21 = m12;
            transpose.m22 = m22;
            transpose.m23 = m32;
            transpose.m24 = m42;
            transpose.m31 = m13;
            transpose.m32 = m23;
            transpose.m33 = m33;
            transpose.m34 = m43;
            transpose.m41 = m14;
            transpose.m42 = m24;
            transpose.m43 = m34;
            transpose.m44 = m44;
        }

        /// transform a vector by this matrix.
        /// the convention used is post-multiplication by a column vector: x=Ab.

        void transform(Vector &vector) const
        {
		    float x = vector.x * m11 + vector.y * m12 + vector.z * m13 + m14;
            float y = vector.x * m21 + vector.y * m22 + vector.z * m23 + m24;
            float z = vector.x * m31 + vector.y * m32 + vector.z * m33 + m34;
		    vector.x = x;
		    vector.y = y;
		    vector.z = z;
        }

        /// transform a vector by this matrix, store result in parameter.
        /// the convention used is post-multiplication by a column vector: x=Ab.

        void transform(const Vector &vector, Vector &result) const
        {
            result.x = vector.x * m11 + vector.y * m12 + vector.z * m13 + m14;
            result.y = vector.x * m21 + vector.y * m22 + vector.z * m23 + m24;
            result.z = vector.x * m31 + vector.y * m32 + vector.z * m33 + m34;
        }

        /// add another matrix to this matrix.

	    void add(const Matrix &matrix)
	    {
            m11 += matrix.m11;
            m12 += matrix.m12;
            m13 += matrix.m13;
            m14 += matrix.m14;
            m21 += matrix.m21;
            m22 += matrix.m22;
            m23 += matrix.m23;
            m24 += matrix.m24;
            m31 += matrix.m31;
            m32 += matrix.m32;
            m33 += matrix.m33;
            m34 += matrix.m34;
            m41 += matrix.m41;
            m42 += matrix.m42;
            m43 += matrix.m43;
            m44 += matrix.m44;
	    }

        /// subtract a matrix from this matrix.

	    void subtract(const Matrix &matrix)
	    {
            m11 -= matrix.m11;
            m12 -= matrix.m12;
            m13 -= matrix.m13;
            m14 -= matrix.m14;
            m21 -= matrix.m21;
            m22 -= matrix.m22;
            m23 -= matrix.m23;
            m24 -= matrix.m24;
            m31 -= matrix.m31;
            m32 -= matrix.m32;
            m33 -= matrix.m33;
            m34 -= matrix.m34;
            m41 -= matrix.m41;
            m42 -= matrix.m42;
            m43 -= matrix.m43;
            m44 -= matrix.m44;
	    }

        /// multiply this matrix by a scalar.

	    void multiply(float scalar)
	    {
            m11 *= scalar;
            m12 *= scalar;
            m13 *= scalar;
            m14 *= scalar;
            m21 *= scalar;
            m22 *= scalar;
            m23 *= scalar;
            m24 *= scalar;
            m31 *= scalar;
            m32 *= scalar;
            m33 *= scalar;
            m34 *= scalar;
            m41 *= scalar;
            m42 *= scalar;
            m43 *= scalar;
            m44 *= scalar;
	    }

        /// multiply two matrices.
        /// note: this is a full 4x4 matrix multiplication.

	    void multiply(const Matrix &matrix, Matrix &result)
        {
            result.m11 = m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31 + m14*matrix.m41;
            result.m12 = m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32 + m14*matrix.m42;
            result.m13 = m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33 + m14*matrix.m43;
            result.m14 = m11*matrix.m14 + m12*matrix.m24 + m13*matrix.m34 + m14*matrix.m44;
            result.m21 = m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31 + m24*matrix.m41;
            result.m22 = m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32 + m24*matrix.m42;
            result.m23 = m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33 + m24*matrix.m43;
            result.m24 = m21*matrix.m14 + m22*matrix.m24 + m23*matrix.m34 + m24*matrix.m44;
            result.m31 = m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31 + m34*matrix.m41;
            result.m32 = m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32 + m34*matrix.m42;
            result.m33 = m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33 + m34*matrix.m43;
            result.m34 = m31*matrix.m14 + m32*matrix.m24 + m33*matrix.m34 + m34*matrix.m44;
            result.m41 = m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + m44*matrix.m41;
            result.m42 = m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + m44*matrix.m42;
            result.m43 = m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + m44*matrix.m43;
            result.m44 = m41*matrix.m14 + m42*matrix.m24 + m43*matrix.m34 + m44*matrix.m44;
        }

        /// equals operator

	    bool operator ==(const Matrix &other) const
	    {
		    if (Float::equal(m11,other.m11) &&
			    Float::equal(m12,other.m12) &&
			    Float::equal(m13,other.m13) &&
			    Float::equal(m14,other.m14) &&
			    Float::equal(m21,other.m21) &&
			    Float::equal(m22,other.m22) &&
			    Float::equal(m23,other.m23) &&
			    Float::equal(m24,other.m24) &&
			    Float::equal(m31,other.m31) &&
			    Float::equal(m32,other.m32) &&
			    Float::equal(m33,other.m33) &&
			    Float::equal(m34,other.m34) &&
			    Float::equal(m41,other.m41) &&
			    Float::equal(m42,other.m42) &&
			    Float::equal(m43,other.m43) &&
			    Float::equal(m44,other.m44)) return true;
		    else return false;
	    }

        /// not equals operator

	    bool operator !=(const Matrix &other) const
	    {
		    return !(*this==other);
	    }

        /// cute access to matrix elements via overloaded () operator.
        /// use it like this: Matrix matrix; float element = matrix(row, column);

	    float operator()(int i, int j) const
	    {
		    assert(i>=1);
		    assert(i<=4);
		    assert(j>=1);
		    assert(j<=4);
		    const float *data = &m11;
		    return data[(i<<2) + j];
	    }

		/// cute access to basis vectors of 3x3 submatrix

		const Vector& i() const
		{
			return *((Vector*)&m11);
		}

		const Vector& j() const
		{
			return *((Vector*)&m21);
		}

		const Vector& k() const
		{
			return *((Vector*)&m31);
		}

		/// print a basic representation of the matrix data to stdout.

	    void print() const
	    {
		    printf("Matrix[(%f, %f, %f, %f) | (%f, %f, %f, %f) | (%f, %f, %f, %f) | (%f, %f, %f, %f)]", m11,m12,m13,m14,m21,m22,m23,m24,m31,m32,m33,m34,m41,m42,m43,m44);
	    }

	    friend inline Matrix operator-(const Matrix &a);
	    friend inline Matrix operator+(const Matrix &a, const Matrix &b);
	    friend inline Matrix operator-(const Matrix &a, const Matrix &b);
	    friend inline Matrix operator*(const Matrix &a, const Matrix &b);
	    friend inline Matrix& operator+=(Matrix &a, const Matrix &b);
	    friend inline Matrix& operator-=(Matrix &a, const Matrix &b);
	    friend inline Matrix& operator*=(Matrix &a, const Matrix &b);

	    friend inline Vector operator*(const Matrix &matrix, const Vector &vector);
	    friend inline Vector operator*(const Vector &vector, const Matrix &matrix);
	    friend inline Vector& operator*=(Vector &vector, const Matrix &matrix);

	    friend inline Matrix operator*(const Matrix &a, float s);
	    friend inline Matrix operator/(const Matrix &a, float s);
	    friend inline Matrix& operator*=(Matrix &a, float s);
	    friend inline Matrix& operator/=(Matrix &a, float s);
	    friend inline Matrix operator*(float s, const Matrix &a);
	    friend inline Matrix& operator*=(float s, Matrix &a);

        float m11,m12,m13,m14;			// 4x4 matrix, index m[row][column], convention: pre-multiply column vector, Ax = b
        float m21,m22,m23,m24;          // hence: (m11,m21,m31) make up the x axis of the 3x3 sub matrix,
        float m31,m32,m33,m34;          // and (m14,m24,m34) is the translation vector.
        float m41,m42,m43,m44;
    };


    inline Matrix operator-(const Matrix &a)
    {
	    return Matrix(-a.m11, -a.m12, -a.m13, -a.m14,
				      -a.m21, -a.m22, -a.m23, -a.m24,
				      -a.m31, -a.m32, -a.m33, -a.m34,
				      -a.m41, -a.m42, -a.m43, -a.m44);
    }

    inline Matrix operator+(const Matrix &a, const Matrix &b)
    {
	    return Matrix(a.m11+b.m11, a.m12+b.m12, a.m13+b.m13, a.m14+b.m14,
				      a.m21+b.m21, a.m22+b.m22, a.m23+b.m23, a.m24+b.m24,
				      a.m31+b.m31, a.m32+b.m32, a.m33+b.m33, a.m34+b.m34,
				      a.m41+b.m41, a.m42+b.m42, a.m43+b.m43, a.m44+b.m44);
    }

    inline Matrix operator-(const Matrix &a, const Matrix &b)
    {
	    return Matrix(a.m11-b.m11, a.m12-b.m12, a.m13-b.m13, a.m14-b.m14,
				      a.m21-b.m21, a.m22-b.m22, a.m23-b.m23, a.m24-b.m24,
				      a.m31-b.m31, a.m32-b.m32, a.m33-b.m33, a.m34-b.m34,
				      a.m41-b.m41, a.m42-b.m42, a.m43-b.m43, a.m44-b.m44);
    }

    inline Matrix operator*(const Matrix &a, const Matrix &b)
    {
	    return Matrix(a.m11*b.m11 + a.m12*b.m21 + a.m13*b.m31 + a.m14*b.m41,
				      a.m11*b.m12 + a.m12*b.m22 + a.m13*b.m32 + a.m14*b.m42,
				      a.m11*b.m13 + a.m12*b.m23 + a.m13*b.m33 + a.m14*b.m43,
				      a.m11*b.m14 + a.m12*b.m24 + a.m13*b.m34 + a.m14*b.m44,
				      a.m21*b.m11 + a.m22*b.m21 + a.m23*b.m31 + a.m24*b.m41,
				      a.m21*b.m12 + a.m22*b.m22 + a.m23*b.m32 + a.m24*b.m42,
				      a.m21*b.m13 + a.m22*b.m23 + a.m23*b.m33 + a.m24*b.m43,
				      a.m21*b.m14 + a.m22*b.m24 + a.m23*b.m34 + a.m24*b.m44,
				      a.m31*b.m11 + a.m32*b.m21 + a.m33*b.m31 + a.m34*b.m41,
				      a.m31*b.m12 + a.m32*b.m22 + a.m33*b.m32 + a.m34*b.m42,
				      a.m31*b.m13 + a.m32*b.m23 + a.m33*b.m33 + a.m34*b.m43,
				      a.m31*b.m14 + a.m32*b.m24 + a.m33*b.m34 + a.m34*b.m44,
				      a.m41*b.m11 + a.m42*b.m21 + a.m43*b.m31 + a.m44*b.m41,
				      a.m41*b.m12 + a.m42*b.m22 + a.m43*b.m32 + a.m44*b.m42,
				      a.m41*b.m13 + a.m42*b.m23 + a.m43*b.m33 + a.m44*b.m43,
				      a.m41*b.m14 + a.m42*b.m24 + a.m43*b.m34 + a.m44*b.m44);
    }

    inline Matrix& operator+=(Matrix &a, const Matrix &b)
    {
	    a.add(b);
	    return a;
    }

    inline Matrix& operator-=(Matrix &a, const Matrix &b)
    {
	    a.subtract(b);
	    return a;
    }

    inline Matrix& operator*=(Matrix &a, const Matrix &b)
    {
	    a = Matrix(a.m11*b.m11 + a.m12*b.m21 + a.m13*b.m31 + a.m14*b.m41,
			       a.m11*b.m12 + a.m12*b.m22 + a.m13*b.m32 + a.m14*b.m42,
			       a.m11*b.m13 + a.m12*b.m23 + a.m13*b.m33 + a.m14*b.m43,
			       a.m11*b.m14 + a.m12*b.m24 + a.m13*b.m34 + a.m14*b.m44,
			       a.m21*b.m11 + a.m22*b.m21 + a.m23*b.m31 + a.m24*b.m41,
			       a.m21*b.m12 + a.m22*b.m22 + a.m23*b.m32 + a.m24*b.m42,
			       a.m21*b.m13 + a.m22*b.m23 + a.m23*b.m33 + a.m24*b.m43,
			       a.m21*b.m14 + a.m22*b.m24 + a.m23*b.m34 + a.m24*b.m44,
			       a.m31*b.m11 + a.m32*b.m21 + a.m33*b.m31 + a.m34*b.m41,
			       a.m31*b.m12 + a.m32*b.m22 + a.m33*b.m32 + a.m34*b.m42,
			       a.m31*b.m13 + a.m32*b.m23 + a.m33*b.m33 + a.m34*b.m43,
			       a.m31*b.m14 + a.m32*b.m24 + a.m33*b.m34 + a.m34*b.m44,
			       a.m41*b.m11 + a.m42*b.m21 + a.m43*b.m31 + a.m44*b.m41,
			       a.m41*b.m12 + a.m42*b.m22 + a.m43*b.m32 + a.m44*b.m42,
			       a.m41*b.m13 + a.m42*b.m23 + a.m43*b.m33 + a.m44*b.m43,
			       a.m41*b.m14 + a.m42*b.m24 + a.m43*b.m34 + a.m44*b.m44);
	    return a;											 
    }

    inline Vector operator*(const Matrix &matrix, const Vector &vector)
    {
	    return Vector(vector.x * matrix.m11 + vector.y * matrix.m12 + vector.z * matrix.m13 + matrix.m14,
				      vector.x * matrix.m21 + vector.y * matrix.m22 + vector.z * matrix.m23 + matrix.m24,
				      vector.x * matrix.m31 + vector.y * matrix.m32 + vector.z * matrix.m33 + matrix.m34);
    }

    inline Vector operator*(const Vector &vector, const Matrix &matrix)
    {
	    // when we premultiply x*A we assume the vector is a row vector

	    return Vector(vector.x * matrix.m11 + vector.y * matrix.m21 + vector.z * matrix.m31 + matrix.m41,
				      vector.x * matrix.m12 + vector.y * matrix.m22 + vector.z * matrix.m32 + matrix.m42,
                      vector.x * matrix.m13 + vector.y * matrix.m23 + vector.z * matrix.m33 + matrix.m43);
    }

    inline Vector& operator*=(Vector &vector, const Matrix &matrix)
    {
	    // equivalent to: vector = matrix * vector (not vector*matrix!)

	    const float rx = vector.x * matrix.m11 + vector.y * matrix.m12 + vector.z * matrix.m13 + matrix.m14;
	    const float ry = vector.x * matrix.m21 + vector.y * matrix.m22 + vector.z * matrix.m23 + matrix.m24;
	    const float rz = vector.x * matrix.m31 + vector.y * matrix.m32 + vector.z * matrix.m33 + matrix.m34;
	    vector.x = rx;
	    vector.y = ry;
	    vector.z = rz;
	    return vector;
    }
    	
    inline Matrix operator*(const Matrix &a, float s)
    {
	    return Matrix(s*a.m11, s*a.m12, s*a.m13, s*a.m14,
				      s*a.m21, s*a.m22, s*a.m23, s*a.m24,
				      s*a.m31, s*a.m32, s*a.m33, s*a.m34,
				      s*a.m41, s*a.m42, s*a.m43, s*a.m44);
    }

    inline Matrix operator/(const Matrix &a, float s)
    {
	    assert(s!=0);
	    const float inv = 1.0f / s;
	    return Matrix(inv*a.m11, inv*a.m12, inv*a.m13, inv*a.m14,
				      inv*a.m21, inv*a.m22, inv*a.m23, inv*a.m24,
				      inv*a.m31, inv*a.m32, inv*a.m33, inv*a.m34,
				      inv*a.m41, inv*a.m42, inv*a.m43, inv*a.m44);
    }

    inline Matrix& operator*=(Matrix &a, float s)
    {
	    a.multiply(s);
	    return a;
    }

    inline Matrix& operator/=(Matrix &a, float s)
    {
	    assert(s!=0);
	    a.multiply(1.0f/s);
	    return a;
    }

    inline Matrix operator*(float s, const Matrix &a)
    {
	    return Matrix(s*a.m11, s*a.m12, s*a.m13, s*a.m14,
				      s*a.m21, s*a.m22, s*a.m23, s*a.m24,
				      s*a.m31, s*a.m32, s*a.m33, s*a.m34,
				      s*a.m41, s*a.m42, s*a.m43, s*a.m44);
    }

    inline Matrix& operator*=(float s, Matrix &a)
    {
	    a.multiply(s);
	    return a;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -