zenilib: zenilib/jni/external/zenilib/zeni/Quaternion.cpp Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Quaternion.cpp
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2 * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3 *
4 * zenilib is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * zenilib is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <zeni.h>
19
20 #include <cmath>
21
22 #include <Zeni/Define.h>
23
24 namespace Zeni {
25
26 Quaternion::Quaternion(const float &t, const Vector3f &s, const bool &degenerate_)
27 : time(t),
28 space(s),
29 degenerate(s.degenerate || degenerate_)
30 {
31 }
32
33 Quaternion Quaternion::Vector3f_to_Vector3f(const Vector3f &destination, const Vector3f &source) {
34 const Vector3f axis = source % destination;
35 const float angle = source.angle_between(destination);
36 Quaternion rotation = Quaternion::Axis_Angle(axis, angle);
37
38 if(rotation.degenerate) {
39 if(INFINTESSIMAL(angle))
40 return Quaternion();
41 else {
42 const Vector3f pos(fabsf(source.i), fabsf(source.j), fabsf(source.k));
43
44 if(pos.i < pos.j && pos.i < pos.k)
45 rotation = Quaternion::Axis_Angle(source % Vector3f(1.0f, 0.0f, 0.0f), Global::pi);
46 else if(pos.j < pos.k)
47 rotation = Quaternion::Axis_Angle(source % Vector3f(0.0f, 1.0f, 0.0f), Global::pi);
48 else
49 rotation = Quaternion::Axis_Angle(source % Vector3f(0.0f, 0.0f, 1.0f), Global::pi);
50 }
51 }
52
53 return rotation.normalized();
54 }
55
56 Quaternion Quaternion::Axis_Angle(const Vector3f &v, const float &theta) {
57 const float half_theta = 0.5f * theta;
58
59 const float time = float(cos(half_theta));
60 const float space_coeff = float(sin(half_theta));
61 const Vector3f space_vec = v.normalized();
62
63 return Quaternion(time, space_coeff * space_vec, space_vec.degenerate).normalized();
64 }
65
66 Quaternion Quaternion::Forward_Up(const Vector3f &destination_forward,
67 const Vector3f &destination_up,
68 const Vector3f &default_forward,
69 const Vector3f &default_up)
70 {
71 const Vector3f axis0 = default_forward % destination_forward;
72 const float angle0 = default_forward.angle_between(destination_forward);
73
74 Quaternion rotation0 = Quaternion::Axis_Angle(axis0, angle0);
75 if(rotation0.degenerate) {
76 if(INFINTESSIMAL(angle0))
77 rotation0 = Quaternion();
78 else
79 rotation0 = Quaternion::Axis_Angle(default_up, Global::pi);
80 }
81
82 const Vector3f intermediate_up = rotation0 * default_up;
83 const Vector3f axis1 = intermediate_up % destination_up;
84 const float angle1 = intermediate_up.angle_between(destination_up);
85
86 Quaternion rotation1 = Quaternion::Axis_Angle(axis1, angle1);
87 if(rotation1.degenerate) {
88 if(INFINTESSIMAL(angle1))
89 rotation1 = Quaternion();
90 else
91 rotation1 = Quaternion::Axis_Angle(destination_forward, Global::pi);
92 }
93
94 return (rotation1 * rotation0).normalized();
95 }
96
97 Quaternion::Quaternion(const float &yaw, const float &pitch, const float &roll, const bool &degenerate_)
98 : degenerate(degenerate_)
99 {
100 const float half_yaw = 0.5f * yaw;
101 const float half_pitch = 0.5f * pitch;
102 const float half_roll = 0.5f * roll;
103
104 const float shy = float(sin(half_yaw));
105 const float shp = float(sin(half_pitch));
106 const float shr = float(sin(half_roll));
107 const float chy = float(cos(half_yaw));
108 const float chp = float(cos(half_pitch));
109 const float chr = float(cos(half_roll));
110
111 time = chr * chp * chy + shr * shp * shy;
112 space.i = shr * chp * chy - chr * shp * shy;
113 space.j = chr * shp * chy + shr * chp * shy;
114 space.k = chr * chp * shy - shr * shp * chy;
115 }
116
117 Quaternion::Quaternion(const Quaternion &rhs, const bool &degenerate_)
118 : time(rhs.time),
119 space(rhs.space),
120 degenerate(rhs.degenerate || degenerate_)
121 {
122 }
123
124 Quaternion & Quaternion::normalize() {
125 float mplier = magnitude();
126
127 if(INFINTESSIMAL(mplier)) {
128 degenerate = true;
129 return *this;
130 }
131
132 mplier = 1.0f / mplier;
133
134 time *= mplier;
135 space *= mplier;
136
137 return *this;
138 }
139
140 Quaternion Quaternion::normalized() const {
141 float mplier = magnitude();
142
143 if(INFINTESSIMAL(mplier))
144 return Quaternion(*this, true);
145
146 mplier = 1.0f / mplier;
147
148 return Quaternion(time * mplier, space * mplier);
149 }
150
151 std::ostream & serialize(std::ostream &os, const Quaternion &value) {
152 return serialize(serialize(os, value.time), value.space);
153 }
154
155 std::istream & unserialize(std::istream &is, Quaternion &value) {
156 return unserialize(unserialize(is, value.time), value.space);
157 }
158
159 }
160
161 #include <Zeni/Undefine.h>
Zeni::Quaternion::time
float time
Definition: Quaternion.h:104
Zeni::Quaternion::Vector3f_to_Vector3f
static Quaternion Vector3f_to_Vector3f(const Vector3f &destination, const Vector3f &source)
Create a Quaternion rotating to one Vector3f from another.
Definition: Quaternion.cpp:33
s
GLdouble s
Definition: glew.h:1376
Zeni::Quaternion::degenerate
bool degenerate
Definition: Quaternion.h:107
f
GLclampf f
Definition: glew.h:3390
angle
GLdouble angle
Definition: glew.h:8396
Zeni::Quaternion::Axis_Angle
static Quaternion Axis_Angle(const Vector3f &v, const float &theta)
Create a Quaternion from an Axis/Angle pair.
Definition: Quaternion.cpp:56
t
GLdouble GLdouble t
Definition: glew.h:1384
Zeni::Quaternion::space
Vector3f space
Definition: Quaternion.h:105
Zeni::unserialize
std::istream & unserialize(std::istream &is, Color &value)
Definition: Color.cpp:72
Zeni::serialize
std::ostream & serialize(std::ostream &os, const Color &value)
Definition: Color.cpp:68
Undefine.h
Zeni::Vector3f
A Featureful 3-Space Vector Class.
Definition: Vector3f.h:58
v
const GLdouble * v
Definition: glew.h:1377
Zeni::Vector3f::degenerate
bool degenerate
Definition: Vector3f.h:123
Zeni::Global::pi
const float pi
pi == 3.1415926...
Definition: Vector3f.cpp:27
Define.h
Zeni::Quaternion::normalized
Quaternion normalized() const
Get the normalized vector.
Definition: Quaternion.cpp:140
Zeni::Quaternion
A Featureful Quaternion Class.
Definition: Quaternion.h:44
Zeni::Quaternion::Forward_Up
static Quaternion Forward_Up(const Vector3f &destination_forward, const Vector3f &destination_up, const Vector3f &default_forward=ZENI_DEFAULT_FORWARD_VECTOR, const Vector3f &default_up=ZENI_DEFAULT_UP_VECTOR)
Create a Quaternion from a Forward/Up Vector3f pair.
Definition: Quaternion.cpp:66
Zeni::Vector3f::angle_between
float angle_between(const Vector3f &rhs) const
Find the angle between the Vector3fs.
Definition: Vector3f.hxx:178
Zeni::Vector3f::k
float k
Definition: Vector3f.h:119
Zeni::Quaternion::magnitude
float magnitude() const
Get the magnitude of the vector.
Definition: Quaternion.hxx:123
sin
double sin(double x)
Definition: s_sin.c:56
Zeni::Vector3f::j
float j
Definition: Vector3f.h:115
value
EGLSurface EGLint void ** value
Definition: eglext.h:301
Zeni::Quaternion::Quaternion
Quaternion(const bool &degenerate_=false)
Definition: Quaternion.hxx:34
zeni.h
cos
double cos(double x)
Definition: s_cos.c:56
source
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
Zeni::Vector3f::i
float i
Definition: Vector3f.h:111
Zeni::Quaternion::normalize
Quaternion & normalize()
Normalize the vector.
Definition: Quaternion.cpp:124
Zeni::Vector3f::normalized
Vector3f normalized() const
Get the normalized vector.
Definition: Vector3f.cpp:58
INFINTESSIMAL
#define INFINTESSIMAL(x)
Definition: Define.h:134