1 /* 2 * vec_mat.h - vector and matrix defination & calculation 3 * 4 * Copyright (c) 2017 Intel Corporation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * Author: Zong Wei <wei.zong (at) intel.com> 19 */ 20 21 #ifndef XCAM_VECTOR_MATRIX_H 22 #define XCAM_VECTOR_MATRIX_H 23 24 #include <xcam_std.h> 25 #include <cmath> 26 27 28 namespace XCam { 29 30 #ifndef PI 31 #define PI 3.14159265358979323846 32 #endif 33 34 #ifndef FLT_EPSILON 35 #define FLT_EPSILON 1.19209290e-07F // float 36 #endif 37 38 #ifndef DBL_EPSILON 39 #define DBL_EPSILON 2.2204460492503131e-16 // double 40 #endif 41 42 #ifndef DEGREE_2_RADIANS 43 #define DEGREE_2_RADIANS(x) (((x) * PI) / 180.0) 44 #endif 45 46 #ifndef RADIANS_2_DEGREE 47 #define RADIANS_2_DEGREE(x) (((x) * 180.0) / PI) 48 #endif 49 50 #define XCAM_VECT2_OPERATOR_VECT2(op) \ 51 Vector2<T> operator op (const Vector2<T>& b) const { \ 52 return Vector2<T>(x op b.x, y op b.y); \ 53 } \ 54 Vector2<T> &operator op##= (const Vector2<T>& b) { \ 55 x op##= b.x; y op##= b.y; return *this; \ 56 } 57 58 #define XCAM_VECT2_OPERATOR_SCALER(op) \ 59 Vector2<T> operator op (const T& b) const { \ 60 return Vector2<T>(x op b, y op b); \ 61 } \ 62 Vector2<T> &operator op##= (const T& b) { \ 63 x op##= b; y op##= b; return *this; \ 64 } 65 66 template<class T> 67 class Vector2 68 { 69 public: 70 71 T x; 72 T y; 73 74 Vector2 () : x(0), y(0) {}; 75 Vector2 (T _x, T _y) : x(_x), y(_y) {}; 76 77 template <typename New> 78 Vector2<New> convert_to () const { 79 Vector2<New> ret((New)(this->x), (New)(this->y)); 80 return ret; 81 } 82 83 Vector2<T>& operator = (const Vector2<T>& rhs) 84 { 85 x = rhs.x; 86 y = rhs.y; 87 return *this; 88 } 89 90 template <typename Other> 91 Vector2<T>& operator = (const Vector2<Other>& rhs) 92 { 93 x = rhs.x; 94 y = rhs.y; 95 return *this; 96 } 97 98 Vector2<T> operator - () const { 99 return Vector2<T>(-x, -y); 100 } 101 102 XCAM_VECT2_OPERATOR_VECT2 (+) 103 XCAM_VECT2_OPERATOR_VECT2 (-) 104 XCAM_VECT2_OPERATOR_VECT2 (*) 105 XCAM_VECT2_OPERATOR_VECT2 ( / ) 106 XCAM_VECT2_OPERATOR_SCALER (+) 107 XCAM_VECT2_OPERATOR_SCALER (-) 108 XCAM_VECT2_OPERATOR_SCALER (*) 109 XCAM_VECT2_OPERATOR_SCALER ( / ) 110 111 bool operator == (const Vector2<T>& rhs) const { 112 return (x == rhs.x) && (y == rhs.y); 113 } 114 115 void reset () { 116 this->x = (T) 0; 117 this->y = (T) 0; 118 } 119 120 void set (T _x, T _y) { 121 this->x = _x; 122 this->y = _y; 123 } 124 125 T magnitude () const { 126 return (T) sqrtf(x * x + y * y); 127 } 128 129 float distance (const Vector2<T>& vec) const { 130 return sqrtf((vec.x - x) * (vec.x - x) + (vec.y - y) * (vec.y - y)); 131 } 132 133 T dot (const Vector2<T>& vec) const { 134 return (x * vec.x + y * vec.y); 135 } 136 137 inline Vector2<T> lerp (T weight, const Vector2<T>& vec) const { 138 return (*this) + (vec - (*this)) * weight; 139 } 140 141 }; 142 143 template<class T, uint32_t N> 144 class VectorN 145 { 146 public: 147 148 VectorN (); 149 VectorN (T x); 150 VectorN (T x, T y); 151 VectorN (T x, T y, T z); 152 VectorN (T x, T y, T z, T w); 153 VectorN (VectorN<T, 3> vec3, T w); 154 155 inline VectorN<T, N>& operator = (const VectorN<T, N>& rhs); 156 inline VectorN<T, N> operator - () const; 157 inline bool operator == (const VectorN<T, N>& rhs) const; 158 159 inline T& operator [] (uint32_t index) { 160 XCAM_ASSERT(index >= 0 && index < N); 161 return data[index]; 162 } 163 inline const T& operator [] (uint32_t index) const { 164 XCAM_ASSERT(index >= 0 && index < N); 165 return data[index]; 166 } 167 168 inline VectorN<T, N> operator + (const T rhs) const; 169 inline VectorN<T, N> operator - (const T rhs) const; 170 inline VectorN<T, N> operator * (const T rhs) const; 171 inline VectorN<T, N> operator / (const T rhs) const; 172 inline VectorN<T, N> operator += (const T rhs); 173 inline VectorN<T, N> operator -= (const T rhs); 174 inline VectorN<T, N> operator *= (const T rhs); 175 inline VectorN<T, N> operator /= (const T rhs); 176 177 inline VectorN<T, N> operator + (const VectorN<T, N>& rhs) const; 178 inline VectorN<T, N> operator - (const VectorN<T, N>& rhs) const; 179 inline VectorN<T, N> operator * (const VectorN<T, N>& rhs) const; 180 inline VectorN<T, N> operator / (const VectorN<T, N>& rhs) const; 181 inline VectorN<T, N> operator += (const VectorN<T, N>& rhs); 182 inline VectorN<T, N> operator -= (const VectorN<T, N>& rhs); 183 inline VectorN<T, N> operator *= (const VectorN<T, N>& rhs); 184 inline VectorN<T, N> operator /= (const VectorN<T, N>& rhs); 185 186 template <typename NEW> inline 187 VectorN<NEW, N> convert_to () const; 188 189 inline void zeros (); 190 inline void set (T x, T y); 191 inline void set (T x, T y, T z); 192 inline void set (T x, T y, T z, T w); 193 inline T magnitude () const; 194 inline float distance (const VectorN<T, N>& vec) const; 195 inline T dot (const VectorN<T, N>& vec) const; 196 inline VectorN<T, N> lerp (T weight, const VectorN<T, N>& vec) const; 197 198 private: 199 T data[N]; 200 201 }; 202 203 204 template<class T, uint32_t N> inline 205 VectorN<T, N>::VectorN () 206 { 207 for (uint32_t i = 0; i < N; i++) { 208 data[i] = 0; 209 } 210 } 211 212 template<class T, uint32_t N> inline 213 VectorN<T, N>::VectorN (T x) { 214 data[0] = x; 215 } 216 217 template<class T, uint32_t N> inline 218 VectorN<T, N>::VectorN (T x, T y) { 219 if (N >= 2) { 220 data[0] = x; 221 data[1] = y; 222 } 223 } 224 225 template<class T, uint32_t N> inline 226 VectorN<T, N>::VectorN (T x, T y, T z) { 227 if (N >= 3) { 228 data[0] = x; 229 data[1] = y; 230 data[2] = z; 231 } 232 } 233 234 template<class T, uint32_t N> inline 235 VectorN<T, N>::VectorN (T x, T y, T z, T w) { 236 if (N >= 4) { 237 data[0] = x; 238 data[1] = y; 239 data[2] = z; 240 data[3] = w; 241 } 242 } 243 244 template<class T, uint32_t N> inline 245 VectorN<T, N>::VectorN (VectorN<T, 3> vec3, T w) { 246 if (N >= 4) { 247 data[0] = vec3.data[0]; 248 data[1] = vec3.data[1]; 249 data[2] = vec3.data[2]; 250 data[3] = w; 251 } 252 } 253 254 template<class T, uint32_t N> inline 255 VectorN<T, N>& VectorN<T, N>::operator = (const VectorN<T, N>& rhs) { 256 for (uint32_t i = 0; i < N; i++) { 257 data[i] = rhs.data[i]; 258 } 259 260 return *this; 261 } 262 263 template<class T, uint32_t N> inline 264 VectorN<T, N> VectorN<T, N>::operator - () const { 265 for (uint32_t i = 0; i < N; i++) { 266 data[i] = -data[i]; 267 } 268 269 return *this; 270 } 271 272 template<class T, uint32_t N> inline 273 VectorN<T, N> VectorN<T, N>::operator + (const T rhs) const { 274 VectorN<T, N> result; 275 276 for (uint32_t i = 0; i < N; i++) { 277 result.data[i] = data[i] + rhs; 278 } 279 return result; 280 } 281 282 template<class T, uint32_t N> inline 283 VectorN<T, N> VectorN<T, N>::operator - (const T rhs) const { 284 VectorN<T, N> result; 285 286 for (uint32_t i = 0; i < N; i++) { 287 result.data[i] = data[i] - rhs; 288 } 289 return result; 290 } 291 292 template<class T, uint32_t N> inline 293 VectorN<T, N> VectorN<T, N>::operator * (const T rhs) const { 294 VectorN<T, N> result; 295 296 for (uint32_t i = 0; i < N; i++) { 297 result.data[i] = data[i] * rhs; 298 } 299 return result; 300 } 301 302 template<class T, uint32_t N> inline 303 VectorN<T, N> VectorN<T, N>::operator / (const T rhs) const { 304 VectorN<T, N> result; 305 306 for (uint32_t i = 0; i < N; i++) { 307 result.data[i] = data[i] / rhs; 308 } 309 return result; 310 } 311 312 template<class T, uint32_t N> inline 313 VectorN<T, N> VectorN<T, N>::operator += (const T rhs) { 314 for (uint32_t i = 0; i < N; i++) { 315 data[i] += rhs; 316 } 317 return *this; 318 } 319 320 template<class T, uint32_t N> inline 321 VectorN<T, N> VectorN<T, N>::operator -= (const T rhs) { 322 for (uint32_t i = 0; i < N; i++) { 323 data[i] -= rhs; 324 } 325 return *this; 326 } 327 328 template<class T, uint32_t N> inline 329 VectorN<T, N> VectorN<T, N>::operator *= (const T rhs) { 330 for (uint32_t i = 0; i < N; i++) { 331 data[i] *= rhs; 332 } 333 return *this; 334 } 335 336 template<class T, uint32_t N> inline 337 VectorN<T, N> VectorN<T, N>::operator /= (const T rhs) { 338 for (uint32_t i = 0; i < N; i++) { 339 data[i] /= rhs; 340 } 341 return *this; 342 } 343 344 template<class T, uint32_t N> inline 345 VectorN<T, N> VectorN<T, N>::operator + (const VectorN<T, N>& rhs) const { 346 VectorN<T, N> result; 347 348 for (uint32_t i = 0; i < N; i++) { 349 result.data[i] = data[i] + rhs.data[i]; 350 } 351 return result; 352 } 353 354 template<class T, uint32_t N> inline 355 VectorN<T, N> VectorN<T, N>::operator - (const VectorN<T, N>& rhs) const { 356 VectorN<T, N> result; 357 358 for (uint32_t i = 0; i < N; i++) { 359 result.data[i] = data[i] - rhs.data[i]; 360 } 361 return result; 362 } 363 364 template<class T, uint32_t N> inline 365 VectorN<T, N> VectorN<T, N>::operator * (const VectorN<T, N>& rhs) const { 366 VectorN<T, N> result; 367 368 for (uint32_t i = 0; i < N; i++) { 369 result.data[i] = data[i] * rhs.data[i]; 370 } 371 return result; 372 } 373 374 template<class T, uint32_t N> inline 375 VectorN<T, N> VectorN<T, N>::operator / (const VectorN<T, N>& rhs) const { 376 VectorN<T, N> result; 377 378 for (uint32_t i = 0; i < N; i++) { 379 result.data[i] = data[i] / rhs.data[i]; 380 } 381 return result; 382 } 383 384 template<class T, uint32_t N> inline 385 VectorN<T, N> VectorN<T, N>::operator += (const VectorN<T, N>& rhs) { 386 387 for (uint32_t i = 0; i < N; i++) { 388 data[i] += rhs.data[i]; 389 } 390 return *this; 391 } 392 393 template<class T, uint32_t N> inline 394 VectorN<T, N> VectorN<T, N>::operator -= (const VectorN<T, N>& rhs) { 395 396 for (uint32_t i = 0; i < N; i++) { 397 data[i] -= rhs.data[i]; 398 } 399 return *this; 400 } 401 402 template<class T, uint32_t N> inline 403 VectorN<T, N> VectorN<T, N>::operator *= (const VectorN<T, N>& rhs) { 404 405 for (uint32_t i = 0; i < N; i++) { 406 data[i] *= rhs.data[i]; 407 } 408 return *this; 409 } 410 411 template<class T, uint32_t N> inline 412 VectorN<T, N> VectorN<T, N>::operator /= (const VectorN<T, N>& rhs) { 413 414 for (uint32_t i = 0; i < N; i++) { 415 data[i] /= rhs.data[i]; 416 } 417 return *this; 418 } 419 420 template<class T, uint32_t N> inline 421 bool VectorN<T, N>::operator == (const VectorN<T, N>& rhs) const { 422 for (uint32_t i = 0; i < N; i++) { 423 if (data[i] != rhs[i]) { 424 return false; 425 } 426 } 427 return true; 428 } 429 430 template <class T, uint32_t N> 431 template <typename NEW> 432 VectorN<NEW, N> VectorN<T, N>::convert_to () const { 433 VectorN<NEW, N> result; 434 435 for (uint32_t i = 0; i < N; i++) { 436 result[i] = (NEW)(this->data[i]); 437 } 438 return result; 439 } 440 441 template <class T, uint32_t N> inline 442 void VectorN<T, N>::zeros () { 443 for (uint32_t i = 0; i < N; i++) { 444 data[i] = (T)(0); 445 } 446 } 447 448 template<class T, uint32_t N> inline 449 void VectorN<T, N>::set (T x, T y) { 450 if (N >= 2) { 451 data[0] = x; 452 data[1] = y; 453 } 454 } 455 456 template<class T, uint32_t N> inline 457 void VectorN<T, N>::set (T x, T y, T z) { 458 if (N >= 3) { 459 data[0] = x; 460 data[1] = y; 461 data[2] = z; 462 } 463 } 464 465 template<class T, uint32_t N> inline 466 void VectorN<T, N>::set (T x, T y, T z, T w) { 467 if (N >= 4) { 468 data[0] - x; 469 data[1] = y; 470 data[2] = z; 471 data[3] = w; 472 } 473 } 474 475 template<class T, uint32_t N> inline 476 T VectorN<T, N>::magnitude () const { 477 T result = 0; 478 479 for (uint32_t i = 0; i < N; i++) { 480 result += (data[i] * data[i]); 481 } 482 return (T) sqrtf(result); 483 } 484 485 template<class T, uint32_t N> inline 486 float VectorN<T, N>::distance (const VectorN<T, N>& vec) const { 487 T result = 0; 488 489 for (uint32_t i = 0; i < N; i++) { 490 result += (vec.data[i] - data[i]) * (vec.data[i] - data[i]); 491 } 492 return sqrtf(result); 493 } 494 495 template<class T, uint32_t N> inline 496 T VectorN<T, N>::dot (const VectorN<T, N>& vec) const { 497 T result = 0; 498 499 for (uint32_t i = 0; i < N; i++) { 500 result += (vec.data[i] * data[i]); 501 } 502 return result; 503 } 504 505 template<class T, uint32_t N> inline 506 VectorN<T, N> VectorN<T, N>::lerp (T weight, const VectorN<T, N>& vec) const { 507 return (*this) + (vec - (*this)) * weight; 508 } 509 510 // NxN matrix in row major order 511 template<class T, uint32_t N> 512 class MatrixN 513 { 514 public: 515 MatrixN (); 516 MatrixN (VectorN<T, 2> a, VectorN<T, 2> b); 517 MatrixN (VectorN<T, 3> a, VectorN<T, 3> b, VectorN<T, 3> c); 518 MatrixN (VectorN<T, 4> a, VectorN<T, 4> b, VectorN<T, 4> c, VectorN<T, 4> d); 519 520 inline void zeros (); 521 inline void eye (); 522 523 inline T& at (uint32_t row, uint32_t col) { 524 XCAM_ASSERT(row >= 0 && row < N); 525 XCAM_ASSERT(col >= 0 && col < N); 526 527 return data[row * N + col]; 528 }; 529 inline const T& at (uint32_t row, uint32_t col) const { 530 XCAM_ASSERT(row >= 0 && row < N); 531 XCAM_ASSERT(col >= 0 && col < N); 532 533 return data[row * N + col]; 534 }; 535 536 inline T& operator () (uint32_t row, uint32_t col) { 537 return at (row, col); 538 }; 539 inline const T& operator () (uint32_t row, uint32_t col) const { 540 return at (row, col); 541 }; 542 543 inline MatrixN<T, N>& operator = (const MatrixN<T, N>& rhs); 544 inline MatrixN<T, N> operator - () const; 545 inline MatrixN<T, N> operator + (const MatrixN<T, N>& rhs) const; 546 inline MatrixN<T, N> operator - (const MatrixN<T, N>& rhs) const; 547 inline MatrixN<T, N> operator * (const T a) const; 548 inline MatrixN<T, N> operator / (const T a) const; 549 inline VectorN<T, N> operator * (const VectorN<T, N>& rhs) const; 550 inline MatrixN<T, N> operator * (const MatrixN<T, N>& rhs) const; 551 inline MatrixN<T, N> transpose (); 552 inline MatrixN<T, N> inverse (); 553 inline T trace (); 554 555 private: 556 inline MatrixN<T, 2> inverse (const MatrixN<T, 2>& mat); 557 inline MatrixN<T, 3> inverse (const MatrixN<T, 3>& mat); 558 inline MatrixN<T, 4> inverse (const MatrixN<T, 4>& mat); 559 560 private: 561 T data[N * N]; 562 563 }; 564 565 // NxN matrix in row major order 566 template<class T, uint32_t N> 567 MatrixN<T, N>::MatrixN () { 568 eye (); 569 } 570 571 template<class T, uint32_t N> 572 MatrixN<T, N>::MatrixN (VectorN<T, 2> a, VectorN<T, 2> b) { 573 if (N == 2) { 574 data[0] = a[0]; 575 data[1] = a[1]; 576 data[2] = b[0]; 577 data[3] = b[1]; 578 } else { 579 eye (); 580 } 581 } 582 583 template<class T, uint32_t N> 584 MatrixN<T, N>::MatrixN (VectorN<T, 3> a, VectorN<T, 3> b, VectorN<T, 3> c) { 585 if (N == 3) { 586 data[0] = a[0]; 587 data[1] = a[1]; 588 data[2] = a[2]; 589 data[3] = b[0]; 590 data[4] = b[1]; 591 data[5] = b[2]; 592 data[6] = c[0]; 593 data[7] = c[1]; 594 data[8] = c[2]; 595 } else { 596 eye (); 597 } 598 } 599 600 template<class T, uint32_t N> 601 MatrixN<T, N>::MatrixN (VectorN<T, 4> a, VectorN<T, 4> b, VectorN<T, 4> c, VectorN<T, 4> d) { 602 if (N == 4) { 603 data[0] = a[0]; 604 data[1] = a[1]; 605 data[2] = a[2]; 606 data[3] = a[3]; 607 data[4] = b[0]; 608 data[5] = b[1]; 609 data[6] = b[2]; 610 data[7] = b[3]; 611 data[8] = c[0]; 612 data[9] = c[1]; 613 data[10] = c[2]; 614 data[11] = c[3]; 615 data[12] = d[0]; 616 data[13] = d[1]; 617 data[14] = d[2]; 618 data[15] = d[3]; 619 } else { 620 eye (); 621 } 622 } 623 624 template<class T, uint32_t N> inline 625 void MatrixN<T, N>::zeros () { 626 for (uint32_t i = 0; i < N * N; i++) { 627 data[i] = 0; 628 } 629 } 630 631 template<class T, uint32_t N> inline 632 void MatrixN<T, N>::eye () { 633 zeros (); 634 for (uint32_t i = 0; i < N; i++) { 635 data[i * N + i] = 1; 636 } 637 } 638 639 template<class T, uint32_t N> inline 640 MatrixN<T, N>& MatrixN<T, N>::operator = (const MatrixN<T, N>& rhs) { 641 for (uint32_t i = 0; i < N * N; i++) { 642 data[i] = rhs.data[i]; 643 } 644 return *this; 645 } 646 647 template<class T, uint32_t N> inline 648 MatrixN<T, N> MatrixN<T, N>::operator - () const { 649 MatrixN<T, N> result; 650 for (uint32_t i = 0; i < N * N; i++) { 651 result.data[i] = -data[i]; 652 } 653 return result; 654 } 655 656 template<class T, uint32_t N> inline 657 MatrixN<T, N> MatrixN<T, N>::operator + (const MatrixN<T, N>& rhs) const { 658 MatrixN<T, N> result; 659 for (uint32_t i = 0; i < N * N; i++) { 660 result.data[i] = data[i] + rhs.data[i]; 661 } 662 return result; 663 } 664 665 template<class T, uint32_t N> inline 666 MatrixN<T, N> MatrixN<T, N>::operator - (const MatrixN<T, N>& rhs) const { 667 MatrixN<T, N> result; 668 for (uint32_t i = 0; i < N * N; i++) { 669 result.data[i] = data[i] - rhs.data[i]; 670 } 671 return result; 672 } 673 674 template<class T, uint32_t N> inline 675 MatrixN<T, N> MatrixN<T, N>::operator * (const T a) const { 676 MatrixN<T, N> result; 677 for (uint32_t i = 0; i < N * N; i++) { 678 result.data[i] = data[i] * a; 679 } 680 return result; 681 } 682 683 template<class T, uint32_t N> inline 684 MatrixN<T, N> MatrixN<T, N>::operator / (const T a) const { 685 MatrixN<T, N> result; 686 for (uint32_t i = 0; i < N * N; i++) { 687 result.data[i] = data[i] / a; 688 } 689 return result; 690 } 691 692 template<class T, uint32_t N> inline 693 MatrixN<T, N> MatrixN<T, N>::operator * (const MatrixN<T, N>& rhs) const { 694 MatrixN<T, N> result; 695 result.zeros (); 696 697 for (uint32_t i = 0; i < N; i++) { 698 for (uint32_t j = 0; j < N; j++) { 699 T element = 0; 700 for (uint32_t k = 0; k < N; k++) { 701 element += at(i, k) * rhs(k, j); 702 } 703 result(i, j) = element; 704 } 705 } 706 return result; 707 } 708 709 template<class T, uint32_t N> inline 710 VectorN<T, N> MatrixN<T, N>::operator * (const VectorN<T, N>& rhs) const { 711 VectorN<T, N> result; 712 for (uint32_t i = 0; i < N; i++) { // row 713 for (uint32_t j = 0; j < N; j++) { // col 714 result.data[i] = data[i * N + j] * rhs.data[j]; 715 } 716 } 717 return result; 718 } 719 720 template<class T, uint32_t N> inline 721 MatrixN<T, N> MatrixN<T, N>::transpose () { 722 MatrixN<T, N> result; 723 for (uint32_t i = 0; i < N; i++) { 724 for (uint32_t j = 0; j <= N; j++) { 725 result.data[i * N + j] = data[j * N + i]; 726 } 727 } 728 return result; 729 } 730 731 // if the matrix is non-invertible, return identity matrix 732 template<class T, uint32_t N> inline 733 MatrixN<T, N> MatrixN<T, N>::inverse () { 734 MatrixN<T, N> result; 735 736 result = inverse (*this); 737 return result; 738 } 739 740 template<class T, uint32_t N> inline 741 T MatrixN<T, N>::trace () { 742 T t = 0; 743 for ( uint32_t i = 0; i < N; i++ ) { 744 t += data(i, i); 745 } 746 return t; 747 } 748 749 template<class T, uint32_t N> inline 750 MatrixN<T, 2> MatrixN<T, N>::inverse (const MatrixN<T, 2>& mat) 751 { 752 MatrixN<T, 2> result; 753 754 T det = mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0); 755 756 if (det == (T)0) { 757 return result; 758 } 759 760 result(0, 0) = mat(1, 1); 761 result(0, 1) = -mat(0, 1); 762 result(1, 0) = -mat(1, 0); 763 result(1, 1) = mat(0, 0); 764 765 return result * (1.0f / det); 766 } 767 768 template<class T, uint32_t N> inline 769 MatrixN<T, 3> MatrixN<T, N>::inverse (const MatrixN<T, 3>& mat) 770 { 771 MatrixN<T, 3> result; 772 773 T det = mat(0, 0) * mat(1, 1) * mat(2, 2) + 774 mat(1, 0) * mat(2, 1) * mat(0, 2) + 775 mat(2, 0) * mat(0, 1) * mat(1, 2) - 776 mat(0, 0) * mat(2, 1) * mat(1, 2) - 777 mat(1, 0) * mat(0, 1) * mat(2, 2) - 778 mat(2, 0) * mat(1, 1) * mat(0, 2); 779 780 if (det == (T)0) { 781 return result; 782 } 783 784 result(0, 0) = mat(1, 1) * mat(2, 2) - mat(1, 2) * mat(2, 1); 785 result(1, 0) = mat(1, 2) * mat(2, 0) - mat(1, 0) * mat(2, 2); 786 result(2, 0) = mat(1, 0) * mat(2, 1) - mat(1, 1) * mat(2, 0); 787 result(0, 1) = mat(0, 2) * mat(2, 1) - mat(0, 1) * mat(2, 2); 788 result(1, 1) = mat(0, 0) * mat(2, 2) - mat(0, 2) * mat(2, 0); 789 result(2, 1) = mat(0, 1) * mat(2, 0) - mat(0, 0) * mat(2, 1); 790 result(0, 2) = mat(0, 1) * mat(1, 2) - mat(0, 2) * mat(1, 1); 791 result(1, 2) = mat(0, 2) * mat(1, 0) - mat(0, 0) * mat(1, 2); 792 result(2, 2) = mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0); 793 794 return result * (1.0f / det); 795 } 796 797 template<class T, uint32_t N> inline 798 MatrixN<T, 4> MatrixN<T, N>::inverse (const MatrixN<T, 4>& mat) 799 { 800 MatrixN<T, 4> result; 801 802 T det = mat(0, 3) * mat(1, 2) * mat(2, 1) * mat(3, 1) - 803 mat(0, 2) * mat(1, 3) * mat(2, 1) * mat(3, 1) - 804 mat(0, 3) * mat(1, 1) * mat(2, 2) * mat(3, 1) + 805 mat(0, 1) * mat(1, 3) * mat(2, 2) * mat(3, 1) + 806 mat(0, 2) * mat(1, 1) * mat(2, 3) * mat(3, 1) - 807 mat(0, 1) * mat(1, 2) * mat(2, 3) * mat(3, 1) - 808 mat(0, 3) * mat(1, 2) * mat(2, 0) * mat(3, 1) + 809 mat(0, 2) * mat(1, 3) * mat(2, 0) * mat(3, 1) + 810 mat(0, 3) * mat(1, 0) * mat(2, 2) * mat(3, 1) - 811 mat(0, 0) * mat(1, 3) * mat(2, 2) * mat(3, 1) - 812 mat(0, 2) * mat(1, 0) * mat(2, 3) * mat(3, 1) + 813 mat(0, 0) * mat(1, 2) * mat(2, 3) * mat(3, 1) + 814 mat(0, 3) * mat(1, 1) * mat(2, 0) * mat(3, 2) - 815 mat(0, 1) * mat(1, 3) * mat(2, 0) * mat(3, 2) - 816 mat(0, 3) * mat(1, 0) * mat(2, 1) * mat(3, 2) + 817 mat(0, 0) * mat(1, 3) * mat(2, 1) * mat(3, 2) + 818 mat(0, 1) * mat(1, 0) * mat(2, 3) * mat(3, 2) - 819 mat(0, 0) * mat(1, 1) * mat(2, 3) * mat(3, 2) - 820 mat(0, 2) * mat(1, 1) * mat(2, 0) * mat(3, 3) + 821 mat(0, 1) * mat(1, 2) * mat(2, 0) * mat(3, 3) + 822 mat(0, 2) * mat(1, 0) * mat(2, 1) * mat(3, 3) - 823 mat(0, 0) * mat(1, 2) * mat(2, 1) * mat(3, 3) - 824 mat(0, 1) * mat(1, 0) * mat(2, 2) * mat(3, 3) + 825 mat(0, 0) * mat(1, 1) * mat(2, 2) * mat(3, 3); 826 827 if (det == (T)0) { 828 return result; 829 } 830 831 result(0, 0) = mat(1, 2) * mat(2, 3) * mat(3, 1) - 832 mat(1, 3) * mat(2, 2) * mat(3, 1) + 833 mat(1, 3) * mat(2, 1) * mat(3, 2) - 834 mat(1, 1) * mat(2, 3) * mat(3, 2) - 835 mat(1, 2) * mat(2, 1) * mat(3, 3) + 836 mat(1, 1) * mat(2, 2) * mat(3, 3); 837 838 result(0, 1) = mat(0, 3) * mat(2, 2) * mat(3, 1) - 839 mat(0, 2) * mat(2, 3) * mat(3, 1) - 840 mat(0, 3) * mat(2, 1) * mat(3, 2) + 841 mat(0, 1) * mat(2, 3) * mat(3, 2) + 842 mat(0, 2) * mat(2, 1) * mat(3, 3) - 843 mat(0, 1) * mat(2, 2) * mat(3, 3); 844 845 result(0, 2) = mat(0, 2) * mat(1, 3) * mat(3, 1) - 846 mat(0, 3) * mat(1, 2) * mat(3, 1) + 847 mat(0, 3) * mat(1, 1) * mat(3, 2) - 848 mat(0, 1) * mat(1, 3) * mat(3, 2) - 849 mat(0, 2) * mat(1, 1) * mat(3, 3) + 850 mat(0, 1) * mat(1, 2) * mat(3, 3); 851 852 result(0, 3) = mat(0, 3) * mat(1, 2) * mat(2, 1) - 853 mat(0, 2) * mat(1, 3) * mat(2, 1) - 854 mat(0, 3) * mat(1, 1) * mat(2, 2) + 855 mat(0, 1) * mat(1, 3) * mat(2, 2) + 856 mat(0, 2) * mat(1, 1) * mat(2, 3) - 857 mat(0, 1) * mat(1, 2) * mat(2, 3); 858 859 result(1, 0) = mat(1, 3) * mat(2, 2) * mat(3, 0) - 860 mat(1, 2) * mat(2, 3) * mat(3, 0) - 861 mat(1, 3) * mat(2, 0) * mat(3, 2) + 862 mat(1, 0) * mat(2, 3) * mat(3, 2) + 863 mat(1, 2) * mat(2, 0) * mat(3, 3) - 864 mat(1, 0) * mat(2, 2) * mat(3, 3); 865 866 result(1, 1) = mat(0, 2) * mat(2, 3) * mat(3, 0) - 867 mat(0, 3) * mat(2, 2) * mat(3, 0) + 868 mat(0, 3) * mat(2, 0) * mat(3, 2) - 869 mat(0, 0) * mat(2, 3) * mat(3, 2) - 870 mat(0, 2) * mat(2, 0) * mat(3, 3) + 871 mat(0, 0) * mat(2, 2) * mat(3, 3); 872 873 result(1, 2) = mat(0, 3) * mat(1, 2) * mat(3, 0) - 874 mat(0, 2) * mat(1, 3) * mat(3, 0) - 875 mat(0, 3) * mat(1, 0) * mat(3, 2) + 876 mat(0, 0) * mat(1, 3) * mat(3, 2) + 877 mat(0, 2) * mat(1, 0) * mat(3, 3) - 878 mat(0, 0) * mat(1, 2) * mat(3, 3); 879 880 result(1, 3) = mat(0, 2) * mat(1, 3) * mat(2, 0) - 881 mat(0, 3) * mat(1, 2) * mat(2, 0) + 882 mat(0, 3) * mat(1, 0) * mat(2, 2) - 883 mat(0, 0) * mat(1, 3) * mat(2, 2) - 884 mat(0, 2) * mat(1, 0) * mat(2, 3) + 885 mat(0, 0) * mat(1, 2) * mat(2, 3); 886 887 result(2, 0) = mat(1, 1) * mat(2, 3) * mat(3, 0) - 888 mat(1, 3) * mat(2, 1) * mat(3, 0) + 889 mat(1, 3) * mat(2, 0) * mat(3, 1) - 890 mat(1, 0) * mat(2, 3) * mat(3, 1) - 891 mat(1, 1) * mat(2, 0) * mat(3, 3) + 892 mat(1, 0) * mat(2, 1) * mat(3, 3); 893 894 result(2, 1) = mat(0, 3) * mat(2, 1) * mat(3, 0) - 895 mat(0, 1) * mat(2, 3) * mat(3, 0) - 896 mat(0, 3) * mat(2, 0) * mat(3, 1) + 897 mat(0, 0) * mat(2, 3) * mat(3, 1) + 898 mat(0, 1) * mat(2, 0) * mat(3, 3) - 899 mat(0, 0) * mat(2, 1) * mat(3, 3); 900 901 result(2, 2) = mat(0, 1) * mat(1, 3) * mat(3, 0) - 902 mat(0, 3) * mat(1, 1) * mat(3, 0) + 903 mat(0, 3) * mat(1, 0) * mat(3, 1) - 904 mat(0, 0) * mat(1, 3) * mat(3, 1) - 905 mat(0, 1) * mat(1, 0) * mat(3, 3) + 906 mat(0, 0) * mat(1, 1) * mat(3, 3); 907 908 result(2, 3) = mat(0, 3) * mat(1, 1) * mat(2, 0) - 909 mat(0, 1) * mat(1, 3) * mat(2, 0) - 910 mat(0, 3) * mat(1, 0) * mat(2, 1) + 911 mat(0, 0) * mat(1, 3) * mat(2, 1) + 912 mat(0, 1) * mat(1, 0) * mat(2, 3) - 913 mat(0, 0) * mat(1, 1) * mat(2, 3); 914 915 result(3, 0) = mat(1, 2) * mat(2, 1) * mat(3, 0) - 916 mat(1, 1) * mat(2, 2) * mat(3, 0) - 917 mat(1, 2) * mat(2, 0) * mat(3, 1) + 918 mat(1, 0) * mat(2, 2) * mat(3, 1) + 919 mat(1, 1) * mat(2, 0) * mat(3, 2) - 920 mat(1, 0) * mat(2, 1) * mat(3, 2); 921 922 result(3, 1) = mat(1, 1) * mat(2, 2) * mat(3, 0) - 923 mat(1, 2) * mat(2, 1) * mat(3, 0) + 924 mat(1, 2) * mat(2, 0) * mat(3, 1) - 925 mat(1, 0) * mat(2, 2) * mat(3, 1) - 926 mat(1, 1) * mat(2, 0) * mat(3, 2) + 927 mat(1, 0) * mat(2, 1) * mat(3, 2); 928 929 result(3, 2) = mat(0, 2) * mat(1, 1) * mat(3, 0) - 930 mat(0, 1) * mat(1, 2) * mat(3, 0) - 931 mat(0, 2) * mat(1, 0) * mat(3, 1) + 932 mat(0, 0) * mat(1, 2) * mat(3, 1) + 933 mat(0, 1) * mat(1, 0) * mat(3, 2) - 934 mat(0, 0) * mat(1, 1) * mat(3, 2); 935 936 result(3, 3) = mat(0, 1) * mat(1, 2) * mat(2, 0) - 937 mat(0, 2) * mat(1, 1) * mat(2, 0) + 938 mat(0, 2) * mat(1, 0) * mat(2, 1) - 939 mat(0, 0) * mat(1, 2) * mat(2, 1) - 940 mat(0, 1) * mat(1, 0) * mat(2, 2) + 941 mat(0, 0) * mat(1, 1) * mat(2, 2); 942 943 return result * (1.0f / det); 944 } 945 946 typedef VectorN<double, 2> Vec2d; 947 typedef VectorN<double, 3> Vec3d; 948 typedef VectorN<double, 4> Vec4d; 949 typedef MatrixN<double, 2> Mat2d; 950 typedef MatrixN<double, 3> Mat3d; 951 typedef MatrixN<double, 4> Mat4d; 952 953 typedef VectorN<float, 2> Vec2f; 954 typedef VectorN<float, 3> Vec3f; 955 typedef VectorN<float, 4> Vec4f; 956 typedef MatrixN<float, 3> Mat3f; 957 typedef MatrixN<float, 4> Mat4f; 958 959 template<class T> 960 class Quaternion 961 { 962 public: 963 964 Vec3d v; 965 T w; 966 967 Quaternion () : v(0, 0, 0), w(0) {}; 968 Quaternion (const Quaternion<T>& q) : v(q.v), w(q.w) {}; 969 970 Quaternion (const Vec3d& vec, T _w) : v(vec), w(_w) {}; 971 Quaternion (const Vec4d& vec) : v(vec[0], vec[1], vec[2]), w(vec[3]) {}; 972 Quaternion (T _x, T _y, T _z, T _w) : v(_x, _y, _z), w(_w) {}; 973 974 inline void reset () { 975 v.zeros(); 976 w = (T) 0; 977 } 978 979 inline Quaternion<T>& operator = (const Quaternion<T>& rhs) { 980 v = rhs.v; 981 w = rhs.w; 982 return *this; 983 } 984 985 inline Quaternion<T> operator + (const Quaternion<T>& rhs) const { 986 const Quaternion<T>& lhs = *this; 987 return Quaternion<T>(lhs.v + rhs.v, lhs.w + rhs.w); 988 } 989 990 inline Quaternion<T> operator - (const Quaternion<T>& rhs) const { 991 const Quaternion<T>& lhs = *this; 992 return Quaternion<T>(lhs.v - rhs.v, lhs.w - rhs.w); 993 } 994 995 inline Quaternion<T> operator * (T rhs) const { 996 return Quaternion<T>(v * rhs, w * rhs); 997 } 998 999 inline Quaternion<T> operator * (const Quaternion<T>& rhs) const { 1000 const Quaternion<T>& lhs = *this; 1001 return Quaternion<T>(lhs.w * rhs.v[0] + lhs.v[0] * rhs.w + lhs.v[1] * rhs.v[2] - lhs.v[2] * rhs.v[1], 1002 lhs.w * rhs.v[1] - lhs.v[0] * rhs.v[2] + lhs.v[1] * rhs.w + lhs.v[2] * rhs.v[0], 1003 lhs.w * rhs.v[2] + lhs.v[0] * rhs.v[1] - lhs.v[1] * rhs.v[0] + lhs.v[2] * rhs.w, 1004 lhs.w * rhs.w - lhs.v[0] * rhs.v[0] - lhs.v[1] * rhs.v[1] - lhs.v[2] * rhs.v[2]); 1005 } 1006 1007 /* 1008 -------- 1009 / -- 1010 |Qr| = \/ Qr.Qr 1011 */ 1012 inline T magnitude () const { 1013 return (T) sqrtf(w * w + v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 1014 } 1015 1016 inline void normalize () 1017 { 1018 T length = magnitude (); 1019 w = w / length; 1020 v = v / length; 1021 } 1022 1023 inline Quaternion<T> conjugate (const Quaternion<T>& quat) const { 1024 return Quaternion<T>(-quat.v, quat.w); 1025 } 1026 1027 inline Quaternion<T> inverse (const Quaternion<T>& quat) const { 1028 return conjugate(quat) * ( 1.0f / magnitude(quat)); 1029 } 1030 1031 inline Quaternion<T> lerp (T weight, const Quaternion<T>& quat) const { 1032 return Quaternion<T>(v.lerp(weight, quat.v), (1 - weight) * w + weight * quat.w); 1033 } 1034 1035 inline Quaternion<T> slerp(T r, const Quaternion<T>& quat) const { 1036 Quaternion<T> ret; 1037 T cos_theta = w * quat.w + v[0] * quat.v[0] + v[1] * quat.v[1] + v[2] * quat.v[2]; 1038 T theta = (T) acos(cos_theta); 1039 if (fabs(theta) < FLT_EPSILON) 1040 { 1041 ret = *this; 1042 } 1043 else 1044 { 1045 T sin_theta = (T) sqrt(1.0 - cos_theta * cos_theta); 1046 if (fabs(sin_theta) < FLT_EPSILON) 1047 { 1048 ret.w = 0.5 * w + 0.5 * quat.w; 1049 ret.v = v.lerp(0.5, quat.v); 1050 } 1051 else 1052 { 1053 T r0 = (T) sin((1.0 - r) * theta) / sin_theta; 1054 T r1 = (T) sin(r * theta) / sin_theta; 1055 1056 ret.w = w * r0 + quat.w * r1; 1057 ret.v[0] = v[0] * r0 + quat.v[0] * r1; 1058 ret.v[1] = v[1] * r0 + quat.v[1] * r1; 1059 ret.v[2] = v[2] * r0 + quat.v[2] * r1; 1060 } 1061 } 1062 return ret; 1063 } 1064 1065 static Quaternion<T> create_quaternion (Vec3d axis, T angle_rad) { 1066 T theta_over_two = angle_rad / (T) 2.0; 1067 T sin_theta_over_two = std::sin(theta_over_two); 1068 T cos_theta_over_two = std::cos(theta_over_two); 1069 return Quaternion<T>(axis * sin_theta_over_two, cos_theta_over_two); 1070 } 1071 1072 static Quaternion<T> create_quaternion (Vec3d euler) { 1073 return create_quaternion(Vec3d(1, 0, 0), euler[0]) * 1074 create_quaternion(Vec3d(0, 1, 0), euler[1]) * 1075 create_quaternion(Vec3d(0, 0, 1), euler[2]); 1076 } 1077 1078 static Quaternion<T> create_quaternion (const Mat3d& mat) { 1079 Quaternion<T> q; 1080 1081 T trace, s; 1082 T diag1 = mat(0, 0); 1083 T diag2 = mat(1, 1); 1084 T diag3 = mat(2, 2); 1085 1086 trace = diag1 + diag2 + diag3; 1087 1088 if (trace >= FLT_EPSILON) 1089 { 1090 s = 2.0 * (T) sqrt(trace + 1.0); 1091 q.w = 0.25 * s; 1092 q.v[0] = (mat(2, 1) - mat(1, 2)) / s; 1093 q.v[1] = (mat(0, 2) - mat(2, 0)) / s; 1094 q.v[2] = (mat(1, 0) - mat(0, 1)) / s; 1095 } 1096 else 1097 { 1098 char max_diag = (diag1 > diag2) ? ((diag1 > diag3) ? 1 : 3) : ((diag2 > diag3) ? 2 : 3); 1099 1100 if (max_diag == 1) 1101 { 1102 s = 2.0 * (T) sqrt(1.0 + mat(0, 0) - mat(1, 1) - mat(2, 2)); 1103 q.w = (mat(2, 1) - mat(1, 2)) / s; 1104 q.v[0] = 0.25 * s; 1105 q.v[1] = (mat(0, 1) + mat(1, 0)) / s; 1106 q.v[2] = (mat(0, 2) + mat(2, 0)) / s; 1107 } 1108 else if (max_diag == 2) 1109 { 1110 s = 2.0 * (T) sqrt(1.0 + mat(1, 1) - mat(0, 0) - mat(2, 2)); 1111 q.w = (mat(0, 2) - mat(2, 0)) / s; 1112 q.v[0] = (mat(0, 1) + mat(1, 0)) / s; 1113 q.v[1] = 0.25 * s; 1114 q.v[2] = (mat(1, 2) + mat(2, 1)) / s; 1115 } 1116 else 1117 { 1118 s = 2.0 * (T) sqrt(1.0 + mat(2, 2) - mat(0, 0) - mat(1, 1)); 1119 q.w = (mat(1, 0) - mat(0, 1)) / s; 1120 q.v[0] = (mat(0, 2) + mat(2, 0)) / s; 1121 q.v[1] = (mat(1, 2) + mat(2, 1)) / s; 1122 q.v[2] = 0.25 * s; 1123 } 1124 } 1125 1126 return q; 1127 } 1128 1129 inline Vec4d rotation_axis () { 1130 Vec4d rot_axis; 1131 1132 T cos_theta_over_two = w; 1133 rot_axis[4] = (T) std::acos( cos_theta_over_two ) * 2.0f; 1134 1135 T sin_theta_over_two = (T) sqrt( 1.0 - cos_theta_over_two * cos_theta_over_two ); 1136 if ( fabs( sin_theta_over_two ) < 0.0005 ) sin_theta_over_two = 1; 1137 rot_axis[0] = v[0] / sin_theta_over_two; 1138 rot_axis[1] = v[1] / sin_theta_over_two; 1139 rot_axis[2] = v[2] / sin_theta_over_two; 1140 1141 return rot_axis; 1142 } 1143 1144 /* 1145 psi=atan2(2.*(Q(:,1).*Q(:,4)-Q(:,2).*Q(:,3)),(Q(:,4).^2-Q(:,1).^2-Q(:,2).^2+Q(:,3).^2)); 1146 theta=asin(2.*(Q(:,1).*Q(:,3)+Q(:,2).*Q(:,4))); 1147 phi=atan2(2.*(Q(:,3).*Q(:,4)-Q(:,1).*Q(:,2)),(Q(:,4).^2+Q(:,1).^2-Q(:,2).^2-Q(:,3).^2)); 1148 */ 1149 inline Vec3d euler_angles () { 1150 Vec3d euler; 1151 1152 // atan2(2*(qx*qw-qy*qz) , qw2-qx2-qy2+qz2) 1153 euler[0] = atan2(2 * (v[0] * w - v[1] * v[2]), 1154 w * w - v[0] * v[0] - v[1] * v[1] + v[2] * v[2]); 1155 1156 // asin(2*(qx*qz + qy*qw) 1157 euler[1] = asin(2 * (v[0] * v[2] + v[1] * w)); 1158 1159 // atan2(2*(qz*qw- qx*qy) , qw2 + qx2 - qy2 - qz2) 1160 euler[2] = atan2(2 * (v[2] * w - v[0] * v[1]), 1161 w * w + v[0] * v[0] - v[1] * v[1] - v[2] * v[2]); 1162 1163 return euler; 1164 } 1165 1166 inline Mat3d rotation_matrix () { 1167 Mat3d mat; 1168 1169 T xx = v[0] * v[0]; 1170 T xy = v[0] * v[1]; 1171 T xz = v[0] * v[2]; 1172 T xw = v[0] * w; 1173 1174 T yy = v[1] * v[1]; 1175 T yz = v[1] * v[2]; 1176 T yw = v[1] * w; 1177 1178 T zz = v[2] * v[2]; 1179 T zw = v[2] * w; 1180 1181 mat(0, 0) = 1 - 2 * (yy + zz); 1182 mat(0, 1) = 2 * (xy - zw); 1183 mat(0, 2) = 2 * (xz + yw); 1184 mat(1, 0) = 2 * (xy + zw); 1185 mat(1, 1) = 1 - 2 * (xx + zz); 1186 mat(1, 2) = 2 * (yz - xw); 1187 mat(2, 0) = 2 * (xz - yw); 1188 mat(2, 1) = 2 * (yz + xw); 1189 mat(2, 2) = 1 - 2 * (xx + yy); 1190 1191 return mat; 1192 } 1193 }; 1194 1195 1196 typedef Quaternion<double> Quaternd; 1197 1198 } 1199 1200 #endif //XCAM_VECTOR_MATRIX_H 1201