Vector3.js 13.0 KB
Newer Older
M
Mr.doob 已提交
1
/**
M
Mr.doob 已提交
2
 * @author mrdoob / http://mrdoob.com/
3
 * @author *kile / http://kile.stravaganza.org/
M
Mr.doob 已提交
4
 * @author philogb / http://blog.thejit.org/
5
 * @author mikael emtinger / http://gomo.se/
M
Mr.doob 已提交
6
 * @author egraether / http://egraether.com/
W
WestLangley 已提交
7
 * @author WestLangley / http://github.com/WestLangley
M
Mr.doob 已提交
8 9
 */

A
alteredq 已提交
10
THREE.Vector3 = function ( x, y, z ) {
11

12 13 14
	this.x = x || 0;
	this.y = y || 0;
	this.z = z || 0;
M
Mr.doob 已提交
15

16
};
17

18 19 20
THREE.Vector3.prototype = {

	constructor: THREE.Vector3,
21

22
	set: function ( x, y, z ) {
M
Mr.doob 已提交
23

A
alteredq 已提交
24 25 26
		this.x = x;
		this.y = y;
		this.z = z;
M
Mr.doob 已提交
27

28
		return this;
29

30
	},
31

M
Mr.doob 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
	setX: function ( x ) {

		this.x = x;

		return this;

	},

	setY: function ( y ) {

		this.y = y;

		return this;

	},

	setZ: function ( z ) {

		this.z = z;

		return this;

	},

M
Mr.doob 已提交
56
	setComponent: function ( index, value ) {
B
Ben Houston 已提交
57

M
Mr.doob 已提交
58
		switch ( index ) {
59

M
Mr.doob 已提交
60 61 62
			case 0: this.x = value; break;
			case 1: this.y = value; break;
			case 2: this.z = value; break;
63
			default: throw new Error( 'index is out of range: ' + index );
B
Ben Houston 已提交
64

M
Mr.doob 已提交
65
		}
B
Ben Houston 已提交
66

M
Mr.doob 已提交
67
	},
68

M
Mr.doob 已提交
69
	getComponent: function ( index ) {
70

M
Mr.doob 已提交
71
		switch ( index ) {
72

M
Mr.doob 已提交
73 74 75
			case 0: return this.x;
			case 1: return this.y;
			case 2: return this.z;
76
			default: throw new Error( 'index is out of range: ' + index );
77

M
Mr.doob 已提交
78
		}
79

M
Mr.doob 已提交
80
	},
81

82
	copy: function ( v ) {
M
Mr.doob 已提交
83

M
Mr.doob 已提交
84 85 86
		this.x = v.x;
		this.y = v.y;
		this.z = v.z;
M
Mr.doob 已提交
87

88
		return this;
M
Mr.doob 已提交
89

90
	},
91

92 93 94 95
	add: function ( v, w ) {

		if ( w !== undefined ) {

96
			console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
97 98 99
			return this.addVectors( v, w );

		}
M
Mr.doob 已提交
100

M
Mr.doob 已提交
101 102 103
		this.x += v.x;
		this.y += v.y;
		this.z += v.z;
104

B
Ben Nolan 已提交
105 106
		return this;

107
	},
108

109
	addScalar: function ( s ) {
M
Mr.doob 已提交
110

M
Mr.doob 已提交
111 112 113
		this.x += s;
		this.y += s;
		this.z += s;
114

B
Ben Nolan 已提交
115 116
		return this;

117
	},
118

119
	addVectors: function ( a, b ) {
120

121 122 123
		this.x = a.x + b.x;
		this.y = a.y + b.y;
		this.z = a.z + b.z;
124

125
		return this;
M
Mr.doob 已提交
126

127
	},
128

129 130 131 132
	sub: function ( v, w ) {

		if ( w !== undefined ) {

133
			console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
134 135 136
			return this.subVectors( v, w );

		}
137

M
Mr.doob 已提交
138 139 140
		this.x -= v.x;
		this.y -= v.y;
		this.z -= v.z;
141

B
Ben Nolan 已提交
142 143
		return this;

144
	},
145

146
	subVectors: function ( a, b ) {
147

148 149 150
		this.x = a.x - b.x;
		this.y = a.y - b.y;
		this.z = a.z - b.z;
151

152
		return this;
M
Mr.doob 已提交
153

154
	},
155

156 157 158 159
	multiply: function ( v, w ) {

		if ( w !== undefined ) {

160
			console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
161 162 163
			return this.multiplyVectors( v, w );

		}
164

M
Mr.doob 已提交
165 166
		this.x *= v.x;
		this.y *= v.y;
N
Nico Kruithof 已提交
167
		this.z *= v.z;
M
Mr.doob 已提交
168 169 170 171 172

		return this;

	},

173
	multiplyScalar: function ( scalar ) {
M
Mr.doob 已提交
174

175 176 177
		this.x *= scalar;
		this.y *= scalar;
		this.z *= scalar;
178

B
Ben Nolan 已提交
179 180
		return this;

181
	},
182

183 184 185 186 187 188 189 190 191 192
	multiplyVectors: function ( a, b ) {

		this.x = a.x * b.x;
		this.y = a.y * b.y;
		this.z = a.z * b.z;

		return this;

	},

M
Mr.doob 已提交
193 194 195 196 197 198 199 200
	applyEuler: function () {

		var quaternion;

		return function ( euler ) {

			if ( euler instanceof THREE.Euler === false ) {

201
				console.error( 'THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.' );
M
Mr.doob 已提交
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230

			}

			if ( quaternion === undefined ) quaternion = new THREE.Quaternion();

			this.applyQuaternion( quaternion.setFromEuler( euler ) );

			return this;

		};

	}(),

	applyAxisAngle: function () {

		var quaternion;

		return function ( axis, angle ) {

			if ( quaternion === undefined ) quaternion = new THREE.Quaternion();

			this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );

			return this;

		};

	}(),

