26 #ifndef WFMATH_ROTMATRIX_FUNCS_H
27 #define WFMATH_ROTMATRIX_FUNCS_H
29 #include <wfmath/rotmatrix.h>
31 #include <wfmath/vector.h>
32 #include <wfmath/error.h>
33 #include <wfmath/const.h>
42 inline RotMatrix<dim>::RotMatrix(
const RotMatrix<dim>& m)
43 : m_flip(m.m_flip), m_valid(m.m_valid), m_age(1)
45 for(
int i = 0; i < dim; ++i)
46 for(
int j = 0; j < dim; ++j)
47 m_elem[i][j] = m.m_elem[i][j];
51 inline RotMatrix<dim>& RotMatrix<dim>::operator=(
const RotMatrix<dim>& m)
53 for(
int i = 0; i < dim; ++i)
54 for(
int j = 0; j < dim; ++j)
55 m_elem[i][j] = m.m_elem[i][j];
65 inline bool RotMatrix<dim>::isEqualTo(
const RotMatrix<dim>& m,
CoordType epsilon)
const
76 if (!m.m_valid || !m_valid) {
81 for(
int i = 0; i < dim; ++i)
82 for(
int j = 0; j < dim; ++j)
83 if(std::fabs(m_elem[i][j] - m.m_elem[i][j]) > epsilon)
88 assert(
"Generated values, must be equal if all components are equal" &&
99 for(
int i = 0; i < dim; ++i) {
100 for(
int j = 0; j < dim; ++j) {
101 out.m_elem[i][j] = 0;
102 for(
int k = 0; k < dim; ++k) {
103 out.m_elem[i][j] += m1.m_elem[i][k] * m2.m_elem[k][j];
108 out.m_flip = (m1.m_flip != m2.m_flip);
109 out.m_valid = m1.m_valid && m2.m_valid;
110 out.m_age = m1.m_age + m2.m_age;
111 out.checkNormalization();
121 for(
int i = 0; i < dim; ++i) {
122 for(
int j = 0; j < dim; ++j) {
123 out.m_elem[i][j] = 0;
124 for(
int k = 0; k < dim; ++k) {
125 out.m_elem[i][j] += m1.m_elem[i][k] * m2.m_elem[j][k];
130 out.m_flip = (m1.m_flip != m2.m_flip);
131 out.m_valid = m1.m_valid && m2.m_valid;
132 out.m_age = m1.m_age + m2.m_age;
133 out.checkNormalization();
143 for(
int i = 0; i < dim; ++i) {
144 for(
int j = 0; j < dim; ++j) {
145 out.m_elem[i][j] = 0;
146 for(
int k = 0; k < dim; ++k) {
147 out.m_elem[i][j] += m1.m_elem[k][i] * m2.m_elem[k][j];
152 out.m_flip = (m1.m_flip != m2.m_flip);
153 out.m_valid = m1.m_valid && m2.m_valid;
154 out.m_age = m1.m_age + m2.m_age;
155 out.checkNormalization();
165 for(
int i = 0; i < dim; ++i) {
166 for(
int j = 0; j < dim; ++j) {
167 out.m_elem[i][j] = 0;
168 for(
int k = 0; k < dim; ++k) {
169 out.m_elem[i][j] += m1.m_elem[k][i] * m2.m_elem[j][k];
174 out.m_flip = (m1.m_flip != m2.m_flip);
175 out.m_valid = m1.m_valid && m2.m_valid;
176 out.m_age = m1.m_age + m2.m_age;
177 out.checkNormalization();
187 for(
int i = 0; i < dim; ++i) {
189 for(
int j = 0; j < dim; ++j) {
190 out.m_elem[i] += m.m_elem[i][j] * v.m_elem[j];
194 out.m_valid = m.m_valid && v.m_valid;
204 for(
int i = 0; i < dim; ++i) {
206 for(
int j = 0; j < dim; ++j) {
207 out.m_elem[i] += m.m_elem[j][i] * v.m_elem[j];
211 out.m_valid = m.m_valid && v.m_valid;
235 inline Vector<dim>
operator*(
const RotMatrix<dim>& m,
const Vector<dim>& v)
241 inline Vector<dim>
operator*(
const Vector<dim>& v,
const RotMatrix<dim>& m)
252 for(
int i = 0; i < dim; ++i)
253 for(
int j = 0; j < dim; ++j)
254 scratch_vals[i*dim+j] = vals[i][j];
256 return _setVals(scratch_vals, precision);
265 for(
int i = 0; i < dim*dim; ++i)
266 scratch_vals[i] = vals[i];
268 return _setVals(scratch_vals, precision);
271 bool _MatrixSetValsImpl(
int size,
CoordType* vals,
bool& flip,
282 if(!_MatrixSetValsImpl(dim, vals, flip, buf1, buf2, precision))
287 for(
int i = 0; i < dim; ++i)
288 for(
int j = 0; j < dim; ++j)
289 m_elem[i][j] = vals[i*dim+j];
303 for(
int j = 0; j < dim; ++j)
304 out[j] = m_elem[i][j];
316 for(
int j = 0; j < dim; ++j)
317 out[j] = m_elem[j][i];
329 for(
int i = 0; i < dim; ++i)
330 for(
int j = 0; j < dim; ++j)
331 m.m_elem[j][i] = m_elem[i][j];
343 for(
int i = 0; i < dim; ++i)
344 for(
int j = 0; j < dim; ++j)
345 m_elem[i][j] = ((i == j) ? 1.0f : 0.0f);
359 for(
int i = 0; i < dim; ++i)
369 assert(i >= 0 && i < dim && j >= 0 && j < dim && i != j);
371 CoordType ctheta = std::cos(theta), stheta = std::sin(theta);
373 for(
int k = 0; k < dim; ++k) {
374 for(
int l = 0; l < dim; ++l) {
377 m_elem[k][l] = ctheta;
383 m_elem[k][l] = stheta;
384 else if(k == j && l == i)
385 m_elem[k][l] = -stheta;
406 assert(
"need nonzero length vector" && v1_sqr_mag > 0);
410 Vector<dim> vperp = v2 - v1 * Dot(v1, v2) / v1_sqr_mag;
414 assert(
"need nonzero length vector" && v2.
sqrMag() > 0);
425 CoordType mag_prod = std::sqrt(v1_sqr_mag * vperp_sqr_mag);
427 stheta = std::sin(theta);
431 for(
int i = 0; i < dim; ++i)
432 for(
int j = 0; j < dim; ++j)
433 m_elem[i][j] += ((ctheta - 1) * (v1[i] * v1[j] / v1_sqr_mag
434 + vperp[i] * vperp[j] / vperp_sqr_mag)
435 - stheta * (vperp[i] * v1[j] - v1[i] * vperp[j]) / mag_prod);
452 assert(
"need nonzero length vector" && fromSqrMag > 0);
454 assert(
"need nonzero length vector" && toSqrMag > 0);
456 CoordType sqrmagprod = fromSqrMag * toSqrMag;
457 CoordType magprod = std::sqrt(sqrmagprod);
458 CoordType ctheta_plus_1 = dot / magprod + 1;
463 m_elem[0][0] = m_elem[1][1] = ctheta_plus_1 - 1;
464 CoordType sin_theta = std::sqrt(2 * ctheta_plus_1);
465 bool direction = ((to[0] * from[1] - to[1] * from[0]) >= 0);
466 m_elem[0][1] = direction ? sin_theta : -sin_theta;
467 m_elem[1][0] = -m_elem[0][1];
476 for(
int i = 0; i < dim; ++i) {
477 for(
int j = i; j < dim; ++j) {
478 CoordType projfrom = from[i] * from[j] / fromSqrMag;
479 CoordType projto = to[i] * to[j] / toSqrMag;
481 CoordType ijprod = from[i] * to[j], jiprod = to[i] * from[j];
483 CoordType termthree = (ijprod + jiprod) * dot / sqrmagprod;
485 CoordType combined = (projfrom + projto - termthree) / ctheta_plus_1;
488 m_elem[i][i] = 1 - combined;
491 CoordType diffterm = (jiprod - ijprod) / magprod;
493 m_elem[i][j] = -diffterm - combined;
494 m_elem[j][i] = diffterm - combined;
510 const bool not_flip);
525 assert(
"need nonzero length vector" && sqr_mag > 0);
528 for(
int i = 0; i < dim - 1; ++i)
529 for(
int j = i + 1; j < dim; ++j)
530 m_elem[i][j] = m_elem[j][i] = -2 * v[i] * v[j] / sqr_mag;
533 for(
int i = 0; i < dim; ++i)
534 m_elem[i][i] = 1 - 2 * v[i] * v[i] / sqr_mag;
546 for(
int i = 0; i < dim; ++i)
547 for(
int j = 0; j < dim; ++j)
548 m_elem[i][j] = (i == j) ? -1 : 0;
568 for(
int i = 0; i < dim; ++i) {
569 for(
int j = 0; j < dim; ++j) {
570 buf1[j*dim + i] = m_elem[i][j];
571 buf2[j*dim + i] = ((i == j) ? 1.f : 0.f);
575 bool success = _MatrixInverseImpl(dim, buf1, buf2);
581 for(
int i = 0; i < dim; ++i) {
582 for(
int j = 0; j < dim; ++j) {
584 elem += buf2[i*dim + j];
594 #endif // WFMATH_ROTMATRIX_FUNCS_H