Add Matrix4 Inverse and Transpose
Transpose is easy, with a bool flag to determine whether to access elements in row-major or column-major format. Inverse is more difficult, so this change only does translation inverses.
This commit is contained in:
parent
5b25b402c7
commit
4d4dc91ff4
3 changed files with 99 additions and 4 deletions
|
@ -65,7 +65,8 @@ Matrix4::Translation(Double x,
|
||||||
* charles::basics::Matrix4::Matrix4 --
|
* charles::basics::Matrix4::Matrix4 --
|
||||||
*/
|
*/
|
||||||
Matrix4::Matrix4()
|
Matrix4::Matrix4()
|
||||||
: mData()
|
: mData(),
|
||||||
|
mTransposed(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@ Matrix4::Matrix4()
|
||||||
* charles::basics::Matrix4::Matrix4 --
|
* charles::basics::Matrix4::Matrix4 --
|
||||||
*/
|
*/
|
||||||
Matrix4::Matrix4(const Double data[16])
|
Matrix4::Matrix4(const Double data[16])
|
||||||
|
: mTransposed(false)
|
||||||
{
|
{
|
||||||
memcpy(mData, data, sizeof(Double) * 16);
|
memcpy(mData, data, sizeof(Double) * 16);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +85,13 @@ Matrix4::Matrix4(const Double data[16])
|
||||||
*/
|
*/
|
||||||
Matrix4::Matrix4(const Matrix4 &rhs)
|
Matrix4::Matrix4(const Matrix4 &rhs)
|
||||||
: Matrix4(rhs.mData)
|
: Matrix4(rhs.mData)
|
||||||
{ }
|
{
|
||||||
|
/*
|
||||||
|
* Needs to be in the body instead of the initializer list because
|
||||||
|
* (apparently) delegating constructors must be the only thing in the list.
|
||||||
|
*/
|
||||||
|
mTransposed = rhs.mTransposed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -93,6 +101,7 @@ Matrix4&
|
||||||
Matrix4::operator=(const Matrix4 &rhs)
|
Matrix4::operator=(const Matrix4 &rhs)
|
||||||
{
|
{
|
||||||
memcpy(mData, rhs.mData, sizeof(Double) * 16);
|
memcpy(mData, rhs.mData, sizeof(Double) * 16);
|
||||||
|
mTransposed = rhs.mTransposed;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +147,12 @@ Matrix4::operator()(UInt i,
|
||||||
ss << "matrix index out of bounds: i = " << i << ", j = " << j;
|
ss << "matrix index out of bounds: i = " << i << ", j = " << j;
|
||||||
throw std::out_of_range(ss.str());
|
throw std::out_of_range(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mTransposed) {
|
||||||
return mData[i*4 + j];
|
return mData[i*4 + j];
|
||||||
|
} else {
|
||||||
|
return mData[i + j*4];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,7 +169,11 @@ Matrix4::operator()(UInt i,
|
||||||
ss << "matrix index out of bounds: i = " << i << ", j = " << j;
|
ss << "matrix index out of bounds: i = " << i << ", j = " << j;
|
||||||
throw std::out_of_range(ss.str());
|
throw std::out_of_range(ss.str());
|
||||||
}
|
}
|
||||||
|
if (!mTransposed) {
|
||||||
return mData[i*4 + j];
|
return mData[i*4 + j];
|
||||||
|
} else {
|
||||||
|
return mData[i + j*4];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -255,6 +273,28 @@ Matrix4::operator*(const Vector4 &rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* charles::basics::Matrix4::Transpose --
|
||||||
|
*/
|
||||||
|
Matrix4&
|
||||||
|
Matrix4::Transpose()
|
||||||
|
{
|
||||||
|
mTransposed = !mTransposed;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Matrix4&
|
||||||
|
Matrix4::Inverse()
|
||||||
|
{
|
||||||
|
/* XXX: Only translation matrices are supported right now. */
|
||||||
|
operator()(0,3) = -operator()(0,3);
|
||||||
|
operator()(1,3) = -operator()(1,3);
|
||||||
|
operator()(2,3) = -operator()(2,3);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* charles::basics::operator* --
|
* charles::basics::operator* --
|
||||||
*/
|
*/
|
||||||
|
@ -266,6 +306,27 @@ operator*(Double lhs,
|
||||||
return rhs * lhs;
|
return rhs * lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* charles::basics::Transposed --
|
||||||
|
*/
|
||||||
|
Matrix4
|
||||||
|
Transposed(Matrix4 m)
|
||||||
|
{
|
||||||
|
return m.Transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* charles::basics::Inverse --
|
||||||
|
*/
|
||||||
|
Matrix4
|
||||||
|
Inverse(Matrix4 m)
|
||||||
|
{
|
||||||
|
return m.Inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* namespace mespace */
|
} /* namespace mespace */
|
||||||
} /* namespace charles */
|
} /* namespace charles */
|
||||||
|
|
||||||
|
|
|
@ -73,15 +73,31 @@ struct Matrix4
|
||||||
Vector4 operator*(const Vector4 &rhs) const;
|
Vector4 operator*(const Vector4 &rhs) const;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
Matrix4& Transpose();
|
||||||
|
Matrix4& Inverse();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** The matrix data */
|
/** The matrix data */
|
||||||
Double mData[16];
|
Double mData[16];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `true` if the matrix has been transposed (i.e. should be indexed in
|
||||||
|
* column-major format).
|
||||||
|
*/
|
||||||
|
bool mTransposed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Scalar multiplication, scalar factor on the left. */
|
/** Scalar multiplication, scalar factor on the left. */
|
||||||
Matrix4 operator*(Double lhs, const Matrix4 &rhs);
|
Matrix4 operator*(Double lhs, const Matrix4 &rhs);
|
||||||
|
|
||||||
|
|
||||||
|
/** Transpose the given matrix. */
|
||||||
|
Matrix4 Transposed(Matrix4 rhs);
|
||||||
|
|
||||||
|
/** Invert the given matrix. */
|
||||||
|
Matrix4 Inverse(Matrix4 rhs);
|
||||||
|
|
||||||
} /* namespace basics */
|
} /* namespace basics */
|
||||||
} /* namespace charles */
|
} /* namespace charles */
|
||||||
|
|
||||||
|
|
|
@ -293,3 +293,21 @@ TEST_F(Matrix4Test, IdentityVectorMultiplication)
|
||||||
EXPECT_EQ(p1.Y(), v1.Y());
|
EXPECT_EQ(p1.Y(), v1.Y());
|
||||||
EXPECT_EQ(p1.Z(), v1.Z());
|
EXPECT_EQ(p1.Z(), v1.Z());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_F(Matrix4Test, Transpose)
|
||||||
|
{
|
||||||
|
Matrix4 t1 = Transposed(m1);
|
||||||
|
for (UInt i = 0; i < 4; i++) {
|
||||||
|
for (UInt j = 0; j < 4; j++) {
|
||||||
|
EXPECT_EQ(m1(i,j), t1(j,i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t1.Transpose();
|
||||||
|
for (UInt i = 0; i < 4; i++) {
|
||||||
|
for (UInt j = 0; j < 4; j++) {
|
||||||
|
EXPECT_EQ(m1(i,j), t1(i,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue