]> Dogcows Code - chaz/rasterize/blob - vec.h
614e31dfec4c0e68bdbcb5b08ae0be7399ef4ef7
[chaz/rasterize] / vec.h
1
2 /*
3 * CS5600 University of Utah
4 * Charles McGarvey
5 * mcgarvey@eng.utah.edu
6 */
7
8 #ifndef _VEC_H_
9 #define _VEC_H_
10
11 #include "common.h"
12
13
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;
25
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 }
37
38
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 }
49
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 }
59
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))
64
65
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 }
79
80
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 }
89
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 }
98
99
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 }
108
109 /*
110 * Determine whether or not two vectors are mostly equal.
111 */
112 INLINE_MAYBE
113 bool vec_isequal2(vec_t a, vec_t b, scal_t epsilon)
114 {
115 return scal_isequal2(a.x, b.x, epsilon) &&
116 scal_isequal2(a.y, b.y, epsilon) &&
117 scal_isequal2(a.z, b.z, epsilon) &&
118 scal_isequal2(a.w, b.w, epsilon);
119 }
120
121 /*
122 * Determine if one vector is "less than" another, for purposes of sorting.
123 */
124 INLINE_MAYBE
125 int vec_compare(vec_t a, vec_t b)
126 {
127 if (vec_isequal(a, b)) {
128 return 0;
129 }
130 return vec_length2(a) < vec_length2(b) ? -1 : 1;
131 }
132
133
134 /*
135 * Scale the vector with a scalar value.
136 */
137 INLINE_MAYBE
138 vec_t vec_scale(vec_t v, scal_t s)
139 {
140 v.x *= s;
141 v.y *= s;
142 v.z *= s;
143 return v;
144 }
145
146 /*
147 * Add two vectors together.
148 */
149 INLINE_MAYBE
150 vec_t vec_add(vec_t a, vec_t b)
151 {
152 a.x += b.x;
153 a.y += b.y;
154 a.z += b.z;
155 return a;
156 }
157
158 /*
159 * Subtract a vector from another vector.
160 */
161 INLINE_MAYBE
162 vec_t vec_sub(vec_t a, vec_t b)
163 {
164 a.x -= b.x;
165 a.y -= b.y;
166 a.z -= b.z;
167 return a;
168 }
169
170 /*
171 * Negate the vector.
172 */
173 INLINE_MAYBE
174 vec_t vec_neg(vec_t v)
175 {
176 v.x = -v.x;
177 v.y = -v.y;
178 v.z = -v.z;
179 return v;
180 }
181
182
183 /*
184 * Get a normalized (unit length) vector.
185 */
186 INLINE_MAYBE
187 vec_t vec_normalize(vec_t v)
188 {
189 scal_t l = vec_length(v);
190 if (l == S(0.0)) {
191 return VEC_ZERO;
192 }
193 return vec_scale(v, S(1.0) / l);
194 }
195
196
197 /*
198 * Get the dot product of two vectors, ignoring the last component.
199 */
200 INLINE_MAYBE
201 scal_t vec_dot(vec_t a, vec_t b)
202 {
203 return a.x * b.x + a.y * b.y + a.z * b.z;
204 }
205
206 /*
207 * Get the dot product of two vectors.
208 */
209 INLINE_MAYBE
210 scal_t vec_dot2(vec_t a, vec_t b)
211 {
212 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
213 }
214
215
216 /*
217 * Get the cross product of two vectors.
218 */
219 INLINE_MAYBE
220 vec_t vec_cross(vec_t a, vec_t b)
221 {
222 return vec_new(a.y * b.z - a.z * b.y,
223 a.z * b.x - a.x * b.z,
224 a.x * b.y - a.y * b.x);
225 }
226
227
228 /*
229 * Perform a homogeneous divide.
230 */
231 INLINE_MAYBE
232 vec_t vec_homodiv(vec_t v)
233 {
234 v.x /= v.w;
235 v.y /= v.w;
236 v.z /= v.w;
237 v.w = S(1.0);
238 return v;
239 }
240
241
242 #endif // _VEC_H_
243
This page took 0.037964 seconds and 3 git commands to generate.