1
/***********************************************************************
3
quaternion.cpp - A quaternion class
5
-------------------------------------------------------------------
7
GLUI User Interface Toolkit (LGPL)
8
Copyright (c) 1998 Paul Rademacher
10
WWW: http://sourceforge.net/projects/glui/
11
Forums: http://sourceforge.net/forum/?group_id=92496
13
This library is free software; you can redistribute it and/or
14
modify it under the terms of the GNU Lesser General Public
15
License as published by the Free Software Foundation; either
16
version 2.1 of the License, or (at your option) any later version.
18
This library is distributed in the hope that it will be useful,
19
but WITHOUT ANY WARRANTY; without even the implied warranty of
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
Lesser General Public License for more details.
23
You should have received a copy of the GNU Lesser General Public
24
License along with this library; if not, write to the Free Software
25
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
************************************************************************
29
Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
30
Oct 2003, Nigel Stewart - GLUI Code Cleaning
32
************************************************************************/
34
#include "quaternion.h"
36
#include "glui_internal.h"
38
/******************************************* constructors **************/
42
*this = quat_identity();
45
quat::quat(const float x, const float y, const float z, const float w)
51
quat::quat(const vec3 &_v, const float _s)
56
quat::quat(const float _s, const vec3 &_v)
61
quat::quat(const float *d)
69
quat::quat(const double *d)
77
quat::quat(const quat &q)
83
void quat::set(const vec3 &_v, const float _s)
89
quat &quat::operator=(const quat &q)
96
/******** quat friends ************/
98
quat operator + (const quat &a, const quat &b)
100
return quat( a.s+b.s, a.v+b.v );
103
quat operator - (const quat &a, const quat &b)
105
return quat( a.s-b.s, a.v-b.v );
108
quat operator - (const quat &a )
110
return quat( -a.s, -a.v );
113
quat operator * ( const quat &a, const quat &b)
115
return quat( a.s*b.s - a.v*b.v, a.s*b.v + b.s*a.v + a.v^b.v );
118
quat operator * ( const quat &a, const float t)
120
return quat( a.v * t, a.s * t );
123
quat operator * ( const float t, const quat &a )
125
return quat( a.v * t, a.s * t );
128
mat4 quat::to_mat4() const
130
float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
132
float t = 2.0f / (v*v + s*s);
134
xs = v[VX]*t; ys = v[VY]*t; zs = v[VZ]*t;
135
wx = s*xs; wy = s*ys; wz = s*zs;
136
xx = v[VX]*xs; xy = v[VX]*ys; xz = v[VX]*zs;
137
yy = v[VY]*ys; yz = v[VY]*zs; zz = v[VZ]*zs;
140
1.0f-(yy+zz), xy+wz, xz-wy, 0.0f,
141
xy-wz, 1.0f-(xx+zz), yz+wx, 0.0f,
142
xz+wy, yz-wx, 1.0f-(xx+yy), 0.0f,
143
0.0f, 0.0f, 0.0f, 1.0f );
148
/************************************************* quat_identity() *****/
149
/* Returns quaternion identity element */
153
return quat( vec3( 0.0, 0.0, 0.0 ), 1.0 );
156
/************************************************ quat_slerp() ********/
157
/* Quaternion spherical interpolation */
159
quat quat_slerp(const quat &from, const quat &to, float t)
162
float omega, cosom, sinom, scale0, scale1;
164
/* calculate cosine */
165
cosom = from.v * to.v + from.s + to.s;
167
/* Adjust signs (if necessary) */
178
/* Calculate coefficients */
179
if ((1.0 - cosom) > FUDGE )
181
/* standard case (slerp) */
182
omega = (float) acos( cosom );
183
sinom = (float) sin( omega );
184
scale0 = (float) sin((1.0 - t) * omega) / sinom;
185
scale1 = (float) sin(t * omega) / sinom;
189
/* 'from' and 'to' are very close - just do linear interpolation */
194
return scale0 * from + scale1 * to1;
197
/********************************************** set_angle() ************/
198
/* set rot angle (degrees) */
200
void quat::set_angle(float f)
202
vec3 axis = get_axis();
204
s = (float) cos( DEG2RAD( f ) / 2.0 );
206
v = axis * (float) sin(DEG2RAD(f) / 2.0);
209
/********************************************** scale_angle() ************/
210
/* scale rot angle (degrees) */
212
void quat::scale_angle(float f)
214
set_angle( f * get_angle() );
217
/********************************************** get_angle() ************/
218
/* get rot angle (degrees). Assumes s is between -1 and 1 */
220
float quat::get_angle() const
222
return (float) RAD2DEG( 2.0 * acos( s ) );
225
/********************************************* get_axis() **************/
227
vec3 quat::get_axis() const
229
float scale = (float) sin( acos( s ) );
231
if ( scale < FUDGE AND scale > -FUDGE )
232
return vec3( 0.0, 0.0, 0.0 );
237
/******************************************* quat::print() ************/
239
void quat::print(FILE *dest, const char *name) const
241
fprintf( dest, "%s: v:<%3.2f %3.2f %3.2f> s:%3.2f\n",
242
name, v[0], v[1], v[2], s );