three.js 原始碼註釋(四)Math/Vector3.js
阿新 • • 發佈:2019-02-17
以下程式碼是THREE.JS 原始碼檔案中Math/Vector3.js檔案的註釋.
// File:src/math/Vector3.js /** * @author mrdoob / http://mrdoob.com/ * @author *kile / http://kile.stravaganza.org/ * @author philogb / http://blog.thejit.org/ * @author mikael emtinger / http://gomo.se/ * @author egraether / http://egraether.com/ * @author WestLangley / http://github.com/WestLangley */ /* ///Vector3物件的建構函式.用來建立一個三維向量的物件.Vector3物件的功能函式採用 ///定義構造的函式原型物件來實現. /// /// 用法: var p2d = new Vector3(5,3,2) /// 建立一個x座標為5,y座標為3的向量,z座標為2的向量. /// NOTE: 引數(x,y,z)座標為可選引數,如果不指定引數(x,y,z),將建立一個座標為(0,0,0)的向量. */ ///<summary>Vector3</summary> ///<param name ="x" type="number">x座標</param> ///<param name ="y" type="number">y座標</param> ///<param name ="z" type="number">z座標</param> THREE.Vector3 = function ( x, y, z ) { this.x = x || 0; this.y = y || 0; this.z = z || 0; }; /**************************************** ****下面是Vector3物件提供的功能函式. ****************************************/ THREE.Vector3.prototype = { constructor: THREE.Vector3, //構造器 /* ///set方法用來從新設定三維向量的x,y,z座標值.並返回新的座標值的三維向量. */ ///<summary>set</summary> ///<param name ="x" type="number">x座標</param> ///<param name ="y" type="number">y座標</param> ///<param name ="z" type="number">y座標</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> set: function ( x, y, z ) { this.x = x; this.y = y; this.z = z; return this; //返回新座標值的三維向量 }, /* ///setX方法用來從新設定三維向量的x座標值.並返回新的座標值的三維向量. */ ///<summary>setX</summary> ///<param name ="x" type="number">x座標</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> setX: function ( x ) { this.x = x; return this; //返回新座標值的三維向量 }, /* ///setY方法用來從新設定三維向量的y座標值.並返回新的座標值的三維向量. */ ///<summary>setY</summary> ///<param name ="y" type="number">y座標</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> setY: function ( y ) { this.y = y; return this; //返回新座標值的三維向量 }, /* ///setZ方法用來從新設定三維向量的z座標值.並返回新的座標值的三維向量. */ ///<summary>setZ</summary> ///<param name ="z" type="number">z座標</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> setZ: function ( z ) { this.z = z; return this; //返回新座標值的三維向量 }, /* ///setComponent方法用來從新設定三維向量的(x,y)座標值.並返回新的座標值的三維向量. ///引數index取值為0,1 或者 2,取值為0,引數value設定x的座標值,取值為1,引數value設定y的座標, ///取值為2,引數value設定z的座標. */ ///<summary>setComponent</summary> ///<param name ="index" type="number">0,1或2</param> ///<param name ="value" type="number">x, y 或 z座標</param> setComponent: function ( index, value ) { switch ( index ) { case 0: this.x = value; break; case 1: this.y = value; break; case 2: this.z = value; break; default: throw new Error( 'index is out of range: ' + index ); } }, /* ///getComponent方法用獲得三維向量的(x,y,z)座標值. ///引數index取值為0,1 或者 2,取值為0,獲得x的座標值,取值為1,獲得y的座標, ///取值為2,獲得z的座標. */ ///<summary>setComponent</summary> ///<param name ="index" type="number">0,1或2</param> getComponent: function ( index ) { switch ( index ) { case 0: return this.x; case 1: return this.y; case 2: return this.z; default: throw new Error( 'index is out of range: ' + index ); } }, /* ///copy方法用來複制三維向量的(x,y,z)座標值.並返回新的座標值的三維向量. */ ///<summary>copy</summary> ///<param name ="v" type="Vector3">三維向量</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> copy: function ( v ) { this.x = v.x; this.y = v.y; this.z = v.z; return this; //返回新座標值的三維向量 }, /* ///add方法用來將三維向量的(x,y,z)座標值與引數v的(x,y,z)相加.並返回新的座標值的三維向量. /// NOTE:add()方法雖然有兩個引數,但實際上只對引數v做運算,這裡的引數w,如果設定的話,呼叫.addVectors()方法. */ ///<summary>add</summary> ///<param name ="v" type="Vector3">與當前物件(x,y,z)座標值增加的向量</param> ///<param name ="w" type="Vector3">判斷是否有第二個引數w,如果有的話,呼叫.addVectors()方法</param> ///<returns type="Vector2">返回新座標值的二維向量</returns> add: function ( v, w ) { if ( w !== undefined ) { //判斷是否有第二個引數w,如果有的話,呼叫.addVectors()方法. //THREE.Vector3: .add()方法現在只有一個引數,如果2個引數使用.addVectors( a, b )方法來替代. console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } this.x += v.x; this.y += v.y; this.z += v.z; return this; //返回新座標值的三維向量 }, /* ///addScalar方法用來將三維向量的(x,y,z)座標值直接與引數s相加.並返回新的座標值的三維向量. /// NOTE:這裡與add()方法不同的是,這裡傳遞的引數s是一個標量,而add()方法的引數v是一個三維向量. */ ///<summary>addScalar</summary> ///<param name ="s" type="number">(x,y,z)要增加的數值</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> addScalar: function ( s ) { this.x += s; this.y += s; this.z += s; return this; //返回新座標值的三維向量 }, /* ///addVectors方法用來將三維向量的(x,y,z)座標值等於引數(a,b)的(x,y,z)相加.並返回新的座標值的三維向量. /// NOTE:兩個向量元件對應相加。 */ ///<summary>addVectors</summary> ///<param name ="a" type="Vector3">三維向量</param> ///<param name ="b" type="Vector3">三維向量</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> addVectors: function ( a, b ) { this.x = a.x + b.x; this.y = a.y + b.y; this.z = a.z + b.z; return this; //返回新座標值的三維向量 }, /* ///sub方法用來將三維向量的(x,y,z)座標值與引數v的(x,y,z)相減.並返回新的座標值的三維向量. /// NOTE:sub()方法雖然有兩個引數,但實際上只對引數v做運算,這裡的引數w,如果設定的話,呼叫.subVectors()方法. */ ///<summary>sub</summary> ///<param name ="v" type="Vector3">與當前物件(x,y,z)座標值增加的三維向量</param> ///<param name ="w" type="Vector3">判斷是否有第二個引數w,如果有的話,呼叫.subVectors()方法</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> sub: function ( v, w ) { if ( w !== undefined ) { //判斷是否有第二個引數w,如果有的話,呼叫.subVectors()方法. //THREE.Vector3: .sub()方法現在只有一個引數,如果2個引數使用.subVectors( a, b )方法來替代. console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } this.x -= v.x; this.y -= v.y; this.z -= v.z; return this; //返回新座標值的三維向量 }, /* ///subVectors方法用來將三維向量的(x,y,z)座標值分別於引數(a,b)的(x,y,z)相減.並返回新的座標值的三維向量. */ ///<summary>subVectors</summary> ///<param name ="a" type="Vector3">三維向量</param> ///<param name ="b" type="Vector3">三維向量</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> subVectors: function ( a, b ) { this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; return this; //返回新座標值的三維向量 }, /* ///multiply方法用來將三維向量的(x,y,z)座標值與引數v的(x,y,z)相乘.並返回新的座標值的三維向量. */ ///<summary>multiply</summary> ///<param name ="v" type="Vector3">與當前物件(x,y,z)值相乘的三維向量</param> ///<param name ="w" type="Vector3">判斷是否有第二個引數w,如果有的話,呼叫.multiplyVectors()方法</param> ///<returns type="Vector2">返回新座標值的三維向量</returns> multiply: function ( v, w ) { if ( w !== undefined ) { //THREE.Vector3: .multiply()方法現在只有一個引數,如果2個引數使用.multiplyVectors( a, b )方法來替代. console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); return this.multiplyVectors( v, w ); } this.x *= v.x; this.y *= v.y; this.z *= v.z; return this; //返回新座標值的三維向量 }, /* ///multiplyScalar方法用來將三維向量的(x,y,z)座標值直接與引數s相乘.並返回新的座標值的三維向量. /// NOTE:這裡與multiply()方法不同的是,這裡傳遞的引數scalar是一個標量,而multiply()方法的引數v是一個三維向量. */ ///<summary>multiplyScalar</summary> ///<param name ="scalar" type="number">與當前物件(x,y,z)值相乘的標量,數值</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> multiplyScalar: function ( scalar ) { this.x *= scalar; this.y *= scalar; this.z *= scalar; return this; //返回新座標值的三維向量 }, /* ///multiplyVectors方法用來將三維向量的(x,y,z)座標值等於引數(a,b)的(x,y,z)相乘.並返回新的座標值的三維向量. /// NOTE:兩個向量元件對應相乘。 */ ///<summary>multiplyVectors</summary> ///<param name ="a" type="Vector3">三維向量</param> ///<param name ="b" type="Vector3">三維向量</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> multiplyVectors: function ( a, b ) { this.x = a.x * b.x; this.y = a.y * b.y; this.z = a.z * b.z; return this; //返回新座標值的三維向量 }, /* ///applyEuler方法將當前向量通過引數euler(THREE.Euler物件,尤拉物件)轉換成四元數,應用四元數變換. /// 實際上就是呼叫四元數下的.setFromEuler()方法. */ ///<summary>applyEuler</summary> ///<param name ="euler" type="THREE.Euler">THREE.Euler物件,尤拉物件</param> ///<returns type="Vector3">返回變換後的三維向量</returns> applyEuler: function () { var quaternion; return function ( euler ) { if ( euler instanceof THREE.Euler === false ) { console.error( 'THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.' ); } if ( quaternion === undefined ) quaternion = new THREE.Quaternion(); this.applyQuaternion( quaternion.setFromEuler( euler ) ); return this; //返回變換後的三維向量 }; }(), /* ///applyMatrix3方法將當前向量根據指定的軸(一個標準單位的向量),和角度旋轉.或者說根據指定的軸和角度應用旋轉. */ ///<summary>applyMatrix3</summary> ///<param name ="axis" type="Vector3">三維向量</param> ///<param name ="angle" type="Matrix3">3x3矩陣</param> ///<returns type="Vector3">返回變換後的三維向量</returns> applyAxisAngle: function () { var quaternion; return function ( axis, angle ) { if ( quaternion === undefined ) quaternion = new THREE.Quaternion(); this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) ); //實際呼叫的四元數下面的方法.setFromAxisAngle() return this; //返回變換後的三維向量 }; }(), /* ///applyMatrix3方法將當前向量乘以一個3x3的矩陣,引數m(一個Matrix3的矩陣) */ ///<summary>applyMatrix3</summary> ///<param name ="m" type="Matrix3">3x3矩陣</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> applyMatrix3: function ( m ) { var x = this.x; var y = this.y; var z = this.z; var e = m.elements; 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; return this; //返回新座標值的三維向量 }, /* ///applyMatrix4方法乘以該向量和引數m(一個Matrix4投影矩陣)的4x3的子集 */ ///<summary>applyMatrix4</summary> ///<param name ="m" type="Matrix4">仿射矩陣</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> applyMatrix4: function ( m ) { // input: THREE.Matrix4 affine matrix var x = this.x, y = this.y, z = this.z; var e = m.elements; 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 ]; return this; //返回新座標值的三維向量 }, /* ///applyProjection方法乘以該向量和引數m(一個Matrix4投影矩陣),然後除以視角. */ ///<summary>applyProjection</summary> ///<param name ="m" type="Matrix4">投影矩陣</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> applyProjection: function ( m ) { // input: THREE.Matrix4 projection matrix var x = this.x, y = this.y, z = this.z; var e = m.elements; var d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide 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; return this; }, /* ///applyQuaternion方法應用一個四元數變換到當前三維向量. */ ///<summary>applyQuaternion</summary> ///<param name ="q" type="Quaternion">四元數</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> applyQuaternion: function ( q ) { 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; var iw = - qx * x - qy * y - qz * z; // calculate result * inverse quat 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; return this; //返回新座標值的三維向量 }, /* ///transformDirection方法通過引數m(一個Matrix4投射矩陣的3x3子集)轉換這個向量的方向 */ ///<summary>transformDirection</summary> ///<param name ="m" type="Matrix4">仿射矩陣</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> 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; 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; this.normalize(); //返回單位量 return this; //返回新的三維向量 }, /* ///divide方法用來將三維向量的(x,y,z)座標值與引數v的(x,y,z)相除.並返回新的座標值的三維向量. */ ///<summary>divide</summary> ///<param name ="v" type="Vector3">與當前物件(x,y,z)值相除的三維向量</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> divide: function ( v ) { this.x /= v.x; this.y /= v.y; this.z /= v.z; return this; //返回新座標值的三維向量 }, /* ///divideScalar方法用來將三維向量的(x,y,z)座標值直接與引數scalar相除.並返回新的座標值的三維向量. /// NOTE:1. 引數scalar如果為0,當前物件(x,y,z)值直接設定為0!! /// NOTE:2. 這裡與divide()方法不同的是,這裡傳遞的引數scalar是一個標量,而divide()方法的引數v是一個三維向量. */ ///<summary>divideScalar</summary> ///<param name ="scalar" type="number">與當前物件(x,y,z)值相除的標量,數值</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> divideScalar: function ( scalar ) { if ( scalar !== 0 ) { var invScalar = 1 / scalar; //將被除數換算成小數 this.x *= invScalar; this.y *= invScalar; this.z *= invScalar; } else { //引數scalar如果為0,當前物件(x,y,z)值直接設定為0!! this.x = 0; this.y = 0; this.z = 0; } return this; //返回新座標值的三維向量 }, /* ///min方法用來將三維向量的(x,y,z)座標值直接與引數v的(x,y)比較,如果當前三維向量的值大於引數v的(x,y,z), ///將引數v的(x,y,z)賦值給當前向量,並返回(x,y,z)值最小的三維向量. */ ///<summary>min</summary> ///<param name ="v" type="Vector3">與當前物件(x,y)值引數v的(x,y,z)比較,並返回(x,y)值最小的三維向量.</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> min: function ( v ) { if ( this.x > v.x ) { //如果當前三維向量的x值大於引數v.x this.x = v.x; //將引數v的x值賦值給當前向量 } if ( this.y > v.y ) { //如果當前三維向量的y值大於引數v.y this.y = v.y; //將引數v的y值賦值給當前向量 } if ( this.z > v.z ) { //如果當前三維向量的x值大於引數v.z this.z = v.z; //將引數v的z值賦值給當前向量 } return this; //返回新座標值的三維向量 }, /* ///max方法用來將三維向量的(x,y,z)座標值直接與引數v的(x,y,z)比較,如果當前三維向量的值小於引數v的(x,y,z), ///將引數v的(x,y,z)賦值給當前向量,並返回(x,y,z)值最大的三維向量. */ ///<summary>min</summary> ///<param name ="v" type="Vector3">與當前物件(x,y,z)值引數v的(x,y,z)比較,並返回(x,y,z)值最大的三維向量.</param> ///<returns type="Vector3">返回新座標值的三維向量</returns> max: function ( v ) { if ( this.x < v.x ) { //如果當前三維向量的x值小於引數v.x this.x = v.x; //將引數v的x值賦值給當前向量 } if ( this.y < v.y ) { //如果當前三維向量的x值小於引數v.y this.y = v.y; //將引數v的y值賦值給當前向量 } if ( this.z < v.z ) { //如果當前三維向量的x值小於引數v.z this.z = v.z; //將引數v的z值賦值給當前向量 } return this; //返回新座標值的三維向量 }, /* ///clamp方法用來將三維向量的(x,y)座標值直接與引數min,引數max的(x,y,z)比較,如果當前三維向量的值小於引數min的(x,y,z) ///或者大於引數max的(x,y,z),對應的將引數min或max的(x,y,z)賦值給當前三維向量, /// NOTE:保持當前三維向量在min,max所組成的三維空間的之內,最大不超過max的(x,y,z)值,最小不小於min的(x,y,z)值. */ ///<summary>clamp</summary> ///<param name ="min" type="Vector3">三維向量.</param> ///<param name ="max" type="Vector3">三維向量.</param> ///<returns type="Vector2">返回指定界限內的三維向量</returns> clamp: function ( min, max ) { // This function assumes min < max, if this assumption isn't true it will not operate correctly // 這個方法用來獲得三維向量的最小值於最大值,如果沒有獲取到,說明函式執行錯誤. if ( this.x < min.x ) { //如果當前三維向量的x值小於引數min的x值 this.x = min.x; //將引數min的x值賦值給當前向量 } else if ( this.x > max.x ) { //如果當前三維向量的x值大於引數max的x值 this.x = max.x; //將引數max的x值賦值給當前向量 } if ( this.y < min.y ) { //如果當前三維向量的x值小於引數min的y值 this.y = min.y; //將引數min的y值賦值給當前向量 } else if ( this.y > max.y ) { //如果當前三維向量的y值大於引數max的y值 this.y = max.y; //將引數max的y值賦值給當前向量 } if ( this.z < min.z ) { //如果當前三維向量的x值小於引數min的z值 this.z = min.z; //將引數min的z值賦值給當前向量 } else if ( this.z > max.z ) { //如果當前三維向量的x值大於引數max的z值 this.z = max.z; //將引數max的z值賦值給當前向量 } return this; //返回指定界限內的三維向量 }, /* ///clampScalar方法用來將三維向量的(x,y)座標值直接與引數minVal,引數maxVal比較,如果當前三維向量的值小於引數minVal ///或者大於引數maxVal,將引數minVal或maxVal賦值給當前三維向量, /// NOTE: 1. 保持當前三維向量在minVal,maxVal所組成的三維空間的之內,最大不超過maxVal值,最小不小於minVal值. /// NOTE: 2. 這裡與clamp()方法不同的是,這裡傳遞的引數minVal,maxVal是一個標量,而clamp()方法的引數min,引數max是兩個三維向量. */ ///<summary>clampScalar</summary> ///<param name ="minVal" type="number">下限.</param> ///<param name ="maxVal" type="number">上限.</param> ///<returns type="Vector3">返回指定界限內的三維向量</returns> clampScalar: ( function () { //外側括號是一種特殊的用法,似乎代表立即執行.小白,請見諒! var min, max; return function ( minVal, maxVal ) { //建立匿名函式 if ( min === undefined ) { min = new THREE.Vector3(); max = new THREE.Vector3(); } min.set( minVal, minVal, minVal ); max.set( maxVal, maxVal, maxVal ); return this.clamp( min, max ); //呼叫clamp()方法,返回指定界限內的三維向量 }; } )(), /* ///floor方法用來返回小於或等於三維向量的(x,y,z)座標值的最大整數 /// NOTE:去掉小數部分 */ ///<summary>floor</summary> ///<returns type="Vector3">返回圓整後的三維向量</returns> floor: function () { this.x = Math.floor( this.x ); this.y = Math.floor( this.y ); this.z = Math.floor( this.z ); return this; //返回圓整後的三維向量 }, /* ///ceil方法用來返回大於或等於三維向量的(x,y,z)座標值的最小整數 /// NOTE:將小數部分去掉加1. */ ///<summary>ceil</summary> ///<returns type="Vector3">返回圓整後的三維向量</returns> ceil: function () { this.x = Math.ceil( this.x ); this.y = Math.ceil( this.y ); this.z = Math.ceil( this.z ); return this; //返回圓整後的三維向量 }, /* ///round方法用來返回最接近三維向量的(x,y,z)座標值的整數 /// NOTE:也就是四捨五入 */ ///<summary>round</summary> ///<returns type="Vector3">返回圓整後的三維向量</returns> round: function () { this.x = Math.round( this.x ); this.y = Math.round( this.y ); this.z = Math.round( this.z ); return this; //返回圓整後的三維向量 }, /* ///roundToZero方法將當前三維向量的(x,y,z)座標值若為負數時,返回大於或等於三維向量的(x,y,z)座標值的最小整數 /// 而當前三維向量的(x,y,z)座標值若為正數時,返回小於或等於三維向量的(x,y,z)座標值的最大整數 */ ///<summary>roundToZero</summary> ///<returns type="Vector3">返回圓整後的三維向量</returns> 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 ); return this; //返回圓整後的三維向量 }, /* ///negate方法將當前三維向量的(x,y,z)座標值若為負數時,返回正數. /// 而當前三維向量的(x,y,z)座標值若為正數時,返回負數. /// NOTE:取當前三維向量的(x,y,z)座標值相反數 */ ///<summary>negate</summary> ///<returns type="Vector3">返回取相反數後的三維向量</returns> negate: function () { this.x = - this.x; this.y = - this.y; this.z = - this.z; return this; //返回取相反數後的三維向量 }, /* ///dot方法將返回兩個向量的點乘積(點乘,數量積). /// NOTE:1. 關於點積的介紹參考維基百科:http://zh.wikipedia.org/wiki/%E6%95%B0%E9%87%8F%E7%A7%AF, 常用來進行方向性判斷,如兩向量點積大於0,則它們的方向朝向相近;如果小於0,則方向相反。 /// NOTE:2. Vector3.Dot也叫點積,它返回1個-1.0~1.0之間的一個值。網上確實也這麼說。但是這個值表示什麼呢?恩,表示返回進行Dot計算的兩個向量之間的夾角的餘弦值(Cos弧度角).要注意的是能進行Dot計算的前提是兩個向量首先要變成單位向量! */ ///<summary>dot</summary> ///<param name ="v" type="Vector3">三維向量</param> ///<returns type="number">返回點乘積(點乘,數量積)</returns> dot: function ( v ) { return this.x * v.x + this.y * v.y + this.z * v.z; //返回點乘積(點乘,數量積) }, /* ///lengthSq方法將返回這個三維向量的長度的平方(只讀). /// NOTE:勾股定理a^2 + b^2 +c^2= d^2,這裡返回的是d^2. */ ///<summary>lengthSq</summary> ///<returns type="number">返回三維向量的長度的平方(只讀)</returns> lengthSq: function () { return this.x * this.x + this.y * this.y + this.z * this.z; //返回三維向量的長度的平方(只讀) }, /* ///length方法將返回三維向量的長度(只讀). /// NOTE:勾股定理a^2 + b^2 + c^2=d^2,d=Math.sqrt(a^2 + b^2+c^2),這裡返回的是d. */ ///<summary>length</summary> ///<returns type="number">返回三維向量的長度(只讀)</returns> length: function () { return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); //返回三維向量的長度(只讀) }, /* ///lengthManhattan方法將返回三維向量(x,y,z)值的和(只讀). ///曼哈頓距離——兩點在南北方向上的距離加上在東西方向上的距離,即d(i,j)=|xi-xj|+|yi-yj|。對於一個具有 ///正南正北、正東正西方向規則佈局的城鎮街道,從一點到達另一點的距離正是在南北方向上旅行的距離加上在東西方向 ///上旅行的距離,因此曼哈頓距離又稱為計程車距離,曼哈頓距離不是距離不變數,當座標軸變動時,點間的距離就會不同。 ///維基百科上的內容:http://zh.wikipedia.org/zh/%E6%9B%BC%E5%93%88%E9%A0%93%E8%B7%9D%E9%9B%A2 /// NOTE:曼哈頓距離,this.x + this.y + this.z. /// TODO:曼哈頓距離,這個功能應該二維向量中增加這個方法呀?計算路徑的時候很常用呀. */ ///<summary>lengthManhattan</summary> ///<returns type="number">返回三維向量的長度(只讀)</returns> lengthManhattan: function () { return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); }, /* ///normalize方法將返回向量的長度為1(只讀). /// 複習一下初中的幾何吧,三角恆等式,給你準備好了 :) ,見維基百科: /// http://zh.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E5%87%BD%E6%95%B0#.E4.B8.89.E8.A7.92.E6.81.92.E7.AD.89.E5.BC.8F */ ///<summary>normalize</summary> ///<returns type="number">返回三維向量(x,y,z)值的和(只讀)</returns> normalize: function () { return this.divideScalar( this.length() ); //返回三維向量(x,y,z)值的和(只讀) }, /* ///setLength方法用來按照引數l(長度)設定新的三維向量(x,y,z)值. /// NOTE:將以原點到當前向量的線段等比例縮放到引數l所指定的長度. */ ///<summary>setLength</summary> ///<param name ="l" type="number">指定的長度</param> ///<returns type="Vector3">返回按照引數l(長度)設定新的三維向量(x,y,z)值.</returns> setLength: function ( l ) { var oldLength = this.length(); if ( oldLength !== 0 && l !== oldLength ) { //做個判斷,如果原長度與新長度不相等,並且原長度不為0. this.multiplyScalar( l / oldLength ); //呼叫.multiplyScalar()方法,傳遞新長度與原長度的比. } return this; //返回按照引數l(長度)設定新的三維向量(x,y,z)值. }, /*lerp方法 ///lerp方法在將當前三維向量(x,y,z)設定為下限和引數v(x,y,z)設為上限 之間進行線性插值, /// alpha 表示權值。從下限當前三維向量(x,y,z)到上限引數v(x,y,z)乘以百分比alpha(0.0-1.0),加上當前三維向量(x,y,z) ///當前二維向量(x,y,z)的和賦值給當前三維向量(x,y,z),返回當前三維向量(x,y,z). /// NOTE:注意,如果 當前三維向量(x,y,z) 和 引數v(x,y,z)是向量,則權值 alpha 必須是標量,取值範圍是0.0-1.0. */ ///<summary>lerp</summary> ///<param name ="v" type="Vector3">三維向量</param> ///<param name ="alpha" type="number">百分比權值(0.0-1.0)</param> ///<returns type="Vector3">三維向量</returns> lerp: 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; //返回三維向量 }, /*cross方法 ///cross方法將返回兩個交叉乘積,呼叫者本身與v的叉乘。叉乘是一個向量,垂直於參與叉乘的兩個向量並呈右手螺旋法則。 /// 返回為同時垂直於兩個引數向量的向量,方向可朝上也可朝下,由兩向量夾角的方向決定。 /// NOTE:藉助右手定則輔助判斷方向。 /// 叉乘是一種在向量空間中向量的二元運算。與點乘不同,它的運算結果是一個偽向量而不是一個標量。 /// 叉乘的運算結果叫叉積(即交叉乘積)、外積或向量積。叉積與原來的兩個向量都垂直。 1、理論知識 數學上的定義:c=axb【注:粗體小寫字母表示向量】其中a,b,c均為向量。即兩個向量的叉積得到的還是向量! 性質1:c⊥a,c⊥b,即向量c垂直與向量a,b所在的平面。 性質2:模長|c|=|a||b|sin<a,b> 性質3:滿足右手法則。從這點我們有axb ≠ bxa,而axb = - bxa。所以我們可以使用叉積的正負值來判斷向量a,b的相對 位置,即向量b是處於向量a的順時針方向還是逆時針方向。 */ ///<summary>cross</summary> ///<param name ="v" type="Vector3">三維向量</param> ///<param name ="w" type="Vector3">三維向量</param> ///<returns type="Vector3">三維向量</returns> cross: function ( v, w ) { if ( w !== undefined ) { console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); return this.crossVectors( v, w ); //如果存在第二個引數,將呼叫.crossVectors()方法. } var x = this.x, y = this.y, z = this.z; this.x = y * v.z - z * v.y; this.y = z * v.x - x * v.z; this.z = x * v.y - y * v.x; return this; //返回三維向量 }, /*crossVectors方法 ///crossVectors方法將返回兩個交叉乘積,呼叫者變為a,b的叉乘。叉乘是一個向量,垂直於參與叉乘的兩個向量並呈右手螺旋法則。 /// 返回為同時垂直於兩個引數向量的向量,方向可朝上也可朝下,由兩向量夾角的方向決定。 /// NOTE:藉助右手定則輔助判斷方向。參考:http://zh.wikipedia.org/zh/%E5%90%91%E9%87%8F%E7%A7%AF /// 叉乘是一種在向量空間中向量的二元運算。與點乘不同,它的運算結果是一個偽向量而不是一個標量。 /// 叉乘的運算結果叫叉積(即交叉乘積)、外積或向量積。叉積與原來的兩個向量都垂直。 1、理論知識 數學上的定義:c=axb【注:粗體小寫字母表示向量】其中a,b,c均為向量。即兩個向量的叉積得到的還是向量! 性質1:c⊥a,c⊥b,即向量c垂直與向量a,b所在的平面。 性質2:模長|c|=|a||b|sin<a,b> 性質3:滿足右手法則。從這點我們有axb ≠ bxa,而axb = - bxa。所以我們可以使用叉積的正負值來判斷向量a,b的相對位置, 即向量b是處於向量a的順時針方向還是逆時針方向。 */ ///<summary>crossVectors</summary> ///<param name ="a" type="Vector3">三維向量</param> ///<param name ="b" type="Vector3">三維向量</param> ///<returns type="Vector3">三維向量</returns> crossVectors: function ( a, b ) { 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; return this; //返回三維向量 }, /*projectOnVector方法 ///projectOnVector方法在將當前三維向量(x,y,z)投影一個向量到另一個向量,引數vector(x,y,z). /// NOTE:進行Dot計算的前提是兩個向量首先要變成單位向量,這裡通過呼叫.normalize()得到單位向量. */ ///<summary>projectOnVector</summary> ///<param name ="vector" type="Vector3">三維向量</param> ///<returns type="Vector3">三維向量</returns> projectOnVector: function () { var v1, dot; return function ( vector ) { if ( v1 === undefined ) v1 = new THREE.Vector3(); v1.copy( vector ).normalize(); //NOTE:進行Dot計算的前提是兩個向量首先要變成單位向量,這裡通過呼叫.normalize()得到單位向量. dot = this.dot( v1 ); //dot常用來進行方向性判斷,如兩向量點積大於0,則它們的方向朝向相近;如果小於0,則方向相反。 return this.copy( v1 ).multiplyScalar( dot ); //投影一個向量到另一個向量。 }; }(), /*projectOnPlane方法 ///projectOnPlane方法在將當前三維向量(x,y,z)投影一個向量到一個平面(用一個向量表示,引數planeNormal(x,y,z)),然後當前向量減去 ///從這個向量到這個向量到平面法線的投影. */ ///<summary>projectOnPlane</summary> ///<param name ="planeNormal" type="Vector3">三維向量</param> ///<returns type="Vector3">三維向量</returns> projectOnPlane: function () { var v1; return function ( planeNormal ) { if ( v1 === undefined ) v1 = new THREE.Vector3(); v1.copy( this ).projectOnVector( planeNormal ); //呼叫.projectVector方法. return this.sub( v1 ); } }(), /*reflect方法 ///reflect方法沿著法線(引數normal)反射向量. /// NOTE:reflect方法其實就是對一個向量進行映象. */ ///<summary>reflect</summary> ///<param name ="normal" type="Vector3">三維向量</param> ///<returns type="Vector3">返回一個反射過後的向量.</returns> 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 ) ) ); //返回一個反射過後的向量. } }(), /*angleTo方法 ///angleTo方法返回當前向量與另一個向量的夾角. */ ///<summary>angleTo</summary> ///<param name ="v" type="Vector3">三維向量</param> ///<returns type="number">返回當前向量與另一個向量的夾角</returns> angleTo: function ( v ) { var theta = this.dot( v ) / ( this.length() * v.length() ); // clamp, to handle numerical problems return Math.acos( THREE.Math.clamp( theta, - 1, 1 ) ); //返回當前向量與另一個向量的 }, /* ///distanceTo方法將返回當前三維向量到引數v的距離(只讀). */ ///<summary>distanceTo</summary> ///<param name ="v" type="Vector3">三維向量</param> ///<returns type="Vector3">返回當前三維向量到引數v的距離(只讀).</returns> distanceTo: function ( v ) { return Math.sqrt( this.distanceToSquared( v ) ); //返回當前三維向量到引數v的距離(只讀). }, /* ///distanceToSquared方法將返回當前三維向量到引數v的距離的點積(點乘,數量積)(只讀). /// NOTE:關於點積的介紹參考維基百科:http://zh.wikipedia.org/wiki/%E6%95%B0%E9%87%8F%E7%A7%AF */ ///<summary>distanceToSquared</summary> ///<param name ="v" type="Vector3">三維向量</param> ///<returns type="Vector3">返回當前三維向量到引數v的距離的點積(點乘,數量積)(只讀)</returns> distanceToSquared: function ( v ) { var dx = this.x - v.x; var dy = this.y - v.y; var dz = this.z - v.z; return dx * dx + dy * dy + dz * dz; //當前三維向量到引數v的距離的點積(點乘,數量積)(只讀). }, /// NOTE:setEulerFromRotationMatrix()方法已經刪除,使用Euler.setFromRotationMatrix()替換,此處保留函式為了向下相容. setEulerFromRotationMatrix: function ( m, order ) { console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); }, /// NOTE:setEulerFromQuaternion()方法已經刪除,使用Euler.setFromQuaternion()替換,此處保留函式為了向下相容. setEulerFromQuaternion: function ( q, order ) { console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); }, /* ///getPositionFromMatrix方法將返回從矩陣中的元素得到的新的向量值的向量. /// NOTE:getPositionFromMatrix()方法已經刪除,使用.setFromMatrixPosition()替換,此處保留函式為了向下相容. */ ///<summary>getPositionFromMatrix</summary> ///<param name ="m" type="Matrix">矩陣</param> ///<returns type="Vector3">返回三維向量</returns> getPositionFromMatrix: function ( m ) { console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); return this.setFromMatrixPosition( m ); //返回三維向量 }, /* ///getScaleFromMatrix方法將返回從矩陣中的元素的長度賦值給當前向量. /// NOTE:getScaleFromMatrix()方法已經刪除,使用.setFromMatrixScale()替換,此處保留函式為了向下相容. */ ///<summary>getScaleFromMatrix</summary> ///<param name ="m" type="Matrix">矩陣</param> ///<returns type="Vector3">返回三維向量</returns> getScaleFromMatrix: function ( m ) { console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); return this.setFromMatrixScale( m ); //返回三維向量 }, /* ///getColumnFromMatrix方法將矩陣指定的列中的元素的向量值賦值給給當前的向量. /// NOTE:getColumnFromMatrix()方法已經刪除,使用.setFromMatrixColumn()替換,此處保留函式為了向下相容. */ ///<summary>getColumnFromMatrix</summary> ///<param name ="index" type="number">列數,列的下標.</param> ///<param name ="matrix" type="Matrix">矩陣</param> ///<returns type="Vector3">返回三維向量</returns> getColumnFromMatrix: function ( index, matrix ) { console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); return this.setFromMatrixColumn( index, matrix ); //返回三維向量 }, /* ///setFromMatrixPosition方法將返回從矩陣中的元素得到的新的向量值的向量. */ ///<summary>setFromMatrixPosition</summary> ///<param name ="m" type="Matrix">矩陣</param> ///<returns type="Vector3">返回三維向量</returns> setFromMatrixPosition: function ( m ) { this.x = m.elements[ 12 ]; this.y = m.elements[ 13 ]; this.z = m.elements[ 14 ]; return this; //返回三維向量 }, /* ///setFromMatrixScale方法將返回從矩陣中的元素的長度賦值給當前向量. */ ///<summary>setFromMatrixScale</summary> ///<param name ="m" type="Matrix">矩陣</param> ///<returns type="Vector3">返回三維向量</returns> 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(); this.x = sx; this.y = sy; this.z = sz; return this; //返回三維向量 }, /* ///setFromMatrixColumn方法將矩陣指定的列中的元素的向量值賦值給給當前的向量. */ ///<summary>setFromMatrixColumn</summary> ///<param name ="index" type="number">列數,列的下標.</param> ///<param name ="matrix" type="Matrix">矩陣</param> ///<returns type="Vector3">返回三維向量</returns> setFromMatrixColumn: function ( index, matrix ) { var offset = index * 4; var me = matrix.elements; this.x = me[ offset ]; this.y = me[ offset + 1 ]; this.z = me[ offset + 2 ]; return this; //返回三維向量 }, /*equals方法 ///equals方法相當於比較運算子===,將當前三維向量和引數v中的(x,y,z)值進行對比,返回bool型值. */ ///<summary>equals</summary> ///<param name ="v" type="Vector3">三維向量(x,y,z)</param> ///<returns type="bool">返回true or false</returns equals: function ( v ) { return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); //返回true or false }, /*fromArray方法 ///fromArray方法將儲存三維向量(x,y)值的陣列賦值給當前三維向量物件 */ ///<summary>fromArray</summary> ///<param name ="array" type="Array">三維向量(x,y,z)值陣列array[x,y,z]</param> ///<returns type="Vector3">返回新的三維向量</returns> fromArray: function ( array ) { this.x = array[ 0 ]; this.y = array[ 1 ]; this.z = array[ 2 ]; return this; //返回新的三維向量 }, /*toArray方法 ///toArray方法將當前三維向量物件的屬性賦值給陣列array[0.5,0.5,0.5].返回一個數組物件. */ ///<summary>toArray</summary> ///<returns type="Array">三維向量(x,y,z)值陣列array[x,y,z]</returns> toArray: function () { return [ this.x, this.y, this.z ]; //三維向量(x,y)值陣列array[x,y] }, /*clone方法 ///clone方法克隆一個三維向量物件. */ ///<summary>clone</summary> ///<returns type="Vector3">返回三維向量物件</returns> clone: function () { return new THREE.Vector3( this.x, this.y, this.z ); //返回三維向量 } };