231
	applyMatrix3: function ( m ) {
232 233 234 235 236 237 238

		var x = this.x;
		var y = this.y;
		var z = this.z;

		var e = m.elements;

239 240 241
		this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
		this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
		this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
242 243 244 245 246

		return this;

	},

247
	applyMatrix4: function ( m ) {
248

249 250 251
		// input: THREE.Matrix4 affine matrix

		var x = this.x, y = this.y, z = this.z;
252 253 254

		var e = m.elements;

255 256 257
		this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ]  * z + e[ 12 ];
		this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ]  * z + e[ 13 ];
		this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];
258 259 260 261 262

		return this;

	},

263 264 265 266 267 268 269
	applyProjection: function ( m ) {

		// input: THREE.Matrix4 projection matrix

		var x = this.x, y = this.y, z = this.z;

		var e = m.elements;
270
		var d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide
271

272 273 274
		this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ]  * z + e[ 12 ] ) * d;
		this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ]  * z + e[ 13 ] ) * d;
		this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * d;
275 276 277 278 279

		return this;

	},

280
	applyQuaternion: function ( q ) {
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295

		var x = this.x;
		var y = this.y;
		var z = this.z;

		var qx = q.x;
		var qy = q.y;
		var qz = q.z;
		var qw = q.w;

		// calculate quat * vector

		var ix =  qw * x + qy * z - qz * y;
		var iy =  qw * y + qz * x - qx * z;
		var iz =  qw * z + qx * y - qy * x;
296
		var iw = - qx * x - qy * y - qz * z;
297 298 299

		// calculate result * inverse quat

300 301 302
		this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
		this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
		this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
303 304 305 306 307

		return this;

	},

308
	project: function () {
309

310
		var matrix;
311

312
		return function ( camera ) {
313

314
			if ( matrix === undefined ) matrix = new THREE.Matrix4();
315

316 317
			matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
			return this.applyProjection( matrix );
318 319 320 321 322

		};

	}(),

323
	unproject: function () {
324

325
		var matrix;
326

327
		return function ( camera ) {
328

329
			if ( matrix === undefined ) matrix = new THREE.Matrix4();
330

331 332
			matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );
			return this.applyProjection( matrix );
333 334 335 336 337

		};

	}(),

338 339 340 341 342 343 344 345 346
	transformDirection: function ( m ) {

		// input: THREE.Matrix4 affine matrix
		// vector interpreted as a direction

		var x = this.x, y = this.y, z = this.z;

		var e = m.elements;

347 348 349
		this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ]  * z;
		this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ]  * z;
		this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
