Vector3.js 12.3 KB
Newer Older
R
Rich Harris 已提交
1 2 3 4
import { _Math } from './Math';
import { Matrix4 } from './Matrix4';
import { Quaternion } from './Quaternion';

M
Mr.doob 已提交
5
/**
M
Mr.doob 已提交
6
 * @author mrdoob / http://mrdoob.com/
7
 * @author *kile / http://kile.stravaganza.org/
M
Mr.doob 已提交
8
 * @author philogb / http://blog.thejit.org/
9
 * @author mikael emtinger / http://gomo.se/
M
Mr.doob 已提交
10
 * @author egraether / http://egraether.com/
W
WestLangley 已提交
11
 * @author WestLangley / http://github.com/WestLangley
M
Mr.doob 已提交
12 13
 */

M
Mr.doob 已提交
14
function Vector3( x, y, z ) {
15

16 17 18
	this.x = x || 0;
	this.y = y || 0;
	this.z = z || 0;
M
Mr.doob 已提交
19

M
Mr.doob 已提交
20
}
21

22
Object.assign( Vector3.prototype, {
23

24 25
	isVector3: true,

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

A
alteredq 已提交
28 29 30
		this.x = x;
		this.y = y;
		this.z = z;
M
Mr.doob 已提交
31

32
		return this;
33

34
	},
35

M
Mr.doob 已提交
36 37 38 39 40 41 42 43 44 45
	setScalar: function ( scalar ) {

		this.x = scalar;
		this.y = scalar;
		this.z = scalar;

		return this;

	},

M
Mr.doob 已提交
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
	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 已提交
70
	setComponent: function ( index, value ) {
B
Ben Houston 已提交
71

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

M
Mr.doob 已提交
74 75 76
			case 0: this.x = value; break;
			case 1: this.y = value; break;
			case 2: this.z = value; break;
77
			default: throw new Error( 'index is out of range: ' + index );
B
Ben Houston 已提交
78

M
Mr.doob 已提交
79
		}
M
Mugen87 已提交
80

M
matthias-w 已提交
81
		return this;
B
Ben Houston 已提交
82

M
Mr.doob 已提交
83
	},
84

M
Mr.doob 已提交
85
	getComponent: function ( index ) {
86

M
Mr.doob 已提交
87
		switch ( index ) {
88

M
Mr.doob 已提交
89 90 91
			case 0: return this.x;
			case 1: return this.y;
			case 2: return this.z;
92
			default: throw new Error( 'index is out of range: ' + index );
93

M
Mr.doob 已提交
94
		}
95

M
Mr.doob 已提交
96
	},
97

98 99 100 101 102 103
	clone: function () {

		return new this.constructor( this.x, this.y, this.z );

	},

104
	copy: function ( v ) {
M
Mr.doob 已提交
105

M
Mr.doob 已提交
106 107 108
		this.x = v.x;
		this.y = v.y;
		this.z = v.z;
M
Mr.doob 已提交
109

110
		return this;
M
Mr.doob 已提交
111

112
	},
113

114 115 116 117
	add: function ( v, w ) {

		if ( w !== undefined ) {

118
			console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
119 120 121
			return this.addVectors( v, w );

		}
M
Mr.doob 已提交
122

M
Mr.doob 已提交
123 124 125
		this.x += v.x;
		this.y += v.y;
		this.z += v.z;
126

B
Ben Nolan 已提交
127 128
		return this;

129
	},
130

131
	addScalar: function ( s ) {
M
Mr.doob 已提交
132

M
Mr.doob 已提交
133 134 135
		this.x += s;
		this.y += s;
		this.z += s;
136

B
Ben Nolan 已提交
137 138
		return this;

139
	},
140

141
	addVectors: function ( a, b ) {
142

143 144 145
		this.x = a.x + b.x;
		this.y = a.y + b.y;
		this.z = a.z + b.z;
146

147
		return this;
M
Mr.doob 已提交
148

149
	},
150

G
gero3 已提交
151 152
	addScaledVector: function ( v, s ) {

G
gero3 已提交
153 154 155
		this.x += v.x * s;
		this.y += v.y * s;
		this.z += v.z * s;
G
gero3 已提交
156

G
gero3 已提交
157
		return this;
G
gero3 已提交
158

G
gero3 已提交
159
	},
160

161 162 163 164
	sub: function ( v, w ) {

		if ( w !== undefined ) {

165
			console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
166 167 168
			return this.subVectors( v, w );

		}
169

M
Mr.doob 已提交
170 171 172
		this.x -= v.x;
		this.y -= v.y;
		this.z -= v.z;
173

B
Ben Nolan 已提交
174 175
		return this;

176
	},
