Vector3.js 8.9 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
THREE.Vector3.prototype = {
20

21 22 23
	constructor: THREE.Vector3,

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

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

29
		return this;
30

31
	},
32

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

		this.x = x;

		return this;

	},

	setY: function ( y ) {

		this.y = y;

		return this;

	},

	setZ: function ( z ) {

		this.z = z;

		return this;

	},

57
	copy: function ( v ) {
M
Mr.doob 已提交
58

M
Mr.doob 已提交
59 60 61
		this.x = v.x;
		this.y = v.y;
		this.z = v.z;
M
Mr.doob 已提交
62

63
		return this;
M
Mr.doob 已提交
64

65
	},
66

M
Mr.doob 已提交
67
	add: function ( a, b ) {
M
Mr.doob 已提交
68

M
Mr.doob 已提交
69 70 71
		this.x = a.x + b.x;
		this.y = a.y + b.y;
		this.z = a.z + b.z;
M
Mr.doob 已提交
72

73
		return this;
74

75
	},
76

77
	addSelf: function ( v ) {
M
Mr.doob 已提交
78

M
Mr.doob 已提交
79 80 81
		this.x += v.x;
		this.y += v.y;
		this.z += v.z;
82

B
Ben Nolan 已提交
83 84
		return this;

85
	},
86

87
	addScalar: function ( s ) {
M
Mr.doob 已提交
88

M
Mr.doob 已提交
89 90 91
		this.x += s;
		this.y += s;
		this.z += s;
92

B
Ben Nolan 已提交
93 94
		return this;

95
	},
96

M
Mr.doob 已提交
97
	sub: function ( a, b ) {
98

M
Mr.doob 已提交
99 100 101
		this.x = a.x - b.x;
		this.y = a.y - b.y;
		this.z = a.z - b.z;
102

103
		return this;
M
Mr.doob 已提交
104

105
	},
106

107
	subSelf: function ( v ) {
M
Mr.doob 已提交
108

M
Mr.doob 已提交
109 110 111
		this.x -= v.x;
		this.y -= v.y;
		this.z -= v.z;
112

B
Ben Nolan 已提交
113 114
		return this;

115
	},
116

117
	multiply: function ( a, b ) {
118

M
Mr.doob 已提交
119 120 121
		this.x = a.x * b.x;
		this.y = a.y * b.y;
		this.z = a.z * b.z;
122

123
		return this;
M
Mr.doob 已提交
124

125
	},
126

127
	multiplySelf: function ( v ) {
M
Mr.doob 已提交
128

M
Mr.doob 已提交
129 130
		this.x *= v.x;
		this.y *= v.y;
N
Nico Kruithof 已提交
131
		this.z *= v.z;
M
Mr.doob 已提交
132 133 134 135 136

		return this;

	},

137
	multiplyScalar: function ( s ) {
M
Mr.doob 已提交
138

M
Mr.doob 已提交
139 140 141
		this.x *= s;
		this.y *= s;
		this.z *= s;
142

B
Ben Nolan 已提交
143 144
		return this;

145
	},
146

147
	divideSelf: function ( v ) {
148

149 150 151 152 153
		this.x /= v.x;
		this.y /= v.y;
		this.z /= v.z;

		return this;
M
Mr.doob 已提交
154

M
Mr.doob 已提交
155
	},
156

157
	divideScalar: function ( s ) {
158

M
Mr.doob 已提交
159
		if ( s ) {
160

M
Mr.doob 已提交
161 162 163
			this.x /= s;
			this.y /= s;
			this.z /= s;
M
Mr.doob 已提交
164

M
Mr.doob 已提交
165
		} else {
M
Mr.doob 已提交
166

167 168 169
			this.x = 0;
			this.y = 0;
			this.z = 0;
170

M
Mr.doob 已提交
171
		}
172

B
Ben Nolan 已提交
173 174
		return this;

175
	},
176

