1 #ifndef ACG_MATH_MATRIX3X3T_HH_
2 #define ACG_MATH_MATRIX3X3T_HH_
6 #include <ACG/Math/VectorT.hh>
10 #if defined(_MSC_VER) && _MSC_VER < 1900
12 typedef unsigned char uint_fast8_t;
20 template<
typename Scalar>
64 values_(
std::move(row_major)) {}
66 constexpr
bool operator==(
const Matrix3x3T &rhs)
const {
67 return values_ == rhs.values_;
76 constexpr
static uint_fast8_t
indexof(uint_fast8_t r, uint_fast8_t c) {
80 constexpr
const Scalar &operator() (uint_fast8_t r, uint_fast8_t c)
const {
84 Scalar &operator() (uint_fast8_t r, uint_fast8_t c) {
89 constexpr
const Scalar &
operator[] (uint_fast8_t i)
const {
100 (*this)(0, 0) * rhs(0, 0) + (*this)(0, 1) * rhs(1, 0) + (*this)(0, 2) * rhs(2, 0),
101 (*this)(0, 0) * rhs(0, 1) + (*this)(0, 1) * rhs(1, 1) + (*this)(0, 2) * rhs(2, 1),
102 (*this)(0, 0) * rhs(0, 2) + (*this)(0, 1) * rhs(1, 2) + (*this)(0, 2) * rhs(2, 2),
104 (*this)(1, 0) * rhs(0, 0) + (*this)(1, 1) * rhs(1, 0) + (*this)(1, 2) * rhs(2, 0),
105 (*this)(1, 0) * rhs(0, 1) + (*this)(1, 1) * rhs(1, 1) + (*this)(1, 2) * rhs(2, 1),
106 (*this)(1, 0) * rhs(0, 2) + (*this)(1, 1) * rhs(1, 2) + (*this)(1, 2) * rhs(2, 2),
108 (*this)(2, 0) * rhs(0, 0) + (*this)(2, 1) * rhs(1, 0) + (*this)(2, 2) * rhs(2, 0),
109 (*this)(2, 0) * rhs(0, 1) + (*this)(2, 1) * rhs(1, 1) + (*this)(2, 2) * rhs(2, 1),
110 (*this)(2, 0) * rhs(0, 2) + (*this)(2, 1) * rhs(1, 2) + (*this)(2, 2) * rhs(2, 2),
114 constexpr Vec3 operator*(
const Vec3 &rhs)
const {
116 (*
this)(0, 0) * rhs[0] + (*
this)(0, 1) * rhs[1] + (*
this)(0, 2) * rhs[2],
117 (*
this)(1, 0) * rhs[0] + (*
this)(1, 1) * rhs[1] + (*
this)(1, 2) * rhs[2],
118 (*
this)(2, 0) * rhs[0] + (*
this)(2, 1) * rhs[1] + (*
this)(2, 2) * rhs[2]
122 constexpr
friend Vec3 operator*(Vec3 v,
const Matrix3x3T &rhs) {
124 rhs(0, 0) * v[0] + rhs(0, 1) * v[1] + rhs(0, 2) * v[2],
125 rhs(1, 0) * v[0] + rhs(1, 1) * v[1] + rhs(1, 2) * v[2],
126 rhs(2, 0) * v[0] + rhs(2, 1) * v[1] + rhs(2, 2) * v[2]
130 constexpr Matrix3x3T operator*(Scalar c)
const {
132 (*this)[0] * c, (*this)[1] * c, (*this)[2] * c,
133 (*this)[3] * c, (*this)[4] * c, (*this)[5] * c,
134 (*this)[6] * c, (*this)[7] * c, (*this)[8] * c,
138 constexpr
friend Matrix3x3T operator*(Scalar c,
const Matrix3x3T &rhs) {
140 rhs[0] * c, rhs[1] * c, rhs[2] * c,
141 rhs[3] * c, rhs[4] * c, rhs[5] * c,
142 rhs[6] * c, rhs[7] * c, rhs[8] * c,
146 constexpr Matrix3x3T operator+ (
const Matrix3x3T &rhs)
const {
148 (*this)[0] + rhs[0], (*this)[1] + rhs[1], (*this)[2] + rhs[2],
149 (*this)[3] + rhs[3], (*this)[4] + rhs[4], (*this)[5] + rhs[5],
150 (*this)[6] + rhs[6], (*this)[7] + rhs[7], (*this)[8] + rhs[8],
154 constexpr Matrix3x3T operator- (
const Matrix3x3T &rhs)
const {
156 (*this)[0] - rhs[0], (*this)[1] - rhs[1], (*this)[2] - rhs[2],
157 (*this)[3] - rhs[3], (*this)[4] - rhs[4], (*this)[5] - rhs[5],
158 (*this)[6] - rhs[6], (*this)[7] - rhs[7], (*this)[8] - rhs[8],
162 constexpr Matrix3x3T operator- ()
const {
164 -values_[0], -values_[1], -values_[2],
165 -values_[3], -values_[4], -values_[5],
166 -values_[6], -values_[7], -values_[8]
170 const Matrix3x3T &operator*=(
const Matrix3x3T &rhs) {
171 (*this) = operator*(rhs);
175 constexpr Scalar det()
const {
176 return (*
this)(0, 0) * ((*
this)(1, 1) * (*
this)(2, 2) - (*
this)(2, 1) * (*
this)(1, 2)) -
177 (*this)(0, 1) * ((*
this)(1, 0) * (*
this)(2, 2) - (*
this)(1, 2) * (*
this)(2, 0)) +
178 (*this)(0, 2) * ((*
this)(1, 0) * (*
this)(2, 1) - (*
this)(1, 1) * (*
this)(2, 0));
190 constexpr Scalar trace()
const {
191 return (*
this)[0] + (*this)[4] + (*this)[8];
195 std::swap(values_[1], values_[3]);
196 std::swap(values_[2], values_[6]);
197 std::swap(values_[5], values_[7]);
200 constexpr Matrix3x3T transposed()
const {
202 values_[0], values_[3], values_[6],
203 values_[1], values_[4], values_[7],
204 values_[2], values_[5], values_[8],
212 Matrix3x3T inverse()
const {
213 const Scalar invdet = 1.0 / det();
215 ((*this)(1, 1) * (*
this)(2, 2) - (*
this)(2, 1) * (*
this)(1, 2)) * invdet,
216 ((*this)(0, 2) * (*
this)(2, 1) - (*
this)(0, 1) * (*
this)(2, 2)) * invdet,
217 ((*this)(0, 1) * (*
this)(1, 2) - (*
this)(0, 2) * (*
this)(1, 1)) * invdet,
218 ((*this)(1, 2) * (*
this)(2, 0) - (*
this)(1, 0) * (*
this)(2, 2)) * invdet,
219 ((*this)(0, 0) * (*
this)(2, 2) - (*
this)(0, 2) * (*
this)(2, 0)) * invdet,
220 ((*this)(1, 0) * (*
this)(0, 2) - (*
this)(0, 0) * (*
this)(1, 2)) * invdet,
221 ((*this)(1, 0) * (*
this)(2, 1) - (*
this)(2, 0) * (*
this)(1, 1)) * invdet,
222 ((*this)(2, 0) * (*
this)(0, 1) - (*
this)(0, 0) * (*
this)(2, 1)) * invdet,
223 ((*this)(0, 0) * (*
this)(1, 1) - (*
this)(1, 0) * (*
this)(0, 1)) * invdet,
227 constexpr Scalar frobeniusSquared()
const {
228 return std::inner_product(
229 values_.begin(), values_.end(), values_.begin(), Scalar(0.0));
232 constexpr
double frobenius()
const {
233 return std::sqrt(frobeniusSquared());
238 std::ostream &operator<< (std::ostream &os,
const Matrix3x3T &m) {
239 os <<
"[[" << m[0] <<
", " << m[1] <<
", " << m[2] <<
"], "
240 "[" << m[3] <<
", " << m[4] <<
", " << m[5] <<
"], "
241 "[" << m[6] <<
", " << m[7] <<
", " << m[8] <<
"]]";
246 std::array<Scalar, 9> values_;
249 typedef Matrix3x3T<float> Matrix3x3f;
250 typedef Matrix3x3T<double> Matrix3x3d;
254 #if defined(_MSC_VER) && _MSC_VER < 1900
Namespace providing different geometric functions concerning angles.
static constexpr uint_fast8_t indexof(uint_fast8_t r, uint_fast8_t c)
Map row/column index to linearized index.
constexpr const Scalar & operator[](uint_fast8_t i) const
Linearized row major access.
constexpr Matrix3x3T(std::array< Scalar, 9 > row_major)