350 351 352 353 354 355 356

		this.normalize();

		return this;

	},

357
	divide: function ( v ) {
358

359 360 361 362 363
		this.x /= v.x;
		this.y /= v.y;
		this.z /= v.z;

		return this;
M
Mr.doob 已提交
364

M
Mr.doob 已提交
365
	},
366

367
	divideScalar: function ( scalar ) {
368

369
		if ( scalar !== 0 ) {
370

371 372 373 374 375
			var invScalar = 1 / scalar;

			this.x *= invScalar;
			this.y *= invScalar;
			this.z *= invScalar;
M
Mr.doob 已提交
376

M
Mr.doob 已提交
377
		} else {
M
Mr.doob 已提交
378

379 380 381
			this.x = 0;
			this.y = 0;
			this.z = 0;
382

M
Mr.doob 已提交
383
		}
384

B
Ben Nolan 已提交
385 386
		return this;

387
	},
388

389
	min: function ( v ) {
390

A
alteredq 已提交
391 392
		if ( this.x > v.x ) {

393
			this.x = v.x;
A
alteredq 已提交
394

395
		}
A
alteredq 已提交
396 397 398

		if ( this.y > v.y ) {

399
			this.y = v.y;
A
alteredq 已提交
400

401
		}
A
alteredq 已提交
402 403 404

		if ( this.z > v.z ) {

405
			this.z = v.z;
A
alteredq 已提交
406

407
		}
408 409 410 411 412

		return this;

	},

413
	max: function ( v ) {
414

A
alteredq 已提交
415 416
		if ( this.x < v.x ) {

417
			this.x = v.x;
A
alteredq 已提交
418

419
		}
A
alteredq 已提交
420 421 422

		if ( this.y < v.y ) {

423
			this.y = v.y;
A
alteredq 已提交
424

425
		}
A
alteredq 已提交
426 427 428

		if ( this.z < v.z ) {

429
			this.z = v.z;
A
alteredq 已提交
430

431
		}
432 433 434 435

		return this;

	},
M
Mr.doob 已提交
436

437
	clamp: function ( min, max ) {
438 439 440

		// This function assumes min < max, if this assumption isn't true it will not operate correctly

A
alteredq 已提交
441 442
		if ( this.x < min.x ) {

443
			this.x = min.x;
A
alteredq 已提交
444 445 446

		} else if ( this.x > max.x ) {

447
			this.x = max.x;
A
alteredq 已提交
448

449 450
		}

A
alteredq 已提交
451 452
		if ( this.y < min.y ) {

453
			this.y = min.y;
A
alteredq 已提交
454 455 456

		} else if ( this.y > max.y ) {

457
			this.y = max.y;
A
alteredq 已提交
458

459 460
		}

A
alteredq 已提交
461 462
		if ( this.z < min.z ) {

463
			this.z = min.z;
A
alteredq 已提交
464 465 466

		} else if ( this.z > max.z ) {

467
			this.z = max.z;
A
alteredq 已提交
468

469 470 471
		}

		return this;
A
alteredq 已提交
472

473 474
	},

475
	clampScalar: ( function () {
M
Mr.doob 已提交
476

477 478 479
		var min, max;

		return function ( minVal, maxVal ) {
M
Mr.doob 已提交
480 481 482

			if ( min === undefined ) {

483 484
				min = new THREE.Vector3();
				max = new THREE.Vector3();
M
Mr.doob 已提交
485

486 487
			}

M
Mr.doob 已提交
488 489 490 491
			min.set( minVal, minVal, minVal );
			max.set( maxVal, maxVal, maxVal );

			return this.clamp( min, max );
492 493

		};
M
Mr.doob 已提交
494

495 496
	} )(),

M
Mr.doob 已提交
497 498 499 500 501 502
	floor: function () {

		this.x = Math.floor( this.x );
		this.y = Math.floor( this.y );
		this.z = Math.floor( this.z );

503
		return this;
M
Mr.doob 已提交
504

505 506
	},