177

C
Corey Birnbaum 已提交
178 179 180 181 182 183 184 185 186
	subScalar: function ( s ) {

		this.x -= s;
		this.y -= s;
		this.z -= s;

		return this;

	},
187

188
	subVectors: function ( a, b ) {
189

190 191 192
		this.x = a.x - b.x;
		this.y = a.y - b.y;
		this.z = a.z - b.z;
193

194
		return this;
M
Mr.doob 已提交
195

196
	},
197

198 199 200 201
	multiply: function ( v, w ) {

		if ( w !== undefined ) {

202
			console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
203 204 205
			return this.multiplyVectors( v, w );

		}
206

M
Mr.doob 已提交
207 208
		this.x *= v.x;
		this.y *= v.y;
N
Nico Kruithof 已提交
209
		this.z *= v.z;
M
Mr.doob 已提交
210 211 212 213 214

		return this;

	},

215
	multiplyScalar: function ( scalar ) {
M
Mr.doob 已提交
216

M
Mr.doob 已提交
217
		if ( isFinite( scalar ) ) {
M
Mr.doob 已提交
218

M
Mr.doob 已提交
219 220 221
			this.x *= scalar;
			this.y *= scalar;
			this.z *= scalar;
M
Mr.doob 已提交
222

M
Mr.doob 已提交
223
		} else {
M
Mr.doob 已提交
224

M
Mr.doob 已提交
225 226 227
			this.x = 0;
			this.y = 0;
			this.z = 0;
M
Mr.doob 已提交
228

M
Mr.doob 已提交
229
		}
230

B
Ben Nolan 已提交
231 232
		return this;

233
	},
234

235 236 237 238 239 240 241 242 243 244
	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 已提交
245 246
	applyEuler: function () {

247
		var quaternion = new Quaternion();
M
Mr.doob 已提交
248

249
		return function applyEuler( euler ) {
M
Mr.doob 已提交
250

R
Rich Harris 已提交
251
			if ( (euler && euler.isEuler) === false ) {
M
Mr.doob 已提交
252

P
paulmasson 已提交
253
				console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
M
Mr.doob 已提交
254 255 256

			}

257
			return this.applyQuaternion( quaternion.setFromEuler( euler ) );
M
Mr.doob 已提交
258 259 260 261 262 263 264

		};

	}(),

	applyAxisAngle: function () {

265
		var quaternion = new Quaternion();
M
Mr.doob 已提交
266

267
		return function applyAxisAngle( axis, angle ) {
M
Mr.doob 已提交
268

269
			return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );
M
Mr.doob 已提交
270 271 272 273 274

		};

	}(),

275
	applyMatrix3: function ( m ) {
276

277
		var x = this.x, y = this.y, z = this.z;
278 279
		var e = m.elements;

280 281 282
		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;
283 284 285 286 287

		return this;

	},

288
	applyMatrix4: function ( m ) {
289

290
		var x = this.x, y = this.y, z = this.z;
291 292
		var e = m.elements;

293 294 295
		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 ];
F
Franklin Ta 已提交
296
		var w =  e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];
297

F
Franklin Ta 已提交
298
		return this.divideScalar( w );
299 300 301

	},

302
	applyQuaternion: function ( q ) {
303

304 305
		var x = this.x, y = this.y, z = this.z;
		var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
306 307 308 309 310 311

		// 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;
312
		var iw = - qx * x - qy * y - qz * z;
313 314 315

		// calculate result * inverse quat

316 317 318
		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;
319 320 321 322 323

		return this;

	},

324
	project: function () {
325

326
		var matrix = new Matrix4();
327

328
		return function project( camera ) {
329

330
			matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
F
Franklin Ta 已提交
331
			return this.applyMatrix4( matrix );
332 333 334 335 336

		};

	}(),

337
	unproject: function () {
338

339
		var matrix = new Matrix4();
340

341
		return function unproject( camera ) {
342

343
			matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );
F
Franklin Ta 已提交
344
			return this.applyMatrix4( matrix );
345 346 347 348 349

		};

	}(),

350 351 352 353 354 355 356 357
	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;

358 359 360
		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;
361

362
		return this.normalize();
363 364 365

	},

366
	divide: function ( v ) {
367

368 369 370 371 372
		this.x /= v.x;
		this.y /= v.y;
		this.z /= v.z;

		return this;
M
Mr.doob 已提交
373

M
Mr.doob 已提交
374
	},
375

