Vector3.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. import { clamp } from './MathUtils.js';
  2. import { Quaternion } from './Quaternion.js';
  3. /**
  4. * Class representing a 3D vector. A 3D vector is an ordered triplet of numbers
  5. * (labeled x, y and z), which can be used to represent a number of things, such as:
  6. *
  7. * - A point in 3D space.
  8. * - A direction and length in 3D space. In three.js the length will
  9. * always be the Euclidean distance(straight-line distance) from `(0, 0, 0)` to `(x, y, z)`
  10. * and the direction is also measured from `(0, 0, 0)` towards `(x, y, z)`.
  11. * - Any arbitrary ordered triplet of numbers.
  12. *
  13. * There are other things a 3D vector can be used to represent, such as
  14. * momentum vectors and so on, however these are the most
  15. * common uses in three.js.
  16. *
  17. * Iterating through a vector instance will yield its components `(x, y, z)` in
  18. * the corresponding order.
  19. * ```js
  20. * const a = new THREE.Vector3( 0, 1, 0 );
  21. *
  22. * //no arguments; will be initialised to (0, 0, 0)
  23. * const b = new THREE.Vector3( );
  24. *
  25. * const d = a.distanceTo( b );
  26. * ```
  27. */
  28. class Vector3 {
  29. static {
  30. /**
  31. * This flag can be used for type testing.
  32. *
  33. * @type {boolean}
  34. * @readonly
  35. * @default true
  36. */
  37. Vector3.prototype.isVector3 = true;
  38. }
  39. /**
  40. * Constructs a new 3D vector.
  41. *
  42. * @param {number} [x=0] - The x value of this vector.
  43. * @param {number} [y=0] - The y value of this vector.
  44. * @param {number} [z=0] - The z value of this vector.
  45. */
  46. constructor( x = 0, y = 0, z = 0 ) {
  47. /**
  48. * The x value of this vector.
  49. *
  50. * @type {number}
  51. */
  52. this.x = x;
  53. /**
  54. * The y value of this vector.
  55. *
  56. * @type {number}
  57. */
  58. this.y = y;
  59. /**
  60. * The z value of this vector.
  61. *
  62. * @type {number}
  63. */
  64. this.z = z;
  65. }
  66. /**
  67. * Sets the vector components.
  68. *
  69. * @param {number} x - The value of the x component.
  70. * @param {number} y - The value of the y component.
  71. * @param {number} z - The value of the z component.
  72. * @return {Vector3} A reference to this vector.
  73. */
  74. set( x, y, z ) {
  75. if ( z === undefined ) z = this.z; // sprite.scale.set(x,y)
  76. this.x = x;
  77. this.y = y;
  78. this.z = z;
  79. return this;
  80. }
  81. /**
  82. * Sets the vector components to the same value.
  83. *
  84. * @param {number} scalar - The value to set for all vector components.
  85. * @return {Vector3} A reference to this vector.
  86. */
  87. setScalar( scalar ) {
  88. this.x = scalar;
  89. this.y = scalar;
  90. this.z = scalar;
  91. return this;
  92. }
  93. /**
  94. * Sets the vector's x component to the given value.
  95. *
  96. * @param {number} x - The value to set.
  97. * @return {Vector3} A reference to this vector.
  98. */
  99. setX( x ) {
  100. this.x = x;
  101. return this;
  102. }
  103. /**
  104. * Sets the vector's y component to the given value.
  105. *
  106. * @param {number} y - The value to set.
  107. * @return {Vector3} A reference to this vector.
  108. */
  109. setY( y ) {
  110. this.y = y;
  111. return this;
  112. }
  113. /**
  114. * Sets the vector's z component to the given value.
  115. *
  116. * @param {number} z - The value to set.
  117. * @return {Vector3} A reference to this vector.
  118. */
  119. setZ( z ) {
  120. this.z = z;
  121. return this;
  122. }
  123. /**
  124. * Allows to set a vector component with an index.
  125. *
  126. * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.
  127. * @param {number} value - The value to set.
  128. * @return {Vector3} A reference to this vector.
  129. */
  130. setComponent( index, value ) {
  131. switch ( index ) {
  132. case 0: this.x = value; break;
  133. case 1: this.y = value; break;
  134. case 2: this.z = value; break;
  135. default: throw new Error( 'index is out of range: ' + index );
  136. }
  137. return this;
  138. }
  139. /**
  140. * Returns the value of the vector component which matches the given index.
  141. *
  142. * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.
  143. * @return {number} A vector component value.
  144. */
  145. getComponent( index ) {
  146. switch ( index ) {
  147. case 0: return this.x;
  148. case 1: return this.y;
  149. case 2: return this.z;
  150. default: throw new Error( 'index is out of range: ' + index );
  151. }
  152. }
  153. /**
  154. * Returns a new vector with copied values from this instance.
  155. *
  156. * @return {Vector3} A clone of this instance.
  157. */
  158. clone() {
  159. return new this.constructor( this.x, this.y, this.z );
  160. }
  161. /**
  162. * Copies the values of the given vector to this instance.
  163. *
  164. * @param {Vector3} v - The vector to copy.
  165. * @return {Vector3} A reference to this vector.
  166. */
  167. copy( v ) {
  168. this.x = v.x;
  169. this.y = v.y;
  170. this.z = v.z;
  171. return this;
  172. }
  173. /**
  174. * Adds the given vector to this instance.
  175. *
  176. * @param {Vector3} v - The vector to add.
  177. * @return {Vector3} A reference to this vector.
  178. */
  179. add( v ) {
  180. this.x += v.x;
  181. this.y += v.y;
  182. this.z += v.z;
  183. return this;
  184. }
  185. /**
  186. * Adds the given scalar value to all components of this instance.
  187. *
  188. * @param {number} s - The scalar to add.
  189. * @return {Vector3} A reference to this vector.
  190. */
  191. addScalar( s ) {
  192. this.x += s;
  193. this.y += s;
  194. this.z += s;
  195. return this;
  196. }
  197. /**
  198. * Adds the given vectors and stores the result in this instance.
  199. *
  200. * @param {Vector3} a - The first vector.
  201. * @param {Vector3} b - The second vector.
  202. * @return {Vector3} A reference to this vector.
  203. */
  204. addVectors( a, b ) {
  205. this.x = a.x + b.x;
  206. this.y = a.y + b.y;
  207. this.z = a.z + b.z;
  208. return this;
  209. }
  210. /**
  211. * Adds the given vector scaled by the given factor to this instance.
  212. *
  213. * @param {Vector3|Vector4} v - The vector.
  214. * @param {number} s - The factor that scales `v`.
  215. * @return {Vector3} A reference to this vector.
  216. */
  217. addScaledVector( v, s ) {
  218. this.x += v.x * s;
  219. this.y += v.y * s;
  220. this.z += v.z * s;
  221. return this;
  222. }
  223. /**
  224. * Subtracts the given vector from this instance.
  225. *
  226. * @param {Vector3} v - The vector to subtract.
  227. * @return {Vector3} A reference to this vector.
  228. */
  229. sub( v ) {
  230. this.x -= v.x;
  231. this.y -= v.y;
  232. this.z -= v.z;
  233. return this;
  234. }
  235. /**
  236. * Subtracts the given scalar value from all components of this instance.
  237. *
  238. * @param {number} s - The scalar to subtract.
  239. * @return {Vector3} A reference to this vector.
  240. */
  241. subScalar( s ) {
  242. this.x -= s;
  243. this.y -= s;
  244. this.z -= s;
  245. return this;
  246. }
  247. /**
  248. * Subtracts the given vectors and stores the result in this instance.
  249. *
  250. * @param {Vector3} a - The first vector.
  251. * @param {Vector3} b - The second vector.
  252. * @return {Vector3} A reference to this vector.
  253. */
  254. subVectors( a, b ) {
  255. this.x = a.x - b.x;
  256. this.y = a.y - b.y;
  257. this.z = a.z - b.z;
  258. return this;
  259. }
  260. /**
  261. * Multiplies the given vector with this instance.
  262. *
  263. * @param {Vector3} v - The vector to multiply.
  264. * @return {Vector3} A reference to this vector.
  265. */
  266. multiply( v ) {
  267. this.x *= v.x;
  268. this.y *= v.y;
  269. this.z *= v.z;
  270. return this;
  271. }
  272. /**
  273. * Multiplies the given scalar value with all components of this instance.
  274. *
  275. * @param {number} scalar - The scalar to multiply.
  276. * @return {Vector3} A reference to this vector.
  277. */
  278. multiplyScalar( scalar ) {
  279. this.x *= scalar;
  280. this.y *= scalar;
  281. this.z *= scalar;
  282. return this;
  283. }
  284. /**
  285. * Multiplies the given vectors and stores the result in this instance.
  286. *
  287. * @param {Vector3} a - The first vector.
  288. * @param {Vector3} b - The second vector.
  289. * @return {Vector3} A reference to this vector.
  290. */
  291. multiplyVectors( a, b ) {
  292. this.x = a.x * b.x;
  293. this.y = a.y * b.y;
  294. this.z = a.z * b.z;
  295. return this;
  296. }
  297. /**
  298. * Applies the given Euler rotation to this vector.
  299. *
  300. * @param {Euler} euler - The Euler angles.
  301. * @return {Vector3} A reference to this vector.
  302. */
  303. applyEuler( euler ) {
  304. return this.applyQuaternion( _quaternion.setFromEuler( euler ) );
  305. }
  306. /**
  307. * Applies a rotation specified by an axis and an angle to this vector.
  308. *
  309. * @param {Vector3} axis - A normalized vector representing the rotation axis.
  310. * @param {number} angle - The angle in radians.
  311. * @return {Vector3} A reference to this vector.
  312. */
  313. applyAxisAngle( axis, angle ) {
  314. return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) );
  315. }
  316. /**
  317. * Multiplies this vector with the given 3x3 matrix.
  318. *
  319. * @param {Matrix3} m - The 3x3 matrix.
  320. * @return {Vector3} A reference to this vector.
  321. */
  322. applyMatrix3( m ) {
  323. const x = this.x, y = this.y, z = this.z;
  324. const e = m.elements;
  325. this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
  326. this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
  327. this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
  328. return this;
  329. }
  330. /**
  331. * Multiplies this vector by the given normal matrix and normalizes
  332. * the result.
  333. *
  334. * @param {Matrix3} m - The normal matrix.
  335. * @return {Vector3} A reference to this vector.
  336. */
  337. applyNormalMatrix( m ) {
  338. return this.applyMatrix3( m ).normalize();
  339. }
  340. /**
  341. * Multiplies this vector (with an implicit 1 in the 4th dimension) by m, and
  342. * divides by perspective.
  343. *
  344. * @param {Matrix4} m - The matrix to apply.
  345. * @return {Vector3} A reference to this vector.
  346. */
  347. applyMatrix4( m ) {
  348. const x = this.x, y = this.y, z = this.z;
  349. const e = m.elements;
  350. const w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
  351. this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;
  352. this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;
  353. this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;
  354. return this;
  355. }
  356. /**
  357. * Applies the given Quaternion to this vector.
  358. *
  359. * @param {Quaternion} q - The Quaternion.
  360. * @return {Vector3} A reference to this vector.
  361. */
  362. applyQuaternion( q ) {
  363. // quaternion q is assumed to have unit length
  364. const vx = this.x, vy = this.y, vz = this.z;
  365. const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
  366. // t = 2 * cross( q.xyz, v );
  367. const tx = 2 * ( qy * vz - qz * vy );
  368. const ty = 2 * ( qz * vx - qx * vz );
  369. const tz = 2 * ( qx * vy - qy * vx );
  370. // v + q.w * t + cross( q.xyz, t );
  371. this.x = vx + qw * tx + qy * tz - qz * ty;
  372. this.y = vy + qw * ty + qz * tx - qx * tz;
  373. this.z = vz + qw * tz + qx * ty - qy * tx;
  374. return this;
  375. }
  376. /**
  377. * Projects this vector from world space into the camera's normalized
  378. * device coordinate (NDC) space.
  379. *
  380. * @param {Camera} camera - The camera.
  381. * @return {Vector3} A reference to this vector.
  382. */
  383. project( camera ) {
  384. return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix );
  385. }
  386. /**
  387. * Unprojects this vector from the camera's normalized device coordinate (NDC)
  388. * space into world space.
  389. *
  390. * @param {Camera} camera - The camera.
  391. * @return {Vector3} A reference to this vector.
  392. */
  393. unproject( camera ) {
  394. return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld );
  395. }
  396. /**
  397. * Transforms the direction of this vector by a matrix (the upper left 3 x 3
  398. * subset of the given 4x4 matrix and then normalizes the result.
  399. *
  400. * @param {Matrix4} m - The matrix.
  401. * @return {Vector3} A reference to this vector.
  402. */
  403. transformDirection( m ) {
  404. // input: THREE.Matrix4 affine matrix
  405. // vector interpreted as a direction
  406. const x = this.x, y = this.y, z = this.z;
  407. const e = m.elements;
  408. this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
  409. this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
  410. this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
  411. return this.normalize();
  412. }
  413. /**
  414. * Divides this instance by the given vector.
  415. *
  416. * @param {Vector3} v - The vector to divide.
  417. * @return {Vector3} A reference to this vector.
  418. */
  419. divide( v ) {
  420. this.x /= v.x;
  421. this.y /= v.y;
  422. this.z /= v.z;
  423. return this;
  424. }
  425. /**
  426. * Divides this vector by the given scalar.
  427. *
  428. * @param {number} scalar - The scalar to divide.
  429. * @return {Vector3} A reference to this vector.
  430. */
  431. divideScalar( scalar ) {
  432. return this.multiplyScalar( 1 / scalar );
  433. }
  434. /**
  435. * If this vector's x, y or z value is greater than the given vector's x, y or z
  436. * value, replace that value with the corresponding min value.
  437. *
  438. * @param {Vector3} v - The vector.
  439. * @return {Vector3} A reference to this vector.
  440. */
  441. min( v ) {
  442. this.x = Math.min( this.x, v.x );
  443. this.y = Math.min( this.y, v.y );
  444. this.z = Math.min( this.z, v.z );
  445. return this;
  446. }
  447. /**
  448. * If this vector's x, y or z value is less than the given vector's x, y or z
  449. * value, replace that value with the corresponding max value.
  450. *
  451. * @param {Vector3} v - The vector.
  452. * @return {Vector3} A reference to this vector.
  453. */
  454. max( v ) {
  455. this.x = Math.max( this.x, v.x );
  456. this.y = Math.max( this.y, v.y );
  457. this.z = Math.max( this.z, v.z );
  458. return this;
  459. }
  460. /**
  461. * If this vector's x, y or z value is greater than the max vector's x, y or z
  462. * value, it is replaced by the corresponding value.
  463. * If this vector's x, y or z value is less than the min vector's x, y or z value,
  464. * it is replaced by the corresponding value.
  465. *
  466. * @param {Vector3} min - The minimum x, y and z values.
  467. * @param {Vector3} max - The maximum x, y and z values in the desired range.
  468. * @return {Vector3} A reference to this vector.
  469. */
  470. clamp( min, max ) {
  471. // assumes min < max, componentwise
  472. this.x = clamp( this.x, min.x, max.x );
  473. this.y = clamp( this.y, min.y, max.y );
  474. this.z = clamp( this.z, min.z, max.z );
  475. return this;
  476. }
  477. /**
  478. * If this vector's x, y or z values are greater than the max value, they are
  479. * replaced by the max value.
  480. * If this vector's x, y or z values are less than the min value, they are
  481. * replaced by the min value.
  482. *
  483. * @param {number} minVal - The minimum value the components will be clamped to.
  484. * @param {number} maxVal - The maximum value the components will be clamped to.
  485. * @return {Vector3} A reference to this vector.
  486. */
  487. clampScalar( minVal, maxVal ) {
  488. this.x = clamp( this.x, minVal, maxVal );
  489. this.y = clamp( this.y, minVal, maxVal );
  490. this.z = clamp( this.z, minVal, maxVal );
  491. return this;
  492. }
  493. /**
  494. * If this vector's length is greater than the max value, it is replaced by
  495. * the max value.
  496. * If this vector's length is less than the min value, it is replaced by the
  497. * min value.
  498. *
  499. * @param {number} min - The minimum value the vector length will be clamped to.
  500. * @param {number} max - The maximum value the vector length will be clamped to.
  501. * @return {Vector3} A reference to this vector.
  502. */
  503. clampLength( min, max ) {
  504. const length = this.length();
  505. return this.divideScalar( length || 1 ).multiplyScalar( clamp( length, min, max ) );
  506. }
  507. /**
  508. * The components of this vector are rounded down to the nearest integer value.
  509. *
  510. * @return {Vector3} A reference to this vector.
  511. */
  512. floor() {
  513. this.x = Math.floor( this.x );
  514. this.y = Math.floor( this.y );
  515. this.z = Math.floor( this.z );
  516. return this;
  517. }
  518. /**
  519. * The components of this vector are rounded up to the nearest integer value.
  520. *
  521. * @return {Vector3} A reference to this vector.
  522. */
  523. ceil() {
  524. this.x = Math.ceil( this.x );
  525. this.y = Math.ceil( this.y );
  526. this.z = Math.ceil( this.z );
  527. return this;
  528. }
  529. /**
  530. * The components of this vector are rounded to the nearest integer value
  531. *
  532. * @return {Vector3} A reference to this vector.
  533. */
  534. round() {
  535. this.x = Math.round( this.x );
  536. this.y = Math.round( this.y );
  537. this.z = Math.round( this.z );
  538. return this;
  539. }
  540. /**
  541. * The components of this vector are rounded towards zero (up if negative,
  542. * down if positive) to an integer value.
  543. *
  544. * @return {Vector3} A reference to this vector.
  545. */
  546. roundToZero() {
  547. this.x = Math.trunc( this.x );
  548. this.y = Math.trunc( this.y );
  549. this.z = Math.trunc( this.z );
  550. return this;
  551. }
  552. /**
  553. * Inverts this vector - i.e. sets x = -x, y = -y and z = -z.
  554. *
  555. * @return {Vector3} A reference to this vector.
  556. */
  557. negate() {
  558. this.x = - this.x;
  559. this.y = - this.y;
  560. this.z = - this.z;
  561. return this;
  562. }
  563. /**
  564. * Calculates the dot product of the given vector with this instance.
  565. *
  566. * @param {Vector3} v - The vector to compute the dot product with.
  567. * @return {number} The result of the dot product.
  568. */
  569. dot( v ) {
  570. return this.x * v.x + this.y * v.y + this.z * v.z;
  571. }
  572. /**
  573. * Computes the square of the Euclidean length (straight-line length) from
  574. * (0, 0, 0) to (x, y, z). If you are comparing the lengths of vectors, you should
  575. * compare the length squared instead as it is slightly more efficient to calculate.
  576. *
  577. * @return {number} The square length of this vector.
  578. */
  579. lengthSq() {
  580. return this.x * this.x + this.y * this.y + this.z * this.z;
  581. }
  582. /**
  583. * Computes the Euclidean length (straight-line length) from (0, 0, 0) to (x, y, z).
  584. *
  585. * @return {number} The length of this vector.
  586. */
  587. length() {
  588. return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
  589. }
  590. /**
  591. * Computes the Manhattan length of this vector.
  592. *
  593. * @return {number} The length of this vector.
  594. */
  595. manhattanLength() {
  596. return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
  597. }
  598. /**
  599. * Converts this vector to a unit vector - that is, sets it equal to a vector
  600. * with the same direction as this one, but with a vector length of `1`.
  601. *
  602. * @return {Vector3} A reference to this vector.
  603. */
  604. normalize() {
  605. return this.divideScalar( this.length() || 1 );
  606. }
  607. /**
  608. * Sets this vector to a vector with the same direction as this one, but
  609. * with the specified length.
  610. *
  611. * @param {number} length - The new length of this vector.
  612. * @return {Vector3} A reference to this vector.
  613. */
  614. setLength( length ) {
  615. return this.normalize().multiplyScalar( length );
  616. }
  617. /**
  618. * Linearly interpolates between the given vector and this instance, where
  619. * alpha is the percent distance along the line - alpha = 0 will be this
  620. * vector, and alpha = 1 will be the given one.
  621. *
  622. * @param {Vector3} v - The vector to interpolate towards.
  623. * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
  624. * @return {Vector3} A reference to this vector.
  625. */
  626. lerp( v, alpha ) {
  627. this.x += ( v.x - this.x ) * alpha;
  628. this.y += ( v.y - this.y ) * alpha;
  629. this.z += ( v.z - this.z ) * alpha;
  630. return this;
  631. }
  632. /**
  633. * Linearly interpolates between the given vectors, where alpha is the percent
  634. * distance along the line - alpha = 0 will be first vector, and alpha = 1 will
  635. * be the second one. The result is stored in this instance.
  636. *
  637. * @param {Vector3} v1 - The first vector.
  638. * @param {Vector3} v2 - The second vector.
  639. * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
  640. * @return {Vector3} A reference to this vector.
  641. */
  642. lerpVectors( v1, v2, alpha ) {
  643. this.x = v1.x + ( v2.x - v1.x ) * alpha;
  644. this.y = v1.y + ( v2.y - v1.y ) * alpha;
  645. this.z = v1.z + ( v2.z - v1.z ) * alpha;
  646. return this;
  647. }
  648. /**
  649. * Calculates the cross product of the given vector with this instance.
  650. *
  651. * @param {Vector3} v - The vector to compute the cross product with.
  652. * @return {Vector3} The result of the cross product.
  653. */
  654. cross( v ) {
  655. return this.crossVectors( this, v );
  656. }
  657. /**
  658. * Calculates the cross product of the given vectors and stores the result
  659. * in this instance.
  660. *
  661. * @param {Vector3} a - The first vector.
  662. * @param {Vector3} b - The second vector.
  663. * @return {Vector3} A reference to this vector.
  664. */
  665. crossVectors( a, b ) {
  666. const ax = a.x, ay = a.y, az = a.z;
  667. const bx = b.x, by = b.y, bz = b.z;
  668. this.x = ay * bz - az * by;
  669. this.y = az * bx - ax * bz;
  670. this.z = ax * by - ay * bx;
  671. return this;
  672. }
  673. /**
  674. * Projects this vector onto the given one.
  675. *
  676. * @param {Vector3} v - The vector to project to.
  677. * @return {Vector3} A reference to this vector.
  678. */
  679. projectOnVector( v ) {
  680. const denominator = v.lengthSq();
  681. if ( denominator === 0 ) return this.set( 0, 0, 0 );
  682. const scalar = v.dot( this ) / denominator;
  683. return this.copy( v ).multiplyScalar( scalar );
  684. }
  685. /**
  686. * Projects this vector onto a plane by subtracting this
  687. * vector projected onto the plane's normal from this vector.
  688. *
  689. * @param {Vector3} planeNormal - The plane normal.
  690. * @return {Vector3} A reference to this vector.
  691. */
  692. projectOnPlane( planeNormal ) {
  693. _vector.copy( this ).projectOnVector( planeNormal );
  694. return this.sub( _vector );
  695. }
  696. /**
  697. * Reflects this vector off a plane orthogonal to the given normal vector.
  698. *
  699. * @param {Vector3} normal - The (normalized) normal vector.
  700. * @return {Vector3} A reference to this vector.
  701. */
  702. reflect( normal ) {
  703. return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
  704. }
  705. /**
  706. * Returns the angle between the given vector and this instance in radians.
  707. *
  708. * @param {Vector3} v - The vector to compute the angle with.
  709. * @return {number} The angle in radians.
  710. */
  711. angleTo( v ) {
  712. const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );
  713. if ( denominator === 0 ) return Math.PI / 2;
  714. const theta = this.dot( v ) / denominator;
  715. // clamp, to handle numerical problems
  716. return Math.acos( clamp( theta, - 1, 1 ) );
  717. }
  718. /**
  719. * Computes the distance from the given vector to this instance.
  720. *
  721. * @param {Vector3} v - The vector to compute the distance to.
  722. * @return {number} The distance.
  723. */
  724. distanceTo( v ) {
  725. return Math.sqrt( this.distanceToSquared( v ) );
  726. }
  727. /**
  728. * Computes the squared distance from the given vector to this instance.
  729. * If you are just comparing the distance with another distance, you should compare
  730. * the distance squared instead as it is slightly more efficient to calculate.
  731. *
  732. * @param {Vector3} v - The vector to compute the squared distance to.
  733. * @return {number} The squared distance.
  734. */
  735. distanceToSquared( v ) {
  736. const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
  737. return dx * dx + dy * dy + dz * dz;
  738. }
  739. /**
  740. * Computes the Manhattan distance from the given vector to this instance.
  741. *
  742. * @param {Vector3} v - The vector to compute the Manhattan distance to.
  743. * @return {number} The Manhattan distance.
  744. */
  745. manhattanDistanceTo( v ) {
  746. return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
  747. }
  748. /**
  749. * Sets the vector components from the given spherical coordinates.
  750. *
  751. * @param {Spherical} s - The spherical coordinates.
  752. * @return {Vector3} A reference to this vector.
  753. */
  754. setFromSpherical( s ) {
  755. return this.setFromSphericalCoords( s.radius, s.phi, s.theta );
  756. }
  757. /**
  758. * Sets the vector components from the given spherical coordinates.
  759. *
  760. * @param {number} radius - The radius.
  761. * @param {number} phi - The phi angle in radians.
  762. * @param {number} theta - The theta angle in radians.
  763. * @return {Vector3} A reference to this vector.
  764. */
  765. setFromSphericalCoords( radius, phi, theta ) {
  766. const sinPhiRadius = Math.sin( phi ) * radius;
  767. this.x = sinPhiRadius * Math.sin( theta );
  768. this.y = Math.cos( phi ) * radius;
  769. this.z = sinPhiRadius * Math.cos( theta );
  770. return this;
  771. }
  772. /**
  773. * Sets the vector components from the given cylindrical coordinates.
  774. *
  775. * @param {Cylindrical} c - The cylindrical coordinates.
  776. * @return {Vector3} A reference to this vector.
  777. */
  778. setFromCylindrical( c ) {
  779. return this.setFromCylindricalCoords( c.radius, c.theta, c.y );
  780. }
  781. /**
  782. * Sets the vector components from the given cylindrical coordinates.
  783. *
  784. * @param {number} radius - The radius.
  785. * @param {number} theta - The theta angle in radians.
  786. * @param {number} y - The y value.
  787. * @return {Vector3} A reference to this vector.
  788. */
  789. setFromCylindricalCoords( radius, theta, y ) {
  790. this.x = radius * Math.sin( theta );
  791. this.y = y;
  792. this.z = radius * Math.cos( theta );
  793. return this;
  794. }
  795. /**
  796. * Sets the vector components to the position elements of the
  797. * given transformation matrix.
  798. *
  799. * @param {Matrix4} m - The 4x4 matrix.
  800. * @return {Vector3} A reference to this vector.
  801. */
  802. setFromMatrixPosition( m ) {
  803. const e = m.elements;
  804. this.x = e[ 12 ];
  805. this.y = e[ 13 ];
  806. this.z = e[ 14 ];
  807. return this;
  808. }
  809. /**
  810. * Sets the vector components to the scale elements of the
  811. * given transformation matrix.
  812. *
  813. * @param {Matrix4} m - The 4x4 matrix.
  814. * @return {Vector3} A reference to this vector.
  815. */
  816. setFromMatrixScale( m ) {
  817. const sx = this.setFromMatrixColumn( m, 0 ).length();
  818. const sy = this.setFromMatrixColumn( m, 1 ).length();
  819. const sz = this.setFromMatrixColumn( m, 2 ).length();
  820. this.x = sx;
  821. this.y = sy;
  822. this.z = sz;
  823. return this;
  824. }
  825. /**
  826. * Sets the vector components from the specified matrix column.
  827. *
  828. * @param {Matrix4} m - The 4x4 matrix.
  829. * @param {number} index - The column index.
  830. * @return {Vector3} A reference to this vector.
  831. */
  832. setFromMatrixColumn( m, index ) {
  833. return this.fromArray( m.elements, index * 4 );
  834. }
  835. /**
  836. * Sets the vector components from the specified matrix column.
  837. *
  838. * @param {Matrix3} m - The 3x3 matrix.
  839. * @param {number} index - The column index.
  840. * @return {Vector3} A reference to this vector.
  841. */
  842. setFromMatrix3Column( m, index ) {
  843. return this.fromArray( m.elements, index * 3 );
  844. }
  845. /**
  846. * Sets the vector components from the given Euler angles.
  847. *
  848. * @param {Euler} e - The Euler angles to set.
  849. * @return {Vector3} A reference to this vector.
  850. */
  851. setFromEuler( e ) {
  852. this.x = e._x;
  853. this.y = e._y;
  854. this.z = e._z;
  855. return this;
  856. }
  857. /**
  858. * Sets the vector components from the RGB components of the
  859. * given color.
  860. *
  861. * @param {Color} c - The color to set.
  862. * @return {Vector3} A reference to this vector.
  863. */
  864. setFromColor( c ) {
  865. this.x = c.r;
  866. this.y = c.g;
  867. this.z = c.b;
  868. return this;
  869. }
  870. /**
  871. * Returns `true` if this vector is equal with the given one.
  872. *
  873. * @param {Vector3} v - The vector to test for equality.
  874. * @return {boolean} Whether this vector is equal with the given one.
  875. */
  876. equals( v ) {
  877. return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
  878. }
  879. /**
  880. * Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`
  881. * and z value to be `array[ offset + 2 ]`.
  882. *
  883. * @param {Array<number>} array - An array holding the vector component values.
  884. * @param {number} [offset=0] - The offset into the array.
  885. * @return {Vector3} A reference to this vector.
  886. */
  887. fromArray( array, offset = 0 ) {
  888. this.x = array[ offset ];
  889. this.y = array[ offset + 1 ];
  890. this.z = array[ offset + 2 ];
  891. return this;
  892. }
  893. /**
  894. * Writes the components of this vector to the given array. If no array is provided,
  895. * the method returns a new instance.
  896. *
  897. * @param {Array<number>} [array=[]] - The target array holding the vector components.
  898. * @param {number} [offset=0] - Index of the first element in the array.
  899. * @return {Array<number>} The vector components.
  900. */
  901. toArray( array = [], offset = 0 ) {
  902. array[ offset ] = this.x;
  903. array[ offset + 1 ] = this.y;
  904. array[ offset + 2 ] = this.z;
  905. return array;
  906. }
  907. /**
  908. * Sets the components of this vector from the given buffer attribute.
  909. *
  910. * @param {BufferAttribute} attribute - The buffer attribute holding vector data.
  911. * @param {number} index - The index into the attribute.
  912. * @return {Vector3} A reference to this vector.
  913. */
  914. fromBufferAttribute( attribute, index ) {
  915. this.x = attribute.getX( index );
  916. this.y = attribute.getY( index );
  917. this.z = attribute.getZ( index );
  918. return this;
  919. }
  920. /**
  921. * Sets each component of this vector to a pseudo-random value between `0` and
  922. * `1`, excluding `1`.
  923. *
  924. * @return {Vector3} A reference to this vector.
  925. */
  926. random() {
  927. this.x = Math.random();
  928. this.y = Math.random();
  929. this.z = Math.random();
  930. return this;
  931. }
  932. /**
  933. * Sets this vector to a uniformly random point on a unit sphere.
  934. *
  935. * @return {Vector3} A reference to this vector.
  936. */
  937. randomDirection() {
  938. // https://mathworld.wolfram.com/SpherePointPicking.html
  939. const theta = Math.random() * Math.PI * 2;
  940. const u = Math.random() * 2 - 1;
  941. const c = Math.sqrt( 1 - u * u );
  942. this.x = c * Math.cos( theta );
  943. this.y = u;
  944. this.z = c * Math.sin( theta );
  945. return this;
  946. }
  947. *[ Symbol.iterator ]() {
  948. yield this.x;
  949. yield this.y;
  950. yield this.z;
  951. }
  952. }
  953. const _vector = /*@__PURE__*/ new Vector3();
  954. const _quaternion = /*@__PURE__*/ new Quaternion();
  955. export { Vector3 };
粤ICP备19079148号