M
Mr.doob 已提交
507 508 509 510 511 512
	ceil: function () {

		this.x = Math.ceil( this.x );
		this.y = Math.ceil( this.y );
		this.z = Math.ceil( this.z );

513
		return this;
M
Mr.doob 已提交
514

515 516
	},

M
Mr.doob 已提交
517 518 519 520 521 522
	round: function () {

		this.x = Math.round( this.x );
		this.y = Math.round( this.y );
		this.z = Math.round( this.z );

523
		return this;
M
Mr.doob 已提交
524

525 526
	},

M
Mr.doob 已提交
527 528 529 530 531 532
	roundToZero: function () {

		this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
		this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
		this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );

533
		return this;
M
Mr.doob 已提交
534

535
	},
536

537
	negate: function () {
M
Mr.doob 已提交
538

M
Mr.doob 已提交
539 540 541 542 543
		this.x = - this.x;
		this.y = - this.y;
		this.z = - this.z;

		return this;
B
Ben Nolan 已提交
544

545
	},
546

547
	dot: function ( v ) {
M
Mr.doob 已提交
548

M
Mr.doob 已提交
549
		return this.x * v.x + this.y * v.y + this.z * v.z;
M
Mr.doob 已提交
550

M
Mr.doob 已提交
551
	},
M
Mr.doob 已提交
552

553
	lengthSq: function () {
M
Mr.doob 已提交
554

M
Mr.doob 已提交
555
		return this.x * this.x + this.y * this.y + this.z * this.z;
M
Mr.doob 已提交
556 557 558

	},

559
	length: function () {
M
Mr.doob 已提交
560

561
		return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
M
Mr.doob 已提交
562

M
Mr.doob 已提交
563
	},
564

565
	lengthManhattan: function () {
566

567
		return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
A
alteredq 已提交
568

569 570
	},

571
	normalize: function () {
572

M
Mr.doob 已提交
573
		return this.divideScalar( this.length() );
574

575
	},
576

577
	setLength: function ( l ) {
578

579
		var oldLength = this.length();
M
Mr.doob 已提交
580

B
Ben Houston 已提交
581
		if ( oldLength !== 0 && l !== oldLength  ) {
582 583 584 585 586

			this.multiplyScalar( l / oldLength );
		}

		return this;
587

588
	},
589

590
	lerp: function ( v, alpha ) {
591 592 593 594 595 596 597 598

		this.x += ( v.x - this.x ) * alpha;
		this.y += ( v.y - this.y ) * alpha;
		this.z += ( v.z - this.z ) * alpha;

		return this;

	},
599

600 601 602 603
	cross: function ( v, w ) {

		if ( w !== undefined ) {

604
			console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
605 606 607
			return this.crossVectors( v, w );

		}
608

609
		var x = this.x, y = this.y, z = this.z;
610

611 612 613
		this.x = y * v.z - z * v.y;
		this.y = z * v.x - x * v.z;
		this.z = x * v.y - y * v.x;
614

615
		return this;
616 617 618

	},

619 620
	crossVectors: function ( a, b ) {

621 622 623 624 625 626
		var ax = a.x, ay = a.y, az = a.z;
		var bx = b.x, by = b.y, bz = b.z;

		this.x = ay * bz - az * by;
		this.y = az * bx - ax * bz;
		this.z = ax * by - ay * bx;
627 628 629 630 631

		return this;

	},

M
Mr.doob 已提交
632 633
	projectOnVector: function () {

M
Mr.doob 已提交
634
		var v1, dot;
M
Mr.doob 已提交
635 636 637 638 639 640 641

		return function ( vector ) {

			if ( v1 === undefined ) v1 = new THREE.Vector3();

			v1.copy( vector ).normalize();

M
Mr.doob 已提交
642 643 644
			dot = this.dot( v1 );

			return this.copy( v1 ).multiplyScalar( dot );
M
Mr.doob 已提交
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682

		};

	}(),

	projectOnPlane: function () {

		var v1;

		return function ( planeNormal ) {

			if ( v1 === undefined ) v1 = new THREE.Vector3();

			v1.copy( this ).projectOnVector( planeNormal );

			return this.sub( v1 );

		}

	}(),

	reflect: function () {

		// reflect incident vector off plane orthogonal to normal
		// normal is assumed to have unit length

		var v1;

		return function ( normal ) {

			if ( v1 === undefined ) v1 = new THREE.Vector3();

			return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );

		}

	}(),