177 178
	minSelf: function ( v ) {

A
alteredq 已提交
179 180
		if ( this.x > v.x ) {

181
			this.x = v.x;
A
alteredq 已提交
182

183
		}
A
alteredq 已提交
184 185 186

		if ( this.y > v.y ) {

187
			this.y = v.y;
A
alteredq 已提交
188

189
		}
A
alteredq 已提交
190 191 192

		if ( this.z > v.z ) {

193
			this.z = v.z;
A
alteredq 已提交
194

195
		}
196 197 198 199 200 201 202

		return this;

	},

	maxSelf: function ( v ) {

A
alteredq 已提交
203 204
		if ( this.x < v.x ) {

205
			this.x = v.x;
A
alteredq 已提交
206

207
		}
A
alteredq 已提交
208 209 210

		if ( this.y < v.y ) {

211
			this.y = v.y;
A
alteredq 已提交
212

213
		}
A
alteredq 已提交
214 215 216

		if ( this.z < v.z ) {

217
			this.z = v.z;
A
alteredq 已提交
218

219
		}
220 221 222 223

		return this;

	},
M
Mr.doob 已提交
224

225 226 227 228
	clampSelf: function ( min, max ) {

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

A
alteredq 已提交
229 230
		if ( this.x < min.x ) {

231
			this.x = min.x;
A
alteredq 已提交
232 233 234

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

235
			this.x = max.x;
A
alteredq 已提交
236

237 238
		}

A
alteredq 已提交
239 240
		if ( this.y < min.y ) {

241
			this.y = min.y;
A
alteredq 已提交
242 243 244

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

245
			this.y = max.y;
A
alteredq 已提交
246

247 248
		}

A
alteredq 已提交
249 250
		if ( this.z < min.z ) {

251
			this.z = min.z;
A
alteredq 已提交
252 253 254

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

255
			this.z = max.z;
A
alteredq 已提交
256

257 258 259
		}

		return this;
A
alteredq 已提交
260

261 262
	},

263
	negate: function() {
M
Mr.doob 已提交
264

M
Mr.doob 已提交
265
		return this.multiplyScalar( - 1 );
B
Ben Nolan 已提交
266

267
	},
268

269
	dot: function ( v ) {
M
Mr.doob 已提交
270

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

M
Mr.doob 已提交
273
	},
M
Mr.doob 已提交
274

275
	lengthSq: function () {
M
Mr.doob 已提交
276

M
Mr.doob 已提交
277
		return this.x * this.x + this.y * this.y + this.z * this.z;
M
Mr.doob 已提交
278 279 280

	},

281
	length: function () {
M
Mr.doob 已提交
282

M
Mr.doob 已提交
283
		return Math.sqrt( this.lengthSq() );
M
Mr.doob 已提交
284

M
Mr.doob 已提交
285
	},
286

287
	lengthManhattan: function () {
288

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

291 292
	},

293
	normalize: function () {
294

M
Mr.doob 已提交
295
		return this.divideScalar( this.length() );
296

297
	},
298

299
	setLength: function ( l ) {
300

M
Mr.doob 已提交
301
		return this.normalize().multiplyScalar( l );
302

303
	},
304

305 306 307 308 309 310 311 312 313
	lerpSelf: function ( v, alpha ) {

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

		return this;

	},
314

315
	cross: function ( a, b ) {
316

M
Mr.doob 已提交
317 318 319
		this.x = a.y * b.z - a.z * b.y;
		this.y = a.z * b.x - a.x * b.z;
		this.z = a.x * b.y - a.y * b.x;
320

M
Mr.doob 已提交
321
		return this;
322

323
	},
324

325
	crossSelf: function ( v ) {
M
Mr.doob 已提交
326

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

329 330 331
		this.x = y * v.z - z * v.y;
		this.y = z * v.x - x * v.z;
		this.z = x * v.y - y * v.x;
332

333
		return this;
334 335 336

	},

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

W
Wilt 已提交
339
		return Math.acos( this.dot( v ) / this.length() / v.length() );
M
Mr.doob 已提交
340 341

	},
W
Wilt 已提交
342

343
	distanceTo: function ( v ) {
344

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

M
Mr.doob 已提交
347 348
	},

349
	distanceToSquared: function ( v ) {
M
Mr.doob 已提交
350

M
Mr.doob 已提交
351 352 353 354
		var dx = this.x - v.x;
		var dy = this.y - v.y;
		var dz = this.z - v.z;

355
		return dx * dx + dy * dy + dz * dz;
M
Mr.doob 已提交
356

357
	},
M
Mr.doob 已提交
358

M
Mr.doob 已提交
359
	getPositionFromMatrix: function ( m ) {
M
Mr.doob 已提交
360

361 362 363
		this.x = m.elements[12];
		this.y = m.elements[13];
		this.z = m.elements[14];
364

365 366
		return this;

367 368
	},

