Changeset 2112 in orxonox.OLD for orxonox/branches/chris/src/vector.cc
- Timestamp:
- Jul 12, 2004, 10:28:25 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
orxonox/branches/chris/src/vector.cc
r2101 r2112 14 14 main-programmer: Christian Meyer 15 15 co-programmer: ... 16 17 Quaternion code borrowed from an Gamasutra article by Nick Bobick and Ken Shoemake 16 18 */ 17 19 … … 177 179 f = acos( v1 * v2 / (v1.len() * v2.len())); 178 180 return f * 180 / PI; 181 } 182 183 Quaternion::Quaternion () 184 { 185 w = 1; 186 v = Vector(0,0,0); 187 } 188 189 Quaternion::Quaternion (float angle, const Vector& axis) 190 { 191 w = cos(angle/2); 192 v = axis * sin(angle/2); 193 } 194 195 Quaternion::Quaternion (const Vector& dir, const Vector& up) 196 { 197 Vector z = dir; 198 z.normalize(); 199 Vector x = up.cross(z); 200 x.normalize(); 201 Vector y = z.cross(x); 202 203 float m[4][4]; 204 m[0][0] = x.x; 205 m[0][1] = x.y; 206 m[0][2] = x.z; 207 m[0][3] = 0; 208 m[1][0] = y.x; 209 m[1][1] = y.y; 210 m[1][2] = y.z; 211 m[1][3] = 0; 212 m[2][0] = z.x; 213 m[2][1] = z.y; 214 m[2][2] = z.z; 215 m[2][3] = 0; 216 m[3][0] = 0; 217 m[3][1] = 0; 218 m[3][2] = 0; 219 m[3][3] = 1; 220 221 *this = Quaternion (m); 222 } 223 224 Quaternion::Quaternion (float roll, float pitch, float yaw) 225 { 226 float cr, cp, cy, sr, sp, sy, cpcy, spsy; 227 228 // calculate trig identities 229 cr = cos(roll/2); 230 cp = cos(pitch/2); 231 cy = cos(yaw/2); 232 233 sr = sin(roll/2); 234 sp = sin(pitch/2); 235 sy = sin(yaw/2); 236 237 cpcy = cp * cy; 238 spsy = sp * sy; 239 240 w = cr * cpcy + sr * spsy; 241 v.x = sr * cpcy - cr * spsy; 242 v.y = cr * sp * cy + sr * cp * sy; 243 v.z = cr * cp * sy - sr * sp * cy; 244 } 245 246 Quaternion Quaternion::operator*(const Quaternion& q) const 247 { 248 float A, B, C, D, E, F, G, H; 249 Quaternion r; 250 251 A = (w + v.x)*(q.w + q.v.x); 252 B = (v.z - v.y)*(q.v.y - q.v.z); 253 C = (w - v.x)*(q.v.y + q.v.z); 254 D = (v.y + v.z)*(q.w - q.v.x); 255 E = (v.x + v.z)*(q.v.x + q.v.y); 256 F = (v.x - v.z)*(q.v.x - q.v.y); 257 G = (w + v.y)*(q.w - q.v.z); 258 H = (w - v.y)*(q.w + q.v.z); 259 260 r.w = B + (-E - F + G + H)/2; 261 r.v.x = A - (E + F + G + H)/2; 262 r.v.y = C + (E - F + G - H)/2; 263 r.v.z = D + (E - F - G + H)/2; 264 265 return r; 266 } 267 268 Quaternion Quaternion::operator+(const Quaternion& q) const 269 { 270 Quaternion r(*this); 271 r.w = r.w + q.w; 272 r.v = r.v + q.v; 273 return r; 274 } 275 276 Quaternion Quaternion::operator- (const Quaternion& q) const 277 { 278 Quaternion r(*this); 279 r.w = r.w - q.w; 280 r.v = r.v - q.v; 281 return r; 282 } 283 284 Vector Quaternion::apply (Vector& v) const 285 { 286 Quaternion q; 287 q.v = v; 288 q.w = 0; 289 q = *this * q * conjugate(); 290 return q.v; 291 } 292 293 Quaternion Quaternion::operator*(const float& f) const 294 { 295 Quaternion r(*this); 296 r.w = r.w*f; 297 r.v = r.v*f; 298 return r; 299 } 300 301 Quaternion Quaternion::operator/(const float& f) const 302 { 303 if( f == 0) return Quaternion(); 304 Quaternion r(*this); 305 r.w = r.w/f; 306 r.v = r.v/f; 307 return r; 308 } 309 310 Quaternion Quaternion::conjugate() const 311 { 312 Quaternion r(*this); 313 r.v = Vector() - r.v; 314 return r; 315 } 316 317 float Quaternion::norm() const 318 { 319 return w*w + v.x*v.x + v.y*v.y + v.z*v.z; 320 } 321 322 Quaternion Quaternion::inverse() const 323 { 324 float n = norm(); 325 if (n != 0) 326 { 327 return conjugate() / norm(); 328 } 329 else return Quaternion(); 330 } 331 332 void Quaternion::matrix (float m[4][4]) const 333 { 334 float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; 335 336 // calculate coefficients 337 x2 = v.x + v.x; 338 y2 = v.y + v.y; 339 z2 = v.z + v.z; 340 xx = v.x * x2; xy = v.x * y2; xz = v.x * z2; 341 yy = v.y * y2; yz = v.y * z2; zz = v.z * z2; 342 wx = w * x2; wy = w * y2; wz = w * z2; 343 344 m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz; 345 m[2][0] = xz + wy; m[3][0] = 0.0; 346 347 m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz); 348 m[2][1] = yz - wx; m[3][1] = 0.0; 349 350 m[0][2] = xz - wy; m[1][2] = yz + wx; 351 m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0; 352 353 m[0][3] = 0; m[1][3] = 0; 354 m[2][3] = 0; m[3][3] = 1; 355 } 356 357 Quaternion::Quaternion (float m[4][4]) 358 { 359 360 float tr, s, q[4]; 361 int i, j, k; 362 363 int nxt[3] = {1, 2, 0}; 364 365 tr = m[0][0] + m[1][1] + m[2][2]; 366 367 // check the diagonal 368 if (tr > 0.0) 369 { 370 s = sqrt (tr + 1.0); 371 w = s / 2.0; 372 s = 0.5 / s; 373 v.x = (m[1][2] - m[2][1]) * s; 374 v.y = (m[2][0] - m[0][2]) * s; 375 v.z = (m[0][1] - m[1][0]) * s; 376 } 377 else 378 { 379 // diagonal is negative 380 i = 0; 381 if (m[1][1] > m[0][0]) i = 1; 382 if (m[2][2] > m[i][i]) i = 2; 383 j = nxt[i]; 384 k = nxt[j]; 385 386 s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0); 387 388 q[i] = s * 0.5; 389 390 if (s != 0.0) s = 0.5 / s; 391 392 q[3] = (m[j][k] - m[k][j]) * s; 393 q[j] = (m[i][j] + m[j][i]) * s; 394 q[k] = (m[i][k] + m[k][i]) * s; 395 396 v.x = q[0]; 397 v.y = q[1]; 398 v.z = q[2]; 399 w = q[3]; 400 } 179 401 } 180 402
Note: See TracChangeset
for help on using the changeset viewer.