You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
3.5 KiB

#ifndef GFXQUAT_INCLUDED // -*- C++ -*-
#define GFXQUAT_INCLUDED
#if !defined(__GNUC__)
# pragma once
#endif
/************************************************************************
Quaternion class
$Id: quat.h 440 2005-02-23 05:14:13Z garland $
************************************************************************/
#include "mat4.h"
namespace gfx
{
class Quat
{
private:
Vec3 v; // Vector component
double s; // Scalar component
public:
Quat() { v=0.0; s=1.0; }
Quat(double x, double y, double z, double w) { v[0]=x;v[1]=y;v[2]=z; s=w; }
Quat(const Vec3& a, double b) { v=a; s=b; }
Quat(const Quat& q) { *this=q; }
// Access methods
const Vec3& vector() const { return v; }
Vec3& vector() { return v; }
double scalar() const { return s; }
double& scalar() { return s; }
// Assignment and in-place arithmetic methods
Quat& operator=(const Quat& q);
Quat& operator+=(const Quat& q);
Quat& operator-=(const Quat& q);
Quat& operator=(double d);
Quat& operator*=(double d);
Quat& operator/=(double d);
// Construction of standard quaternions
static Quat ident();
};
////////////////////////////////////////////////////////////////////////
//
// Implementation of Quat methods
//
inline Quat& Quat::operator=(const Quat& q) { v=q.v; s=q.s; return *this; }
inline Quat& Quat::operator+=(const Quat& q) { v+=q.v; s+=q.s; return *this; }
inline Quat& Quat::operator-=(const Quat& q) { v-=q.v; s-=q.s; return *this; }
inline Quat& Quat::operator=(double d) { v=d; s=d; return *this; }
inline Quat& Quat::operator*=(double d) { v*=d; s*=d; return *this; }
inline Quat& Quat::operator/=(double d) { v/=d; s/=d; return *this; }
inline Quat Quat::ident() { return Quat(0, 0, 0, 1); }
////////////////////////////////////////////////////////////////////////
//
// Standard arithmetic operators on quaternions
//
inline Quat operator+(const Quat& q, const Quat& r)
{ return Quat(q.vector()+r.vector(), q.scalar()+r.scalar()); }
inline Quat operator*(const Quat& q, const Quat& r)
{
return Quat(cross(q.vector(),r.vector()) +
r.scalar()*q.vector() +
q.scalar()*r.vector(),
q.scalar()*r.scalar() - q.vector()*r.vector());
}
inline Quat operator*(const Quat& q, double s)
{ return Quat(q.vector()*s, q.scalar()*s); }
inline Quat operator*(double s, const Quat& q)
{ return Quat(q.vector()*s, q.scalar()*s); }
inline Quat operator/(const Quat& q, double s)
{ return Quat(q.vector()/s, q.scalar()/s); }
inline std::ostream &operator<<(std::ostream &out, const Quat& q)
{ return out << q.vector() << " " << q.scalar(); }
inline std::istream &operator>>(std::istream &in, Quat& q)
{ return in >> q.vector() >> q.scalar(); }
////////////////////////////////////////////////////////////////////////
//
// Standard functions on quaternions
//
inline double norm(const Quat& q)
{ return q.scalar()*q.scalar() + q.vector()*q.vector(); }
inline Quat conjugate(const Quat& q) { return Quat(-q.vector(), q.scalar()); }
inline Quat inverse(const Quat& q) { return conjugate(q)/norm(q); }
inline Quat& unitize(Quat& q) { q /= sqrt(norm(q)); return q; }
extern Quat exp(const Quat& q);
extern Quat log(const Quat& q);
extern Quat axis_to_quat(const Vec3& a, double phi);
extern Mat4 quat_to_matrix(const Quat& q);
extern Mat4 unit_quat_to_matrix(const Quat& q);
extern Quat slerp(const Quat& from, const Quat& to, double t);
} // namespace gfx
// GFXQUAT_INCLUDED
#endif