W
WestLangley 已提交
369 370 371
	setEulerFromRotationMatrix: function ( m, order ) {

		// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
M
Mr.doob 已提交
372

W
WestLangley 已提交
373
		// clamp, to handle numerical problems
M
Mr.doob 已提交
374 375 376 377 378 379

		function clamp( x ) {

			return Math.min( Math.max( x, -1 ), 1 );

		}
380 381 382 383 384 385 386 387 388

		var te = m.elements;
		var m11 = te[0], m12 = te[4], m13 = te[8];
		var m21 = te[1], m22 = te[5], m23 = te[9];
		var m31 = te[2], m32 = te[6], m33 = te[10];

		if ( order === undefined || order === 'XYZ' ) {

			this.y = Math.asin( clamp( m13 ) );
M
Mr.doob 已提交
389

390
			if ( Math.abs( m13 ) < 0.99999 ) {
M
Mr.doob 已提交
391

392 393
				this.x = Math.atan2( - m23, m33 );
				this.z = Math.atan2( - m12, m11 );
M
Mr.doob 已提交
394

395
			} else {
M
Mr.doob 已提交
396

397
				this.x = Math.atan2( m32, m22 );
398
				this.z = 0;
M
Mr.doob 已提交
399

400 401 402
			}

		} else if ( order === 'YXZ' ) {
M
Mr.doob 已提交
403

404
			this.x = Math.asin( - clamp( m23 ) );
M
Mr.doob 已提交
405

406
			if ( Math.abs( m23 ) < 0.99999 ) {
M
Mr.doob 已提交
407

408 409
				this.y = Math.atan2( m13, m33 );
				this.z = Math.atan2( m21, m22 );
M
Mr.doob 已提交
410

411
			} else {
M
Mr.doob 已提交
412

413 414
				this.y = Math.atan2( - m31, m11 );
				this.z = 0;
M
Mr.doob 已提交
415

416
			}
M
Mr.doob 已提交
417

418
		} else if ( order === 'ZXY' ) {
M
Mr.doob 已提交
419

420
			this.x = Math.asin( clamp( m32 ) );
M
Mr.doob 已提交
421

422
			if ( Math.abs( m32 ) < 0.99999 ) {
M
Mr.doob 已提交
423

424 425
				this.y = Math.atan2( - m31, m33 );
				this.z = Math.atan2( - m12, m22 );
M
Mr.doob 已提交
426

427
			} else {
M
Mr.doob 已提交
428

429
				this.y = 0;
430
				this.z = Math.atan2( m21, m11 );
M
Mr.doob 已提交
431

432 433 434
			}

		} else if ( order === 'ZYX' ) {
M
Mr.doob 已提交
435

436
			this.y = Math.asin( - clamp( m31 ) );
M
Mr.doob 已提交
437

438
			if ( Math.abs( m31 ) < 0.99999 ) {
M
Mr.doob 已提交
439

440 441
				this.x = Math.atan2( m32, m33 );
				this.z = Math.atan2( m21, m11 );
M
Mr.doob 已提交
442

443
			} else {
M
Mr.doob 已提交
444

445 446
				this.x = 0;
				this.z = Math.atan2( - m12, m22 );
M
Mr.doob 已提交
447

448
			}
M
Mr.doob 已提交
449

450
		} else if ( order === 'YZX' ) {
M
Mr.doob 已提交
451

452
			this.z = Math.asin( clamp( m21 ) );
M
Mr.doob 已提交
453

454
			if ( Math.abs( m21 ) < 0.99999 ) {
M
Mr.doob 已提交
455

456 457
				this.x = Math.atan2( - m23, m22 );
				this.y = Math.atan2( - m31, m11 );
M
Mr.doob 已提交
458

459
			} else {
M
Mr.doob 已提交
460

461
				this.x = 0;
462
				this.y = Math.atan2( m13, m33 );
M
Mr.doob 已提交
463

464
			}
M
Mr.doob 已提交
465

466
		} else if ( order === 'XZY' ) {
M
Mr.doob 已提交
467

468
			this.z = Math.asin( - clamp( m12 ) );
M
Mr.doob 已提交
469

470
			if ( Math.abs( m12 ) < 0.99999 ) {
M
Mr.doob 已提交
471

472 473
				this.x = Math.atan2( m32, m22 );
				this.y = Math.atan2( m13, m11 );
M
Mr.doob 已提交
474

475
			} else {
M
Mr.doob 已提交
476

477
				this.x = Math.atan2( - m23, m33 );
478
				this.y = 0;
M
Mr.doob 已提交
479

480
			}
M
Mr.doob 已提交
481

482
		}
M
Mr.doob 已提交
483

484 485 486 487
		return this;

	},

