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 --
|
||||
*/
|
||||
Matrix4::Matrix4()
|
||||
: mData()
|
||||
: mData(),
|
||||
mTransposed(false)
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -73,6 +74,7 @@ Matrix4::Matrix4()
|
|||
* charles::basics::Matrix4::Matrix4 --
|
||||
*/
|
||||
Matrix4::Matrix4(const Double data[16])
|
||||
: mTransposed(false)
|
||||
{
|
||||
memcpy(mData, data, sizeof(Double) * 16);
|
||||
}
|
||||
|
@ -83,7 +85,13 @@ Matrix4::Matrix4(const Double data[16])
|
|||
*/
|
||||
Matrix4::Matrix4(const Matrix4 &rhs)
|
||||
: 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)
|
||||
{
|
||||
memcpy(mData, rhs.mData, sizeof(Double) * 16);
|
||||
mTransposed = rhs.mTransposed;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -138,7 +147,12 @@ Matrix4::operator()(UInt i,
|
|||
ss << "matrix index out of bounds: i = " << i << ", j = " << j;
|
||||
throw std::out_of_range(ss.str());
|
||||
}
|
||||
return mData[i*4 + j];
|
||||
|
||||
if (!mTransposed) {
|
||||
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;
|
||||
throw std::out_of_range(ss.str());
|
||||
}
|
||||
return mData[i*4 + j];
|
||||
if (!mTransposed) {
|
||||
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* --
|
||||
*/
|
||||
|
@ -266,6 +306,27 @@ operator*(Double 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 charles */
|
||||
|
||||
|
|
|
@ -73,15 +73,31 @@ struct Matrix4
|
|||
Vector4 operator*(const Vector4 &rhs) const;
|
||||
/** @} */
|
||||
|
||||
Matrix4& Transpose();
|
||||
Matrix4& Inverse();
|
||||
|
||||
protected:
|
||||
/** The matrix data */
|
||||
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. */
|
||||
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 charles */
|
||||
|
||||
|
|
|
@ -293,3 +293,21 @@ TEST_F(Matrix4Test, IdentityVectorMultiplication)
|
|||
EXPECT_EQ(p1.Y(), v1.Y());
|
||||
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