2 /*
3 * CS5600 University of Utah
4 * Charles McGarvey
5 * mcgarvey@eng.utah.edu
6 */
8 #ifndef _VEC_H_
9 #define _VEC_H_
11 #include "common.h"
14 /*
15 * A simple vector class.
16 */
17 struct vec
18 {
19 scal_t x;
20 scal_t y;
21 scal_t z;
22 scal_t w;
23 };
24 typedef struct vec vec_t;
26 /*
27 * Initialize a vector with four components.
28 */
29 INLINE_MAYBE
30 void vec_init(vec_t* v, scal_t x, scal_t y, scal_t z, scal_t w)
31 {
32 v->x = x;
33 v->y = y;
34 v->z = z;
35 v->w = w;
36 }
39 /*
40 * Create a new vector with four components.
41 */
42 INLINE_MAYBE
43 vec_t vec_new2(scal_t x, scal_t y, scal_t z, scal_t w)
44 {
45 vec_t v;
46 vec_init(&v, x, y, z, w);
47 return v;
48 }
50 /*
51 * Create a new vector with three components. The fourth component is
52 * initialized to one.
53 */
54 INLINE_MAYBE
55 vec_t vec_new(scal_t x, scal_t y, scal_t z)
56 {
57 return vec_new2(x, y, z, S(1.0));
58 }
60 #define VEC_ZERO vec_new(S(0.0), S(0.0), S(0.0))
61 #define VEC_ORTHO_X vec_new(S(1.0), S(0.0), S(0.0))
62 #define VEC_ORTHO_Y vec_new(S(0.0), S(1.0), S(0.0))
63 #define VEC_ORTHO_Z vec_new(S(0.0), S(0.0), S(1.0))
66 /*
67 * Print the vector to stdout.
68 */
69 INLINE_MAYBE
70 void vec_print(vec_t v)
71 {
72 #if (SCALAR_SIZE == 8)
73 const char* fmt = "[ %9.5lf %9.5lf %9.5lf %9.5lf ]";
74 #else
75 const char* fmt = "[ %9.5f %9.5f %9.5f %9.5f ]";
76 #endif
77 printf(fmt, v.x, v.y, v.z, v.w);
78 }
81 /*
82 * Calculate the magnitude of the vector, squared.
83 */
84 INLINE_MAYBE
85 scal_t vec_length2(vec_t v)
86 {
87 return v.x * v.x + v.y * v.y + v.z * v.z;
88 }
90 /*
91 * Calculate the magnitude of the vector.
92 */
93 INLINE_MAYBE
94 scal_t vec_length(vec_t v)
95 {
96 return scal_sqrt(vec_length2(v));
97 }
100 /*
101 * Determine whether or not two vectors are exactly equal.
102 */
103 INLINE_MAYBE
104 bool vec_isequal(vec_t a, vec_t b)
105 {
106 return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
107 }
109 INLINE_MAYBE
110 int vec_compare(vec_t a, vec_t b)
111 {
112 if (vec_isequal(a, b)) {
113 return 0;
114 }
115 return vec_length2(a) < vec_length2(b) ? -1 : 1;
116 }
119 /*
120 * Scale the vector with a scalar value.
121 */
122 INLINE_MAYBE
123 vec_t vec_scale(vec_t v, scal_t s)
124 {
125 v.x *= s;
126 v.y *= s;
127 v.z *= s;
128 return v;
129 }
131 /*
132 * Add two vectors together.
133 */
134 INLINE_MAYBE
135 vec_t vec_add(vec_t a, vec_t b)
136 {
137 a.x += b.x;
138 a.y += b.y;
139 a.z += b.z;
140 return a;
141 }
143 /*
144 * Subtract a vector from another vector.
145 */
146 INLINE_MAYBE
147 vec_t vec_sub(vec_t a, vec_t b)
148 {
149 a.x -= b.x;
150 a.y -= b.y;
151 a.z -= b.z;
152 return a;
153 }
155 /*
156 * Negate the vector.
157 */
158 INLINE_MAYBE
159 vec_t vec_neg(vec_t v)
160 {
161 v.x = -v.x;
162 v.y = -v.y;
163 v.z = -v.z;
164 return v;
165 }
168 /*
169 * Get a normalized (unit length) vector.
170 */
171 INLINE_MAYBE
172 vec_t vec_normalize(vec_t v)
173 {
174 scal_t l = vec_length(v);
175 if (l == S(0.0)) {
176 return VEC_ZERO;
177 }
178 return vec_scale(v, S(1.0) / l);
179 }
182 /*
183 * Get the dot product of two vectors, ignoring the last component.
184 */
185 INLINE_MAYBE
186 scal_t vec_dot(vec_t a, vec_t b)
187 {
188 return a.x * b.x + a.y * b.y + a.z * b.z;
189 }
191 /*
192 * Get the dot product of two vectors.
193 */
194 INLINE_MAYBE
195 scal_t vec_dot2(vec_t a, vec_t b)
196 {
197 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
198 }
201 /*
202 * Get the cross product of two vectors.
203 */
204 INLINE_MAYBE
205 vec_t vec_cross(vec_t a, vec_t b)
206 {
207 return vec_new(a.y * b.z - a.z * b.y,
208 a.z * b.x - a.x * b.z,
209 a.x * b.y - a.y * b.x);
210 }
213 /*
214 * Perform a homogeneous divide.
215 */
216 INLINE_MAYBE
217 vec_t vec_homodiv(vec_t v)
218 {
219 v.x /= v.w;
220 v.y /= v.w;
221 v.z /= v.w;
222 v.w = S(1.0);
223 return v;
224 }
227 #endif // _VEC_H_