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 ************************************************************************/
33 #include "glui_internal_control.h"
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 );