2 * Copyright © 2013 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
29 #include "ao_quaternion.h"
33 print_q(char *name, struct ao_quaternion *q)
35 printf ("%8.8s: r%8.5f x%8.5f y%8.5f z%8.5f ", name,
36 q->r, q->x, q->y, q->z);
42 #define DEG (1.0f * 3.1415926535f / 180.0f)
49 static struct ao_rotation ao_path[] = {
50 { .steps = 45, .x = 2*DEG, .y = 0, .z = 0 },
52 { .steps = 45, .x = 0, .y = 2*DEG, .z = 0 },
54 { .steps = 45, .x = -2*DEG, .y = 0, .z = 0 },
56 { .steps = 45, .x = 0, .y = -2*DEG, .z = 0 },
59 #define NUM_PATH (sizeof ao_path / sizeof ao_path[0])
61 static int close(float a, float b) {
62 return fabsf (a - b) < 1e-5;
65 static int check_quaternion(char *where, struct ao_quaternion *got, struct ao_quaternion *expect) {
66 if (!close (got->r, expect->r) ||
67 !close (got->x, expect->x) ||
68 !close (got->y, expect->y) ||
69 !close (got->z, expect->z))
71 printf ("%s: got r%8.5f x%8.5f y%8.5f z%8.5f expect r%8.5f x%8.5f y%8.5f z%8.5f\n",
73 got->r, got->x, got->y, got->z,
74 expect->r, expect->x, expect->y, expect->z);
80 int main(int argc, char **argv)
82 struct ao_quaternion position;
83 struct ao_quaternion position_expect;
84 struct ao_quaternion rotation;
85 struct ao_quaternion rotated;
86 struct ao_quaternion little_rotation;
92 ao_quaternion_init_vector(&position, 1, 1, 1);
93 ao_quaternion_init_vector(&position_expect, -1, -1, 1);
96 ao_quaternion_init_zero_rotation(&rotation);
100 ao_quaternion_rotate(&rotated, &position, &rotation); \
101 print_q("rotated", &rotated); \
102 print_q("rotation", &rotation); \
108 for (p = 0; p < NUM_PATH; p++) {
109 ao_quaternion_init_half_euler(&little_rotation,
112 ao_path[p].z / 2.0f);
113 // printf ("\t\tx: %8.4f, y: %8.4f, z: %8.4f ", ao_path[p].x, ao_path[p].y, ao_path[p].z);
114 // print_q("step", &little_rotation);
116 for (i = 0; i < ao_path[p].steps; i++) {
117 ao_quaternion_multiply(&rotation, &little_rotation, &rotation);
119 ao_quaternion_normalize(&rotation, &rotation);
125 ao_quaternion_rotate(&rotated, &position, &rotation);
127 ret += check_quaternion("rotation", &rotated, &position_expect);
129 struct ao_quaternion vertical;
130 struct ao_quaternion angle;
131 struct ao_quaternion rot;
133 ao_quaternion_init_vector(&vertical, 0, 0, 1);
134 ao_quaternion_init_vector(&angle, 0, 0, 1);
136 ao_quaternion_init_half_euler(&rot,
137 M_PI * 3.0 / 8.0 , 0, 0);
139 ao_quaternion_rotate(&angle, &angle, &rot);
141 struct ao_quaternion rot_compute;
143 ao_quaternion_vectors_to_rotation(&rot_compute, &vertical, &angle);
145 ret += check_quaternion("vector rotation", &rot_compute, &rot);
147 struct ao_quaternion rotd;
149 ao_quaternion_rotate(&rotd, &vertical, &rot_compute);
151 ret += check_quaternion("vector rotated", &rotd, &angle);