W
Wilt 已提交
683
	angleTo: function ( v ) {
M
Mr.doob 已提交
684

685 686
		var theta = this.dot( v ) / ( this.length() * v.length() );

687 688
		// clamp, to handle numerical problems

689
		return Math.acos( THREE.Math.clamp( theta, - 1, 1 ) );
M
Mr.doob 已提交
690 691

	},
W
Wilt 已提交
692

693
	distanceTo: function ( v ) {
694

M
Mr.doob 已提交
695
		return Math.sqrt( this.distanceToSquared( v ) );
696

M
Mr.doob 已提交
697 698
	},

699
	distanceToSquared: function ( v ) {
M
Mr.doob 已提交
700

M
Mr.doob 已提交
701 702 703 704
		var dx = this.x - v.x;
		var dy = this.y - v.y;
		var dz = this.z - v.z;

705
		return dx * dx + dy * dy + dz * dz;
M
Mr.doob 已提交
706

707
	},
M
Mr.doob 已提交
708

709 710
	setEulerFromRotationMatrix: function ( m, order ) {

711
		console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );
712 713 714 715 716

	},

	setEulerFromQuaternion: function ( q, order ) {

717
		console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );
M
Mr.doob 已提交
718

719 720
	},

W
WestLangley 已提交
721 722
	getPositionFromMatrix: function ( m ) {

723
		console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );
W
WestLangley 已提交
724

725
		return this.setFromMatrixPosition( m );
W
WestLangley 已提交
726 727 728

	},

M
Mr.doob 已提交
729 730
	getScaleFromMatrix: function ( m ) {

731
		console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );
732 733 734 735 736 737

		return this.setFromMatrixScale( m );
	},

	getColumnFromMatrix: function ( index, matrix ) {

738
		console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758

		return this.setFromMatrixColumn( index, matrix );

	},

	setFromMatrixPosition: function ( m ) {

		this.x = m.elements[ 12 ];
		this.y = m.elements[ 13 ];
		this.z = m.elements[ 14 ];

		return this;

	},

	setFromMatrixScale: function ( m ) {

		var sx = this.set( m.elements[ 0 ], m.elements[ 1 ], m.elements[  2 ] ).length();
		var sy = this.set( m.elements[ 4 ], m.elements[ 5 ], m.elements[  6 ] ).length();
		var sz = this.set( m.elements[ 8 ], m.elements[ 9 ], m.elements[ 10 ] ).length();
M
Mr.doob 已提交
759

760 761 762
		this.x = sx;
		this.y = sy;
		this.z = sz;
M
Mr.doob 已提交
763

764
		return this;
M
Mr.doob 已提交
765 766
	},

767
	setFromMatrixColumn: function ( index, matrix ) {
W
WestLangley 已提交
768

769
		var offset = index * 4;
W
WestLangley 已提交
770

771
		var me = matrix.elements;
W
WestLangley 已提交
772

773 774 775
		this.x = me[ offset ];
		this.y = me[ offset + 1 ];
		this.z = me[ offset + 2 ];
W
WestLangley 已提交
776 777 778 779 780

		return this;

	},

M
Mr.doob 已提交
781
	equals: function ( v ) {
782 783 784

		return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );

785 786
	},

787
	fromArray: function ( array, offset ) {
788

789 790 791 792 793
		if ( offset === undefined ) offset = 0;

		this.x = array[ offset ];
		this.y = array[ offset + 1 ];
		this.z = array[ offset + 2 ];
794

M
Mr.doob 已提交
795 796
		return this;

797 798
	},

799
	toArray: function ( array, offset ) {
800

A
arose 已提交
801 802
		if ( array === undefined ) array = [];
		if ( offset === undefined ) offset = 0;
803

A
arose 已提交
804 805 806
		array[ offset ] = this.x;
		array[ offset + 1 ] = this.y;
		array[ offset + 2 ] = this.z;
807

A
arose 已提交
808
		return array;
809

810 811
	},

M
Mr.doob 已提交
812 813 814 815
	clone: function () {

		return new THREE.Vector3( this.x, this.y, this.z );

816
	}
817

818
};