376
	divideScalar: function ( scalar ) {
377

M
Mr.doob 已提交
378
		return this.multiplyScalar( 1 / scalar );
B
Ben Nolan 已提交
379

380
	},
381

382
	min: function ( v ) {
383

M
Mr.doob 已提交
384 385 386
		this.x = Math.min( this.x, v.x );
		this.y = Math.min( this.y, v.y );
		this.z = Math.min( this.z, v.z );
387 388 389 390 391

		return this;

	},

392
	max: function ( v ) {
393

M
Mr.doob 已提交
394 395 396
		this.x = Math.max( this.x, v.x );
		this.y = Math.max( this.y, v.y );
		this.z = Math.max( this.z, v.z );
397 398 399 400

		return this;

	},
M
Mr.doob 已提交
401

402
	clamp: function ( min, max ) {
403 404 405

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

M
Mr.doob 已提交
406 407 408
		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
		this.z = Math.max( min.z, Math.min( max.z, this.z ) );
409 410

		return this;
A
alteredq 已提交
411

412 413
	},

414
	clampScalar: function () {
M
Mr.doob 已提交
415

416 417
		var min = new Vector3();
		var max = new Vector3();
418

419
		return function clampScalar( minVal, maxVal ) {
M
Mr.doob 已提交
420 421 422 423 424

			min.set( minVal, minVal, minVal );
			max.set( maxVal, maxVal, maxVal );

			return this.clamp( min, max );
425 426

		};
M
Mr.doob 已提交
427

428
	}(),
429

M
Mugen87 已提交
430
	clampLength: function ( min, max ) {
431

M
Mugen87 已提交
432
		var length = this.length();
433

434
		return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
435

M
Mugen87 已提交
436
	},
437

M
Mr.doob 已提交
438 439 440 441 442 443
	floor: function () {

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

444
		return this;
M
Mr.doob 已提交
445

446 447
	},

M
Mr.doob 已提交
448 449 450 451 452 453
	ceil: function () {

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

454
		return this;
M
Mr.doob 已提交
455

456 457
	},

M
Mr.doob 已提交
458 459 460 461 462 463
	round: function () {

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

464
		return this;
M
Mr.doob 已提交
465

466 467
	},

M
Mr.doob 已提交
468 469 470 471 472 473
	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 );

474
		return this;
M
Mr.doob 已提交
475

476
	},
477

478
	negate: function () {
M
Mr.doob 已提交
479

M
Mr.doob 已提交
480 481 482 483 484
		this.x = - this.x;
		this.y = - this.y;
		this.z = - this.z;

		return this;
B
Ben Nolan 已提交
485

486
	},
487

488
	dot: function ( v ) {
M
Mr.doob 已提交
489

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

M
Mr.doob 已提交
492
	},
M
Mr.doob 已提交
493

494
	lengthSq: function () {
M
Mr.doob 已提交
495

M
Mr.doob 已提交
496
		return this.x * this.x + this.y * this.y + this.z * this.z;
M
Mr.doob 已提交
497 498 499

	},

500
	length: function () {
M
Mr.doob 已提交
501

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

M
Mr.doob 已提交
504
	},
505

506
	lengthManhattan: function () {
507

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

510 511
	},

512
	normalize: function () {
513

M
Mr.doob 已提交
514
		return this.divideScalar( this.length() );
515

516
	},
517

518
	setLength: function ( length ) {
519

M
Mr.doob 已提交
520
		return this.multiplyScalar( length / this.length() );
521

522
	},
523

524
	lerp: function ( v, alpha ) {
525 526 527 528 529 530 531 532

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

		return this;

	},
533

W
WestLangley 已提交
534 535
	lerpVectors: function ( v1, v2, alpha ) {

536
		return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
W
WestLangley 已提交
537 538 539

	},

540 541 542 543
	cross: function ( v, w ) {

		if ( w !== undefined ) {

544
			console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
545 546 547
			return this.crossVectors( v, w );

		}
548

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

551 552 553
		this.x = y * v.z - z * v.y;
		this.y = z * v.x - x * v.z;
		this.z = x * v.y - y * v.x;
554

555
		return this;
556 557 558

	},

559 560
	crossVectors: function ( a, b ) {

561 562 563 564 565 566
		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;
567 568 569 570 571

		return this;

	},

572
	projectOnVector: function ( vector ) {
M
Mr.doob 已提交
573

574
		var scalar = vector.dot( this ) / vector.lengthSq();
575

576
		return this.copy( vector ).multiplyScalar( scalar );
577

578
	},
