https://github.com/JStech/ICP
Raw File
Tip revision: f8d9a06202c7ec1fd6e5c014665a1715bcf28c78 authored by John Stechschulte on 08 May 2018, 21:30:45 UTC
more ignorance
Tip revision: f8d9a06
dualquat.cpp
// Copyright 2017 John Stechschulte
#include "include/dualquat.h"
#include <Eigen/Dense>
#include <cmath>

template <typename T>
Quat<T>::Quat(pcl::PointXYZ p) {
  this->w = (T) 0.;
  this->x = (T) p.x;
  this->y = (T) p.y;
  this->z = (T) p.z;
  *this *= (T) 0.5;
}

template <typename T>
Quat<T>::Quat(Eigen::Vector3d vector, T rotation_radians) {
  vector = vector / vector.norm();
  T s = sin(rotation_radians/2);
  this->w = cos(rotation_radians/2);
  this->x = vector[0] * s;
  this->y = vector[1] * s;
  this->z = vector[2] * s;
  this->normalize();
}

template <typename T>
Quat<T>::Quat(Eigen::Matrix<T, 4, 1> vector) {
  this->w = vector[3];
  this->x = vector[0];
  this->y = vector[1];
  this->z = vector[2];
}

template <typename T>
Quat<T> Quat<T>::fromRotationMatrix(Eigen::Matrix<T, 3, 3> m) {
  Quat<T> q;
  q.w = sqrt(1. + m(0, 0) + m(1, 1) + m(2, 2))/2.;
  T w4 = 4.*q.w;
  q.x = (m(2, 1) - m(1, 2))/w4;
  q.y = (m(0, 2) - m(2, 0))/w4;
  q.z = (m(1, 0) - m(0, 1))/w4;
  return q;
}

template <typename T>
Quat<T>& Quat<T>::Identity() {
  this->w = (T) 1.0;
  this->x = this->y = this->z = (T) 0.0;
  return *this;
}

template <typename T>
T Quat<T>::Angle() const {
  return 2.*acos(fabs(this->w));
}

template <typename T>
Eigen::Vector3d Quat<T>::RotAxis() const {
  double theta = 2.*acos(this->w);
  Eigen::Vector3d r(this->x, this->y, this->z);
  r = r/r.norm();
  r = theta * r;
  return r;
}

template <typename T>
Quat<T> Quat<T>::conjugate() const {
  return Quat<T>(this->w, -this->x, -this->y, -this->z);
}

template <typename T>
T Quat<T>::magnitude() const {
  return sqrt(this->w*this->w + this->x*this->x + this->y*this->y + this->z*this->z);
}

template <typename T>
void Quat<T>::normalize() {
  T magnitude = this->magnitude();
  this->w /= magnitude;
  this->x /= magnitude;
  this->y /= magnitude;
  this->z /= magnitude;
}

template <typename T>
Eigen::Matrix<T, 3, 3> Quat<T>::K() const {
  Eigen::Matrix<T, 3, 3> k;
  k <<           (T) 0., -this->vector[2],  this->vector[1],
        this->vector[2],           (T) 0., -this->vector[0],
       -this->vector[1],  this->vector[0],           (T) 0.;
  return k;
}

template <typename T>
Eigen::Matrix<T, 4, 4> Quat<T>::Q() const {
  Eigen::Matrix<T, 4, 4> q;
  q.block(0, 0, 3, 3) = this->K();
  q(0, 0) = q(1, 1) = q(2, 2) = q(3, 3) = this->w;
  q(0, 3) = this->x; q(3, 0) = -this->x;
  q(1, 3) = this->y; q(3, 1) = -this->y;
  q(2, 3) = this->z; q(3, 2) = -this->z;
  return q;
}

template <typename T>
Eigen::Matrix<T, 4, 4> Quat<T>::W() const {
  Eigen::Matrix<T, 4, 4> w;
  w.block(0, 0, 3, 3) = -this->K();
  w(0, 0) = w(1, 1) = w(2, 2) = w(3, 3) = this->w;
  w(0, 3) = this->x; w(3, 0) = -this->x;
  w(1, 3) = this->y; w(3, 1) = -this->y;
  w(2, 3) = this->z; w(3, 2) = -this->z;
  return w;
}

template <typename T>
Eigen::Matrix<T, 4, 4> Quat<T>::R() const {
  return this->W().transpose() * this->Q();
}

template <typename T>
Eigen::Matrix<T, 3, 3> Quat<T>::Rot() const {
  T norm = this->magnitude();
  T w = this->w/norm;
  T x = this->x/norm;
  T y = this->y/norm;
  T z = this->z/norm;
  Eigen::Matrix<T, 3, 3> r;
  r << 1 - 2*y*y - 2*z*z,     2*x*y - 2*z*w,     2*x*z + 2*y*w,
           2*x*y + 2*z*w, 1 - 2*x*x - 2*z*z,     2*y*z - 2*x*w,
           2*x*z - 2*w*y,     2*w*x + 2*y*z, 1 - 2*x*x - 2*y*y;
  return r;
}

template <typename T>
DualQuat<T>::DualQuat(pcl::PointXYZ point) {
  this->d = Quat<T>(point);
  this->r = Quat<T>().Identity();
}

template <typename T>
DualQuat<T>& DualQuat<T>::Identity() {
  this->r.w = 1.;
  this->r.x = this->r.y = this->r.z = 0.;
  this->d.w = this->d.x = this->d.y = this->d.z = 0.;
  return *this;
}

template <typename T>
DualQuat<T> DualQuat<T>::conjugate() const {
  return DualQuat<T>(this->r.conjugate(), this->d.conjugate());
}

template <typename T>
T DualQuat<T>::realMagnitude() const {
  return this->r.magnitude();
}

template <typename T>
T DualQuat<T>::sumSq() const {
  return this->r.w*this->r.w + this->r.x*this->r.x +
    this->r.y*this->r.y + this->r.z*this->r.z +
    this->d.w*this->d.w + this->d.x*this->d.x +
    this->d.y*this->d.y + this->d.z*this->d.z;
}

template <typename T>
void DualQuat<T>::normalize() {
  this->r.normalize();
}

template <typename T>
Eigen::Matrix<T, 4, 4> DualQuat<T>::Matrix() const {
  Eigen::Matrix<T, 4, 4> out = this->r.W().transpose()*this->r.Q();
  out.block(0, 3, 3, 1) = (this->getTranslation()).template cast<T>();
  return out;
}

template <typename T>
Eigen::Vector3d DualQuat<T>::getTranslation() const {
  Quat<T> t = this->r.conjugate();
  t = (((T) 2.)*this->d)*t;
  Eigen::Vector3d ret(t.x, t.y, t.z);
  return ret;
}

template class Quat<float>;
template class DualQuat<float>;
back to top