W
WestLangley 已提交
488 489 490
	setEulerFromQuaternion: function ( q, order ) {

		// q is assumed to be normalized
M
Mr.doob 已提交
491

W
WestLangley 已提交
492
		// clamp, to handle numerical problems
M
Mr.doob 已提交
493 494 495 496 497 498 499 500

		function clamp( x ) {

			return Math.min( Math.max( x, -1 ), 1 );

		}

		// http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m
M
Mr.doob 已提交
501

M
Mr.doob 已提交
502 503 504 505
		var sqx = q.x * q.x;
		var sqy = q.y * q.y;
		var sqz = q.z * q.z;
		var sqw = q.w * q.w;
506 507 508 509 510 511

		if ( order === undefined || order === 'XYZ' ) {

			this.x = Math.atan2( 2 * ( q.x * q.w - q.y * q.z ), ( sqw - sqx - sqy + sqz ) );
			this.y = Math.asin(  clamp( 2 * ( q.x * q.z + q.y * q.w ) ) );
			this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw + sqx - sqy - sqz ) );
M
Mr.doob 已提交
512

513
		} else if ( order ===  'YXZ' ) {
M
Mr.doob 已提交
514

515 516 517
			this.x = Math.asin(  clamp( 2 * ( q.x * q.w - q.y * q.z ) ) );
			this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw - sqx - sqy + sqz ) );
			this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw - sqx + sqy - sqz ) );
M
Mr.doob 已提交
518

519
		} else if ( order === 'ZXY' ) {
M
Mr.doob 已提交
520

521 522 523
			this.x = Math.asin(  clamp( 2 * ( q.x * q.w + q.y * q.z ) ) );
			this.y = Math.atan2( 2 * ( q.y * q.w - q.z * q.x ), ( sqw - sqx - sqy + sqz ) );
			this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw - sqx + sqy - sqz ) );
M
Mr.doob 已提交
524

525
		} else if ( order === 'ZYX' ) {
M
Mr.doob 已提交
526

527 528 529
			this.x = Math.atan2( 2 * ( q.x * q.w + q.z * q.y ), ( sqw - sqx - sqy + sqz ) );
			this.y = Math.asin(  clamp( 2 * ( q.y * q.w - q.x * q.z ) ) );
			this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw + sqx - sqy - sqz ) );
M
Mr.doob 已提交
530

531
		} else if ( order === 'YZX' ) {
M
Mr.doob 已提交
532

533 534 535
			this.x = Math.atan2( 2 * ( q.x * q.w - q.z * q.y ), ( sqw - sqx + sqy - sqz ) );
			this.y = Math.atan2( 2 * ( q.y * q.w - q.x * q.z ), ( sqw + sqx - sqy - sqz ) );
			this.z = Math.asin(  clamp( 2 * ( q.x * q.y + q.z * q.w ) ) );
M
Mr.doob 已提交
536

537
		} else if ( order === 'XZY' ) {
M
Mr.doob 已提交
538

539 540 541
			this.x = Math.atan2( 2 * ( q.x * q.w + q.y * q.z ), ( sqw - sqx + sqy - sqz ) );
			this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw + sqx - sqy - sqz ) );
			this.z = Math.asin(  clamp( 2 * ( q.z * q.w - q.x * q.y ) ) );
M
Mr.doob 已提交
542

A
alteredq 已提交
543
		}
M
Mr.doob 已提交
544

W
WestLangley 已提交
545
		return this;
A
alteredq 已提交
546 547

	},
548

M
Mr.doob 已提交
549 550
	getScaleFromMatrix: function ( m ) {

551 552 553
		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 已提交
554

555 556 557
		this.x = sx;
		this.y = sy;
		this.z = sz;
M
Mr.doob 已提交
558

559
		return this;
M
Mr.doob 已提交
560 561 562
	},

	equals: function ( v ) {
563 564 565

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

566 567
	},

M
Mr.doob 已提交
568 569 570 571
	clone: function () {

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

572
	}
573

M
Mr.doob 已提交
574
};