M
Mr.doob 已提交
579 580 581

	projectOnPlane: function () {

582
		var v1 = new Vector3();
M
Mr.doob 已提交
583

584
		return function projectOnPlane( planeNormal ) {
M
Mr.doob 已提交
585 586 587 588 589

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

			return this.sub( v1 );

M
Mr.doob 已提交
590
		};
M
Mr.doob 已提交
591 592 593 594 595 596 597 598

	}(),

	reflect: function () {

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

599
		var v1 = new Vector3();
M
Mr.doob 已提交
600

601
		return function reflect( normal ) {
M
Mr.doob 已提交
602 603 604

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

M
Mr.doob 已提交
605
		};
M
Mr.doob 已提交
606 607 608

	}(),

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

611
		var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );
612

613 614
		// clamp, to handle numerical problems

R
Rich Harris 已提交
615
		return Math.acos( _Math.clamp( theta, - 1, 1 ) );
M
Mr.doob 已提交
616 617

	},
W
Wilt 已提交
618

619
	distanceTo: function ( v ) {
620

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

M
Mr.doob 已提交
623 624
	},

625
	distanceToSquared: function ( v ) {
M
Mr.doob 已提交
626

627
		var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
M
Mr.doob 已提交
628

629
		return dx * dx + dy * dy + dz * dz;
M
Mr.doob 已提交
630

631
	},
M
Mr.doob 已提交
632

W
WestLangley 已提交
633 634 635 636 637 638
	distanceToManhattan: function ( v ) {

		return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );

	},

B
Ben Houston 已提交
639 640 641
	setFromSpherical: function( s ) {

		var sinPhiRadius = Math.sin( s.phi ) * s.radius;
M
Mr.doob 已提交
642

B
Ben Houston 已提交
643 644 645 646 647 648 649 650
		this.x = sinPhiRadius * Math.sin( s.theta );
		this.y = Math.cos( s.phi ) * s.radius;
		this.z = sinPhiRadius * Math.cos( s.theta );

		return this;

	},

M
Mugen87 已提交
651 652 653 654 655 656 657 658 659 660
	setFromCylindrical: function( c ) {

		this.x = c.radius * Math.sin( c.theta );
		this.y = c.y;
		this.z = c.radius * Math.cos( c.theta );

		return this;

	},

661 662
	setFromMatrixPosition: function ( m ) {

M
Mr.doob 已提交
663
		return this.setFromMatrixColumn( m, 3 );
664 665 666 667 668

	},

	setFromMatrixScale: function ( m ) {

669 670 671 672 673 674 675
		var sx = this.setFromMatrixColumn( m, 0 ).length();
		var sy = this.setFromMatrixColumn( m, 1 ).length();
		var sz = this.setFromMatrixColumn( m, 2 ).length();

		this.x = sx;
		this.y = sy;
		this.z = sz;
M
Mr.doob 已提交
676

677
		return this;
G
gero3 已提交
678

M
Mr.doob 已提交
679 680
	},

681
	setFromMatrixColumn: function ( m, index ) {
682

683 684 685
		if ( typeof m === 'number' ) {

			console.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );
T
Tristan Valcke 已提交
686
			var temp = m;
687 688
			m = index;
			index = temp;
689 690 691

		}

M
Mr.doob 已提交
692
		return this.fromArray( m.elements, index * 4 );
W
WestLangley 已提交
693 694 695

	},

M
Mr.doob 已提交
696
	equals: function ( v ) {
697 698 699

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

700 701
	},

702
	fromArray: function ( array, offset ) {
703

704 705 706 707 708
		if ( offset === undefined ) offset = 0;

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

M
Mr.doob 已提交
710 711
		return this;

712 713
	},

714
	toArray: function ( array, offset ) {
715

A
arose 已提交
716 717
		if ( array === undefined ) array = [];
		if ( offset === undefined ) offset = 0;
718

A
arose 已提交
719 720 721
		array[ offset ] = this.x;
		array[ offset + 1 ] = this.y;
		array[ offset + 2 ] = this.z;
722

A
arose 已提交
723
		return array;
724

725 726
	},

727
	fromBufferAttribute: function ( attribute, index, offset ) {
W
WestLangley 已提交
728

729 730
		if ( offset !== undefined ) {

731
			console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
W
WestLangley 已提交
732

733
		}
W
WestLangley 已提交
734

735 736 737
		this.x = attribute.getX( index );
		this.y = attribute.getY( index );
		this.z = attribute.getZ( index );
W
WestLangley 已提交
738

G
gero3 已提交
739
		return this;
W
WestLangley 已提交
740

741
	}
742

743
} );
R
Rich Harris 已提交
744 745


746
export { Vector3 };