Fixed Point Arithmetic  0
Fixed-point math library.
quaternion.h
Go to the documentation of this file.
1 
39 #include "../quaternion.h"
40 #include "../vector.h"
41 #include "../fixed_point.h"
42 
52 {
53  quat s;
54 #define _QTR(e) s.e = df_to_f(q.e)
55 
56  _QTR(r);
57  _QTR(v.x);
58  _QTR(v.y);
59  _QTR(v.z);
60 
61 #undef _QTR
62 
63  return s;
64 }
65 
73 {
74  frac _0_5 = {FRAC_0_5_V};
75  return f_sub(_0_5, df_to_f(
77  f_mul_df(q.r, q.r), f_mul_df(q.v.x, q.v.x)),
78  f_mul_df(q.v.y, q.v.y)),f_mul_df(q.v.z, q.v.z)),2)));
79 }
80 
85 {
86  dquat s;
87 
88  s.r = f_mul_df(q.r, f);
89  s.v.x = f_mul_df(q.v.x, f);
90  s.v.y = f_mul_df(q.v.y, f);
91  s.v.z = f_mul_df(q.v.z, f);
92 
93  return s;
94 }
95 
100 {
101  quat s;
102 
103  s.r = f_mul(q.r, f);
104  s.v.x = f_mul(q.v.x, f);
105  s.v.y = f_mul(q.v.y, f);
106  s.v.z = f_mul(q.v.z, f);
107 
108  return s;
109 }
110 
117 {
118  quat p;
119 
120  p.r = q.r;
121  p.v.x = f_neg(q.v.x);
122  p.v.y = f_neg(q.v.y);
123  p.v.z = f_neg(q.v.z);
124 
125  return p;
126 }
127 
132 {
133  quat s;
134 
135  s.r = f_sub( f_sub( f_sub(
136  f_mul(q.r,p.r), f_mul(q.v.x,p.v.x))
137  ,f_mul(q.v.y,p.v.y)), f_mul(q.v.z,p.v.z));
138 
139  s.v.x = f_add(f_sub(f_add(
140  f_mul(p.r,q.v.x), f_mul(p.v.x,q.r)),
141  f_mul(p.v.y,q.v.z)), f_mul(p.v.z,q.v.y));
142 
143  s.v.y = f_sub(f_add(f_add(
144  f_mul(p.r,q.v.y), f_mul(p.v.x,q.v.z)),
145  f_mul(p.v.y,q.r)), f_mul(p.v.z,q.v.x));
146 
147  s.v.z = f_add(f_add(f_sub(
148  f_mul(p.r,q.v.z), f_mul(p.v.x,q.v.y)),
149  f_mul(p.v.y,q.v.x)),f_mul(p.v.z,q.r));
150 
151  return s;
152 }
153 
160 {
161  dquat s;
162 
164  f_mul_df(q.r,p.r),f_mul_df(q.v.x,p.v.x)),
165  f_mul_df(q.v.y,p.v.y)),f_mul_df(q.v.z,p.v.z)) , f);
166 
167  s.v.x = df_idiv( df_add(df_sub(df_add(
168  f_mul_df(p.r,q.v.x),f_mul_df(p.v.x,q.r)),
169  f_mul_df(p.v.y,q.v.z)),f_mul_df(p.v.z,q.v.y)), f);
170 
171  s.v.y = df_idiv( df_sub(df_add(df_add(
172  f_mul_df(p.r,q.v.y),f_mul_df(p.v.x,q.v.z)),
173  f_mul_df(p.v.y,q.r)),f_mul_df(p.v.z,q.v.x)), f);
174 
175  s.v.z = df_idiv( df_add(df_add(df_sub(
176  f_mul_df(p.r,q.v.z),f_mul_df(p.v.x,q.v.y)),
177  f_mul_df(p.v.y,q.v.x)),f_mul_df(p.v.z,q.r)), f);
178 
179  return s;
180 }
181 
188 {
189  dquat s;
190 
191  s.r = df_sub(df_sub(df_sub(
192  f_mul_df(q.r,p.r),f_mul_df(q.v.x,p.v.x)),
193  f_mul_df(q.v.y,p.v.y)),f_mul_df(q.v.z,p.v.z));
194 
195  s.v.x = df_add(df_sub(df_add(
196  f_mul_df(p.r,q.v.x),f_mul_df(p.v.x,q.r)),
197  f_mul_df(p.v.y,q.v.z)),f_mul_df(p.v.z,q.v.y));
198 
199  s.v.y = df_sub(df_add(df_add(
200  f_mul_df(p.r,q.v.y),f_mul_df(p.v.x,q.v.z)),
201  f_mul_df(p.v.y,q.r)),f_mul_df(p.v.z,q.v.x));
202 
203  s.v.z = df_add(df_add(df_sub(
204  f_mul_df(p.r,q.v.z),f_mul_df(p.v.x,q.v.y)),
205  f_mul_df(p.v.y,q.v.x)),f_mul_df(p.v.z,q.r));
206 
207  return s;
208 }
209 
214 {
215  dquat s;
216 #define _QSUM(e) s.e = df_add(q.e, p.e)
217 
218  _QSUM(r);
219  _QSUM(v.x);
220  _QSUM(v.y);
221  _QSUM(v.z);
222 
223 #undef _QSUM
224  return s;
225 }
226 
231 {
232  quat s;
233 #define _QSUM(e) s.e = f_add(q.e, p.e)
234 
235  _QSUM(r);
236  _QSUM(v.x);
237  _QSUM(v.y);
238  _QSUM(v.z);
239 
240 #undef _QSUM
241  return s;
242 }
243 
251 {
252  quat _v;
253  frac _0 = {0};
254 
255  _v.r = _0;
256  _v.v = v;
257 
258  return q_mul(q, q_mul(_v, q_conj(q))).v;
259 }
260 
269 {
270  frac err;
271  quat correction;
272 
273  err = q_xnormerror(q);
274  correction = q_scale(q, err);
275  return q_add(q, correction);
276 }
277 
284 {
285  frac err;
286  dquat correction;
287  quat qh = dq_to_q(q);
288 
289  err = q_xnormerror(qh);
290  correction = q_scale_dq(qh, err);
291  return dq_add(q, correction);
292 }
293 
303 {
304  frac norm_err;
305  frac the_axis;
306  frac _0_5 = {FRAC_0_5_V};
307  quat ret = {{0}, VEC0};
308 
309  switch (axis) {
310  case AXIS_X:
311  the_axis = q.v.x;
312  break;
313  case AXIS_Y:
314  the_axis = q.v.y;
315  break;
316  case AXIS_Z:
317  the_axis = q.v.z;
318  break;
319  }
320 
321  norm_err = f_sub(_0_5, f_idiv(df_to_f(df_add(f_mul_df(q.r, q.r),
322  f_mul_df(the_axis,the_axis))),2));
323 
324  ret.r = f_add(q.r, f_mul(norm_err, q.r));
325  the_axis = f_add(the_axis, f_mul(norm_err, the_axis));
326 
327  switch (axis) {
328  case AXIS_X:
329  ret.v.x = the_axis;
330  break;
331  case AXIS_Y:
332  ret.v.y = the_axis;
333  break;
334  case AXIS_Z:
335  ret.v.z = the_axis;
336  break;
337  }
338 
339  return ret;
340 }
341 
356 {
357  quat c = q_mul(q_conj(pos), setp);
358 
359  return v_fmul(c.v, c.r);
360 }
361 
369 {
370  quat c = q_mul(q_conj(pos), setp);
371 
372  return v_imul(c.v, F_SIGN(c.r));
373 }
374 
dquat dq_add(dquat q, dquat p)
Quaternion addition (double precision).
Definition: quaternion.h:213
Double precision quaternion.
frac q_xnormerror(quat q)
Pseudo-error of the quaternion norm.
Definition: quaternion.h:72
quat q_scale(quat q, frac f)
Scale a quaternion by a fractional, return simple precision quaternion.
Definition: quaternion.h:99
frac f_sub(frac a, frac b)
Substract two single precision fractional numbers - may overflow.
Definition: fixed_point.h:162
frac df_to_f(dfrac x)
Truncate to single precision.
Definition: fixed_point.h:406
vec3 q_error2(quat setp, quat pos)
This error has a discontinuity at 180 degrees.
Definition: quaternion.h:368
#define _QTR(e)
#define VEC0
Literal for the Zero vector.
Definition: vector_types.h:84
dquat q_scale_dq(quat q, frac f)
Scale a quaternion by a fractional, return double precision quaternion.
Definition: quaternion.h:84
quat dq_to_q(dquat q)
Truncate double precision quaternion to single precision.
Definition: quaternion.h:51
frac f_idiv(frac a, int16_t b)
Divide single precision by integer, yield single precision.
Definition: fixed_point.h:331
frac f_neg(frac a)
Negate single precision fractional.
Definition: fixed_point.h:184
dquat q_mul_s_dq(quat q, quat p, int f)
Scaled Quaternion multiplication, return value is double precision.
Definition: quaternion.h:159
dfrac df_sub(dfrac a, dfrac b)
Substract two double precision fractional numbers - may overflow.
Definition: fixed_point.h:168
frac y
Definition: vector_types.h:62
vec3 v_imul(vec3 a, int16_t b)
Multiply vector by integer having the same width as frac.
Definition: vector.h:90
vec3 v_fmul(vec3 a, frac b)
Multiply a single precision vector by a fractional, yield single precision.
Definition: vector.h:145
dfrac df_idiv(dfrac a, int16_t b)
Divide double precision by integer, yield double precision.
Definition: fixed_point.h:346
quat q_conj(quat q)
Conjugate quaternion.
Definition: quaternion.h:116
#define _QSUM(e)
frac z
Definition: vector_types.h:62
#define FXP_DECLARATION
Definition: quaternion.h:51
dfrac f_mul_df(frac a, frac b)
Multiply single precision, yield double precision.
Definition: fixed_point.h:228
frac f_add(frac a, frac b)
Add two single precision fractional numbers - may overflow.
Definition: fixed_point.h:159
dfrac x
Definition: vector_types.h:71
quat q_add(quat q, quat p)
Quaternion addition (single precision)
Definition: quaternion.h:230
dquat q_mul_dq(quat q, quat p)
Quaternion multiplication, return value is double precision.
Definition: quaternion.h:187
16 bit fractional number in Q1.15 format.
Definition: types.h:86
dquat dq_xrenorm(dquat q)
Renormalize quaternion.
Definition: quaternion.h:283
Single precision quaternion.
vec3 q_error(quat setp, quat pos)
The magnitude of this error reaches its maximum at 90 degrees and goes to zero at 180 degrees.
Definition: quaternion.h:355
dfrac z
Definition: vector_types.h:71
vec_axis
This type is used to indicate the axis.
Definition: vector_types.h:94
dfrac y
Definition: vector_types.h:71
dfrac df_add(dfrac a, dfrac b)
Add two double precision fractional numbers - may overflow.
Definition: fixed_point.h:165
frac f_mul(frac a, frac b)
Multiply single precision, yield single precision.
Definition: fixed_point.h:214
Single precision 3D vector.
Definition: vector_types.h:61
quat q_mul(quat q, quat p)
Quaternion multiplication, return value is simple precision.
Definition: quaternion.h:131
frac x
Definition: vector_types.h:62
quat q_udecompose(quat q, vec_axis axis)
Extract a component from a unit quaternion.
Definition: quaternion.h:302
quat q_xrenorm(quat q)
Renormalize quaternion (single precision)
Definition: quaternion.h:268
vec3 q_rot(quat q, vec3 v)
Rotate 3D vector by quaternion.
Definition: quaternion.h:250