source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/src/math/Vector4.js@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

File size: 8.8 KB
Line 
1/**
2 * @author supereggbert / http://www.paulbrunt.co.uk/
3 * @author philogb / http://blog.thejit.org/
4 * @author mikael emtinger / http://gomo.se/
5 * @author egraether / http://egraether.com/
6 * @author WestLangley / http://github.com/WestLangley
7 */
8
9THREE.Vector4 = function ( x, y, z, w ) {
10
11 this.x = x || 0;
12 this.y = y || 0;
13 this.z = z || 0;
14 this.w = ( w !== undefined ) ? w : 1;
15
16};
17
18THREE.Vector4.prototype = {
19
20 constructor: THREE.Vector4,
21
22 set: function ( x, y, z, w ) {
23
24 this.x = x;
25 this.y = y;
26 this.z = z;
27 this.w = w;
28
29 return this;
30
31 },
32
33 setX: function ( x ) {
34
35 this.x = x;
36
37 return this;
38
39 },
40
41 setY: function ( y ) {
42
43 this.y = y;
44
45 return this;
46
47 },
48
49 setZ: function ( z ) {
50
51 this.z = z;
52
53 return this;
54
55 },
56
57 setW: function ( w ) {
58
59 this.w = w;
60
61 return this;
62
63 },
64
65 setComponent: function ( index, value ) {
66
67 switch ( index ) {
68
69 case 0: this.x = value; break;
70 case 1: this.y = value; break;
71 case 2: this.z = value; break;
72 case 3: this.w = value; break;
73 default: throw new Error( "index is out of range: " + index );
74
75 }
76
77 },
78
79 getComponent: function ( index ) {
80
81 switch ( index ) {
82
83 case 0: return this.x;
84 case 1: return this.y;
85 case 2: return this.z;
86 case 3: return this.w;
87 default: throw new Error( "index is out of range: " + index );
88
89 }
90
91 },
92
93 copy: function ( v ) {
94
95 this.x = v.x;
96 this.y = v.y;
97 this.z = v.z;
98 this.w = ( v.w !== undefined ) ? v.w : 1;
99
100 return this;
101
102 },
103
104 add: function ( v, w ) {
105
106 if ( w !== undefined ) {
107
108 console.warn( 'DEPRECATED: Vector4\'s .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
109 return this.addVectors( v, w );
110
111 }
112
113 this.x += v.x;
114 this.y += v.y;
115 this.z += v.z;
116 this.w += v.w;
117
118 return this;
119
120 },
121
122 addScalar: function ( s ) {
123
124 this.x += s;
125 this.y += s;
126 this.z += s;
127 this.w += s;
128
129 return this;
130
131 },
132
133 addVectors: function ( a, b ) {
134
135 this.x = a.x + b.x;
136 this.y = a.y + b.y;
137 this.z = a.z + b.z;
138 this.w = a.w + b.w;
139
140 return this;
141
142 },
143
144 sub: function ( v, w ) {
145
146 if ( w !== undefined ) {
147
148 console.warn( 'DEPRECATED: Vector4\'s .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
149 return this.subVectors( v, w );
150
151 }
152
153 this.x -= v.x;
154 this.y -= v.y;
155 this.z -= v.z;
156 this.w -= v.w;
157
158 return this;
159
160 },
161
162 subVectors: function ( a, b ) {
163
164 this.x = a.x - b.x;
165 this.y = a.y - b.y;
166 this.z = a.z - b.z;
167 this.w = a.w - b.w;
168
169 return this;
170
171 },
172
173 multiplyScalar: function ( scalar ) {
174
175 this.x *= scalar;
176 this.y *= scalar;
177 this.z *= scalar;
178 this.w *= scalar;
179
180 return this;
181
182 },
183
184 applyMatrix4: function ( m ) {
185
186 var x = this.x;
187 var y = this.y;
188 var z = this.z;
189 var w = this.w;
190
191 var e = m.elements;
192
193 this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w;
194 this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w;
195 this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w;
196 this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w;
197
198 return this;
199
200 },
201
202 divideScalar: function ( scalar ) {
203
204 if ( scalar !== 0 ) {
205
206 var invScalar = 1 / scalar;
207
208 this.x *= invScalar;
209 this.y *= invScalar;
210 this.z *= invScalar;
211 this.w *= invScalar;
212
213 } else {
214
215 this.x = 0;
216 this.y = 0;
217 this.z = 0;
218 this.w = 1;
219
220 }
221
222 return this;
223
224 },
225
226 setAxisAngleFromQuaternion: function ( q ) {
227
228 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
229
230 // q is assumed to be normalized
231
232 this.w = 2 * Math.acos( q.w );
233
234 var s = Math.sqrt( 1 - q.w * q.w );
235
236 if ( s < 0.0001 ) {
237
238 this.x = 1;
239 this.y = 0;
240 this.z = 0;
241
242 } else {
243
244 this.x = q.x / s;
245 this.y = q.y / s;
246 this.z = q.z / s;
247
248 }
249
250 return this;
251
252 },
253
254 setAxisAngleFromRotationMatrix: function ( m ) {
255
256 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
257
258 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
259
260 var angle, x, y, z, // variables for result
261 epsilon = 0.01, // margin to allow for rounding errors
262 epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees
263
264 te = m.elements,
265
266 m11 = te[0], m12 = te[4], m13 = te[8],
267 m21 = te[1], m22 = te[5], m23 = te[9],
268 m31 = te[2], m32 = te[6], m33 = te[10];
269
270 if ( ( Math.abs( m12 - m21 ) < epsilon )
271 && ( Math.abs( m13 - m31 ) < epsilon )
272 && ( Math.abs( m23 - m32 ) < epsilon ) ) {
273
274 // singularity found
275 // first check for identity matrix which must have +1 for all terms
276 // in leading diagonal and zero in other terms
277
278 if ( ( Math.abs( m12 + m21 ) < epsilon2 )
279 && ( Math.abs( m13 + m31 ) < epsilon2 )
280 && ( Math.abs( m23 + m32 ) < epsilon2 )
281 && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
282
283 // this singularity is identity matrix so angle = 0
284
285 this.set( 1, 0, 0, 0 );
286
287 return this; // zero angle, arbitrary axis
288
289 }
290
291 // otherwise this singularity is angle = 180
292
293 angle = Math.PI;
294
295 var xx = ( m11 + 1 ) / 2;
296 var yy = ( m22 + 1 ) / 2;
297 var zz = ( m33 + 1 ) / 2;
298 var xy = ( m12 + m21 ) / 4;
299 var xz = ( m13 + m31 ) / 4;
300 var yz = ( m23 + m32 ) / 4;
301
302 if ( ( xx > yy ) && ( xx > zz ) ) { // m11 is the largest diagonal term
303
304 if ( xx < epsilon ) {
305
306 x = 0;
307 y = 0.707106781;
308 z = 0.707106781;
309
310 } else {
311
312 x = Math.sqrt( xx );
313 y = xy / x;
314 z = xz / x;
315
316 }
317
318 } else if ( yy > zz ) { // m22 is the largest diagonal term
319
320 if ( yy < epsilon ) {
321
322 x = 0.707106781;
323 y = 0;
324 z = 0.707106781;
325
326 } else {
327
328 y = Math.sqrt( yy );
329 x = xy / y;
330 z = yz / y;
331
332 }
333
334 } else { // m33 is the largest diagonal term so base result on this
335
336 if ( zz < epsilon ) {
337
338 x = 0.707106781;
339 y = 0.707106781;
340 z = 0;
341
342 } else {
343
344 z = Math.sqrt( zz );
345 x = xz / z;
346 y = yz / z;
347
348 }
349
350 }
351
352 this.set( x, y, z, angle );
353
354 return this; // return 180 deg rotation
355
356 }
357
358 // as we have reached here there are no singularities so we can handle normally
359
360 var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 )
361 + ( m13 - m31 ) * ( m13 - m31 )
362 + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
363
364 if ( Math.abs( s ) < 0.001 ) s = 1;
365
366 // prevent divide by zero, should not happen if matrix is orthogonal and should be
367 // caught by singularity test above, but I've left it in just in case
368
369 this.x = ( m32 - m23 ) / s;
370 this.y = ( m13 - m31 ) / s;
371 this.z = ( m21 - m12 ) / s;
372 this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
373
374 return this;
375
376 },
377
378 min: function ( v ) {
379
380 if ( this.x > v.x ) {
381
382 this.x = v.x;
383
384 }
385
386 if ( this.y > v.y ) {
387
388 this.y = v.y;
389
390 }
391
392 if ( this.z > v.z ) {
393
394 this.z = v.z;
395
396 }
397
398 if ( this.w > v.w ) {
399
400 this.w = v.w;
401
402 }
403
404 return this;
405
406 },
407
408 max: function ( v ) {
409
410 if ( this.x < v.x ) {
411
412 this.x = v.x;
413
414 }
415
416 if ( this.y < v.y ) {
417
418 this.y = v.y;
419
420 }
421
422 if ( this.z < v.z ) {
423
424 this.z = v.z;
425
426 }
427
428 if ( this.w < v.w ) {
429
430 this.w = v.w;
431
432 }
433
434 return this;
435
436 },
437
438 clamp: function ( min, max ) {
439
440 // This function assumes min < max, if this assumption isn't true it will not operate correctly
441
442 if ( this.x < min.x ) {
443
444 this.x = min.x;
445
446 } else if ( this.x > max.x ) {
447
448 this.x = max.x;
449
450 }
451
452 if ( this.y < min.y ) {
453
454 this.y = min.y;
455
456 } else if ( this.y > max.y ) {
457
458 this.y = max.y;
459
460 }
461
462 if ( this.z < min.z ) {
463
464 this.z = min.z;
465
466 } else if ( this.z > max.z ) {
467
468 this.z = max.z;
469
470 }
471
472 if ( this.w < min.w ) {
473
474 this.w = min.w;
475
476 } else if ( this.w > max.w ) {
477
478 this.w = max.w;
479
480 }
481
482 return this;
483
484 },
485
486 negate: function() {
487
488 return this.multiplyScalar( -1 );
489
490 },
491
492 dot: function ( v ) {
493
494 return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
495
496 },
497
498 lengthSq: function () {
499
500 return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
501
502 },
503
504 length: function () {
505
506 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
507
508 },
509
510 lengthManhattan: function () {
511
512 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
513
514 },
515
516 normalize: function () {
517
518 return this.divideScalar( this.length() );
519
520 },
521
522 setLength: function ( l ) {
523
524 var oldLength = this.length();
525
526 if ( oldLength !== 0 && l !== oldLength ) {
527
528 this.multiplyScalar( l / oldLength );
529
530 }
531
532 return this;
533
534 },
535
536 lerp: function ( v, alpha ) {
537
538 this.x += ( v.x - this.x ) * alpha;
539 this.y += ( v.y - this.y ) * alpha;
540 this.z += ( v.z - this.z ) * alpha;
541 this.w += ( v.w - this.w ) * alpha;
542
543 return this;
544
545 },
546
547 equals: function ( v ) {
548
549 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );
550
551 },
552
553 fromArray: function ( array ) {
554
555 this.x = array[ 0 ];
556 this.y = array[ 1 ];
557 this.z = array[ 2 ];
558 this.w = array[ 3 ];
559
560 return this;
561
562 },
563
564 toArray: function () {
565
566 return [ this.x, this.y, this.z, this.w ];
567
568 },
569
570 clone: function () {
571
572 return new THREE.Vector4( this.x, this.y, this.z, this.w );
573
574 }
575
576};
Note: See TracBrowser for help on using the repository browser.