three.js 源代码凝视(七)Math/Euler.js

商域无疆 (http://blog.csdn.net/omni360/)

本文遵循“署名-非商业用途-保持一致”创作公用协议

转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化、GOLANG、Html5、WEBGL、THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。

下面代码是THREE.JS 源代码文件里Math/Quaternion.js文件的凝视.

很多其它更新在 : https://github.com/omni360/three.js.sourcecode/blob/master/Three.js

// File:src/math/Euler.js

/**
 * @author mrdoob / http://mrdoob.com/
 * @author WestLangley / http://github.com/WestLangley
 * @author bhouston / http://exocortex.com
 */
/*
///Euler对象的构造函数.用来创建一个欧拉角的对象.Euler对象的功能函数採用
///定义构造的函数原型对象来实现.
///
///	使用方法: var euler = new Euler(5,3,2,'XYZ')
///	创建一个绕某轴旋转5度,绕y轴旋转某度,绕某轴旋转2度,旋转顺序为'XYZ'.有了旋转顺序才干确定每一个x,y,z轴分别旋转多少度.
///	NOTE: 參数x,y,z代表3个轴的旋转角度,具体哪个轴旋转多少度,须要后面的參数(order)旋转顺序来确定.
///	NOTE: 參数(x,y,z,order)为可选參数,假设不指定參数(x,y,z,order),将创建一个坐标为(0,0,0,'XYZ')的Eular(欧拉角)对象.
/// NOTE: 參数order(旋转顺序) 默认顺序是'XYZ' 取值范围是['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]
///
/// 通俗的讲,欧拉角就是用来描写叙述一个物体在三维空间中方向的一种经常使用的方法.举例来说,一个物体在三维空间中,绕x轴转了多少度,
///	y轴转了多少度,z轴转了多少度,来描写叙述物体在三维空间中的方向.
/// 有点相似香港电影里飞虎队队员之间说,"飞鹰,飞鹰,在你的正前方,5点钟方向,发现目标,准备聚集目标."
///
*/
///<summary>Euler</summary>
///<param name ="x" type="number">绕某轴旋转x度</param>
///<param name ="y" type="number">绕某轴旋转y度</param>
///<param name ="z" type="number">绕某轴旋转z度</param>
///<param name ="order" type="String">order(旋转顺序) 默认顺序是'XYZ' 取值范围是['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]</param>

THREE.Euler = function ( x, y, z, order ) {

	this._x = x || 0;
	this._y = y || 0;
	this._z = z || 0;
	this._order = order || THREE.Euler.DefaultOrder;

};

THREE.Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];	//(旋转顺序) 默认顺序是'XYZ' 取值范围是['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]

THREE.Euler.DefaultOrder = 'XYZ';	//默认的旋转顺序为'XYZ'

/****************************************
****以下是Euler对象提供的功能函数.
****************************************/

THREE.Euler.prototype = {

	constructor: THREE.Euler, //构造器

	_x: 0, _y: 0, _z: 0, _order: THREE.Euler.DefaultOrder,	//将(_x,_y,_z,_order)初始化x,y,z为0,旋转顺序为默认旋转顺序'XYZ';

	/*
	///get x 方法用来获取euler角x值.
	///NOTE: get x()的使用方法是Euler.prototype.x(Euler.x),这样的使用方法在除ie浏览器以外的浏览器上能够使用.
	*/
	///<summary>get x</summary>
	///<returns type="number">返回euler角_x值</returns>
	get x () {

		return this._x;	//返回euler角_x值

	},

	/*
	///set x 方法用来从新设置Euler角的x值.并返回新的值的Euler角.
	///NOTE: set x()的使用方法是Euler.prototype.x=value(Euler.x = value),这样的使用方法在除ie浏览器以外的浏览器上能够使用.
	*/
	///<summary>set x</summary>
	///<param name ="value" type="number">绕x轴旋转的角度值</param>
	set x ( value ) {

		this._x = value;	//设置Euler角的_x值
		this.onChangeCallback(); //调用回调函数.

	},

	/*
	///get y 方法用来从获取euler角y值.
	///NOTE: get y()的使用方法是Euler.prototype.y(Euler.y),这样的使用方法在除ie浏览器以外的浏览器上能够使用.
	*/
	///<summary>get y</summary>
	///<returns type="number">返回euler角_y值</returns>
	get y () {

		return this._y;	//返回euler角_y值

	},

	/*
	///set y 方法用来从新设置Euler角的y值.并返回新的值的Euler角.
	///NOTE: set y()的使用方法是Euler.prototype.y=value(Euler.y = value),这样的使用方法在除ie浏览器以外的浏览器上能够使用.
	*/
	///<summary>set y</summary>
	///<param name ="value" type="number">绕y轴旋转的角度值</param>
	set y ( value ) {

		this._y = value;	//设置Euler角的_y值
		this.onChangeCallback(); //调用回调函数.

	},

	/*
	///get z 方法用来获取euler角z值.
	///NOTE: get z()的使用方法是Euler.prototype.z(Euler.z),这样的使用方法在除ie浏览器以外的浏览器上能够使用.
	*/
	///<summary>get z</summary>
	///<returns type="number">返回euler角_z值</returns>
	get z () {

		return this._z;	//返回euler角_z值

	},

	/*
	///set z 方法用来从新设置Euler角的z值.并返回新的值的Euler角.
	///NOTE: set z()的使用方法是Euler.prototype.z=value(Euler.z = value),这样的使用方法在除ie浏览器以外的浏览器上能够使用.
	*/
	///<summary>set z</summary>
	///<param name ="value" type="number">绕z轴旋转的角度值</param>
	set z ( value ) {

		this._z = value;	//设置Euler角的_z值
		this.onChangeCallback(); //调用回调函数.

	},

	/*
	///get order 方法用来获取euler角order值.
	///NOTE: get order()的使用方法是Euler.prototype.order(Euler.order),这样的使用方法在除ie浏览器以外的浏览器上能够使用.
	*/
	///<summary>get order</summary>
	///<returns type="number">返回euler角_z值</returns>
	get order () {

		return this._order;	//返回euler角_order值

	},

	/*
	///set order 方法用来从新设置Euler角的order值.并返回新的值的Euler角.
	///NOTE: set order()的使用方法是Euler.prototype.order=value(Euler.order = value),这样的使用方法在除ie浏览器以外的浏览器上能够使用.
	///	NOTE: 參数(x,y,z,order)为可选參数,假设不指定參数(x,y,z,order),将创建一个坐标为(0,0,0,'XYZ')的Eular(欧拉角)对象.
	/// NOTE: 參数order(旋转顺序) 默认顺序是'XYZ' 取值范围是['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]
	*/
	///<summary>set order</summary>
	///<param name ="value" type="number">绕z轴旋转的角度值</param>
	set order ( value ) {

		this._order = value;	  	//设置Euler角的_order值
		this.onChangeCallback();	 //调用回调函数.

	},

	///TODO:这里缺少setX()方法.
	///TODO:这里缺少setY()方法.
	///TODO:这里缺少setZ()方法.
	///TODO:这里缺少setW()方法.
	///TODO:这里缺少setComponent()方法.
	///TODO:这里缺少getComponent()方法.

	/*
	///set方法用来从新设置Euler(欧拉角)的x,y,z,order值.并返回新的坐标值的Euler(欧拉角).
	/// TODO:改动set方法,兼容x,y,z,order參数省略支持多态.
	*/
	///<summary>set</summary>
	///<param name ="x" type="number">绕某轴旋转x度</param>
	///<param name ="y" type="number">绕某轴旋转y度</param>
	///<param name ="z" type="number">绕某轴旋转z度</param>
	///<param name ="order" type="number">order(旋转顺序) 默认顺序是'XYZ' 取值范围是['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]</param>
	///<returns type="Euler(欧拉角)">返回新的Euler(欧拉角)</returns>
	set: function ( x, y, z, order ) {

		this._x = x;
		this._y = y;
		this._z = z;
		this._order = order || this._order;

		this.onChangeCallback();	//调用回调函数.

		return this;	//返回新的Euler(欧拉角)

	},

	/*
	///copy方法用来复制Euler(欧拉角)的(x,y,z,order)值.并返回新的Euler(欧拉角).
	*/
	///<summary>copy</summary>
	///<param name ="euler(欧拉角)" type="Quaternion">Euler(欧拉角)</param>
	///<returns type="Euler(欧拉角)">返回新的Euler(欧拉角)</returns>
	copy: function ( euler ) {

		this._x = euler._x;
		this._y = euler._y;
		this._z = euler._z;
		this._order = euler._order;

		this.onChangeCallback();	//调用回调函数.

		return this;	//返回新的Euler(欧拉角)

	},

	/*
	///setFromRotationMatrix方法利用一个參数m(旋转矩阵),达到旋转变换的目的吧.
	/// NOTE:m是一个旋转矩阵,很多其它公式:http://en.wikipedia.org/wiki/Transformation_matrix
	///
	/// 例子:

		这个例子是z轴旋转30度.

					/----------------------------------------------------					|cos(heading) = 0.866	| sin(heading) = 0.5   | 0	 |
					|-----------------------|----------------------------|
		matrix =	|-sin(heading) = -0.5   |cos(heading) = 0.866  | 0   |
					|-----------------------|----------------------|-----|
					|     0                 |     0                | 1   |
					\----------------------------------------------------/

		angle = acos ( ( m00 + m11 + m22 - 1)/2)

		angle = acos ( ( 0.866 + 0.866 + 1 - 1)/2)

		angle = acos ( 0.866 )

		angle = 30 degrees

		x = (m21 - m12) = 0 - 0 =0
		y = (m02 - m20) = 0 - 0 =0
		z = (m10 - m01) = -0.5 - 0.5 = -1

	*/
	///<summary>setFromRotationMatrix</summary>
	///<param name ="m" type="Matrix3">3x3矩阵(旋转矩阵)</param>
	///<param name ="order" type="String">order(旋转顺序) 默认顺序是'XYZ' 取值范围是['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]</param>
	///<returns type="Euler(欧拉角)">返回新的Euler(欧拉角)</returns>
	setFromRotationMatrix: function ( m, order ) {

		var clamp = THREE.Math.clamp;	//clamp用来设置数值的取值范围

		// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
		// 确保參数m是一个3x3的旋转矩阵.

		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 ];

		order = order || this._order;

		if ( order === 'XYZ' ) {

			this._y = Math.asin( clamp( m13, - 1, 1 ) );

			if ( Math.abs( m13 ) < 0.99999 ) {

				this._x = Math.atan2( - m23, m33 );
				this._z = Math.atan2( - m12, m11 );

			} else {

				this._x = Math.atan2( m32, m22 );
				this._z = 0;

			}

		} else if ( order === 'YXZ' ) {

			this._x = Math.asin( - clamp( m23, - 1, 1 ) );

			if ( Math.abs( m23 ) < 0.99999 ) {

				this._y = Math.atan2( m13, m33 );
				this._z = Math.atan2( m21, m22 );

			} else {

				this._y = Math.atan2( - m31, m11 );
				this._z = 0;

			}

		} else if ( order === 'ZXY' ) {

			this._x = Math.asin( clamp( m32, - 1, 1 ) );

			if ( Math.abs( m32 ) < 0.99999 ) {

				this._y = Math.atan2( - m31, m33 );
				this._z = Math.atan2( - m12, m22 );

			} else {

				this._y = 0;
				this._z = Math.atan2( m21, m11 );

			}

		} else if ( order === 'ZYX' ) {

			this._y = Math.asin( - clamp( m31, - 1, 1 ) );

			if ( Math.abs( m31 ) < 0.99999 ) {

				this._x = Math.atan2( m32, m33 );
				this._z = Math.atan2( m21, m11 );

			} else {

				this._x = 0;
				this._z = Math.atan2( - m12, m22 );

			}

		} else if ( order === 'YZX' ) {

			this._z = Math.asin( clamp( m21, - 1, 1 ) );

			if ( Math.abs( m21 ) < 0.99999 ) {

				this._x = Math.atan2( - m23, m22 );
				this._y = Math.atan2( - m31, m11 );

			} else {

				this._x = 0;
				this._y = Math.atan2( m13, m33 );

			}

		} else if ( order === 'XZY' ) {

			this._z = Math.asin( - clamp( m12, - 1, 1 ) );

			if ( Math.abs( m12 ) < 0.99999 ) {

				this._x = Math.atan2( m32, m22 );
				this._y = Math.atan2( m13, m11 );

			} else {

				this._x = Math.atan2( - m23, m33 );
				this._y = 0;

			}

		} else {

			console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order )	//通过依照以上几种旋转顺序设置欧拉角对象失败报错

		}

		this._order = order;	//又一次设置旋转顺序

		this.onChangeCallback();	//调用回调函数.

		return this;	//返回新的Euler(欧拉角)

	},

	/*
	///setFromQuaternion方法通过四元数设置Euler(欧拉角).
	/// NOTE:參数(q)必须是单位向量,通过调用.normalize()得到单位向量.
	/// NOTE:參数update是一个可选參数.假设不设置默觉得true.
	*/
	///<summary>setFromQuaternion</summary>
	///<param name ="q" type="Quaternion">四元数</param>
	///<param name ="order" type="String">旋转顺序</param>
	///<param name ="update" type="bool">update表示是否调用回调函数bool型标记值</param>
	///<returns type="Euler(欧拉角)">返回新的Euler(欧拉角)</returns>
	setFromQuaternion: function ( q, order, update ) {

		var clamp = THREE.Math.clamp;	//clamp用来设置数值的取值范围

		// q is assumed to be normalized
		// 确保q是一个单位向量

		// 以下网址是对四元数转换成欧拉角的一个具体的介绍.里面有好多的数学算法.
		// http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m

		var sqx = q.x * q.x;
		var sqy = q.y * q.y;
		var sqz = q.z * q.z;
		var sqw = q.w * q.w;

		order = order || this._order;

		if ( 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 ), - 1, 1 ) );
			this._z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw + sqx - sqy - sqz ) );

		} else if ( order ===  'YXZ' ) {

			this._x = Math.asin(  clamp( 2 * ( q.x * q.w - q.y * q.z ), - 1, 1 ) );
			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 ) );

		} else if ( order === 'ZXY' ) {

			this._x = Math.asin(  clamp( 2 * ( q.x * q.w + q.y * q.z ), - 1, 1 ) );
			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 ) );

		} else if ( order === 'ZYX' ) {

			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 ), - 1, 1 ) );
			this._z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw + sqx - sqy - sqz ) );

		} else if ( order === 'YZX' ) {

			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 ), - 1, 1 ) );

		} else if ( order === 'XZY' ) {

			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 ), - 1, 1 ) );

		} else {

			console.warn( 'THREE.Euler: .setFromQuaternion() given unsupported order: ' + order )	//通过依照以上几种旋转顺序设置欧拉角对象失败报错

		}

		this._order = order;		//又一次设置旋转顺序

		if ( update !== false ) this.onChangeCallback();	//通过update參数推断是否调用回调函数.

		return this;	//返回新的Euler(欧拉角)

	},

	/*
	///reorder方法通过四元数设置Euler(欧拉角)的旋转顺序.
	/// NOTE:參数(q)必须是单位向量,通过调用.normalize()得到单位向量.
	/// WARNING: reorder 方法将丢弃Euler(欧拉角)的旋转顺序信息.
	*/
	///<summary>reorder</summary>
	///<param name ="order" type="String">旋转顺序</param>
	///<returns type="Euler(欧拉角)">返回新的Euler(欧拉角)</returns>
	reorder: function () {
		// WARNING: reorder 方法将丢弃Euler(欧拉角)的旋转顺序信息.
		// WARNING: this discards revolution information -bhouston

		var q = new THREE.Quaternion();

		return function ( newOrder ) {

			q.setFromEuler( this );
			this.setFromQuaternion( q, newOrder );	//调用setFromQuaternion()方法,返回新旋转顺序的Euler(欧拉角)

		};

	}(),

	/*equals方法
	///equals方法相当于比較运算符===,将当前Euler(欧拉角)和參数euler中的(x,y,z,order)值进行对照,返回bool型值.
	*/
	///<summary>equals</summary>
	///<param name ="v" type="Euler(欧拉角)">Euler(欧拉角)(x,y,z,order)</param>
	///<returns type="bool">返回true or false</returns>
	equals: function ( euler ) {

		return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );

	},

	/*fromArray方法
	///fromArray方法将存储Euler(欧拉角)(x,y,z,order)值的数组赋值给当前Euler(欧拉角)对象
	/// NOTE:參数order是一个可选參数.假设不设置使用默认的旋转顺序.
	*/
	///<summary>fromArray</summary>
	///<param name ="array" type="Array">Euler(欧拉角)(x,y,z,order)值数组array[x,y,z,order]</param>
	///<returns type="Euler(欧拉角)">返回新的Euler(欧拉角)</returns>
	fromArray: function ( array ) {

		this._x = array[ 0 ];
		this._y = array[ 1 ];
		this._z = array[ 2 ];
		if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];

		this.onChangeCallback();	//调用回调函数.

		return this;	//返回新的Euler(欧拉角)

	},

	/*toArray方法
	///toArray方法将当前Euler(欧拉角)对象的属性赋值给数组array[5,3,2,'XYZ'].返回一个数组对象.
	*/
	///<summary>toArray</summary>
	///<returns type="Array">Euler(欧拉角)(_x,_y,_z,_order)值数组array[x,y,z,order]</returns>
	toArray: function () {

		return [ this._x, this._y, this._z, this._order ];	//返回一个包括x,y,z,order数值的数组,

	},

	/*onChange方法
	///onChange方法在将回调函数表达式作为callback參数传递给onChangeCallback()方法.
	*/
	///<summary>onChange</summary>
	///<param name ="callback" type="function">回调函数</param>
	///<returns type="Euler(欧拉角)">Euler(欧拉角)</returns>
	onChange: function ( callback ) {

		this.onChangeCallback = callback;

		return this;

	},

	/*onChangeCallback方法
	///onChangeCallback方法克隆一个Euler(欧拉角)对象.
	///NOTE:onChangeCallback()方法在这里就是一个空的函数属性,在上面大部分的方法中都调用了onChangeCallback()方法,这是一种非常方便的方法.
	*/
	///<summary>onChangeCallback</summary>
	onChangeCallback: function () {},

	/*clone方法
	///clone方法克隆一个Euler(欧拉角)对象.
	*/
	///<summary>clone</summary>
	///<returns type="Euler(欧拉角)">返回Euler(欧拉角)对象</returns>
	clone: function () {

		return new THREE.Euler( this._x, this._y, this._z, this._order );

	}

};

商域无疆 (http://blog.csdn.net/omni360/)

本文遵循“署名-非商业用途-保持一致”创作公用协议

转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化、GOLANG、Html5、WEBGL、THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。

下面代码是THREE.JS 源代码文件里Math/Quaternion.js文件的凝视.

很多其它更新在 : https://github.com/omni360/three.js.sourcecode/blob/master/Three.js

时间: 2024-11-11 17:20:16

three.js 源代码凝视(七)Math/Euler.js的相关文章

three.js 源代码凝视(九)Math/Matrix4.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 今天把math库中最大的对象Matrix4凝视完了,发现之前好多的凝视理解的不太正确,还有好多的凝视由于马虎,好多小错误.能改的都在github上更新了,只是大概意思,

three.js 源代码凝视(十六)Math/Frustum.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 俺也是刚開始学,好多地儿肯定不正确还请见谅. 下面代码是THREE.JS 源代码文件里Math/Frustum.js文件的凝视. 很多其它更新在 : https://g

three.js 源代码凝视(十)Math/Line3.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 俺也是刚開始学,好多地儿肯定不正确还请见谅. 下面代码是THREE.JS 源代码文件里Math/Line3.js文件的凝视. 很多其它更新在 : https://git

three.js 源码注释(七)Math/Euler.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 以下代码是THREE.JS 源码文件中Math/Quaternion.js文件的注释. 更多更新在 : https://github.com/omni360/three

cube.js 学习(七)cube.js type 以及format 说明

cube.js 对于measure以及dimension 提供了丰富的数据类型,基本满足我们常见应用的开发,同时对于不同类型也提供了 格式化的操作 measure类型 number 格式 purchasesRatio: { sql: `${purchases} / ${count} * 100.0`, type: `number`, format: `percent` } count 格式 numerOfUsers: { type: `count`, // optional drillMembe

three.js 来源目光(十三)Math/Ray.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 俺也是刚開始学,好多地儿肯定不正确还请见谅. 下面代码是THREE.JS 源代码文件里Math/Ray.js文件的凝视. 很多其它更新在 : https://githu

【高德地图API】从零开始学高德JS API(七)——定位方式大揭秘

摘要:关于定位,分为GPS定位和网络定位2种.GPS定位,精度较高,可达到10米,但室内不可用,且超级费电.网络定位,分为wifi定位和基站定位,都是通过获取wifi或者基站信息,然后查询对应的wifi或者基站位置数据库,得到的定位地点.定位数据库可以不断完善不断补充,所以,越定位越准确.本文详细描述了,如果使用高德JS API来实现位置定位.城市定位的方法,包含了IP定位,浏览器定位,检索定位等多种网络定位方法.当然,如果您的手机有GPS功能,那么使用浏览器定位的时候,会自动获取GPS信息,使

分享:json2.js源代码解读笔记

1. 怎样理解"json" 首先应该意识到,json是一种数据转换格式,既然是个"格式",就是个抽象的东西.它不是js对象,也不是字符串,它仅仅是一种格式,一种规定而已. 这个格式规定了如何将js对象转换成字符串.以及转换成如何的字符串--序列化 -- JSON.stringify 接口: 以及怎样将一个有效字符串转换成js对象--反序列化-- JSON.parse 接口: 2. 关于作者 json作者是 道格拉斯.克劳福德 ,是一位js大牛,写过一本<jav

three.js 源码注释(九)Math/Matrix4.js

商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化.GOLANG.Html5.WEBGL.THREE.JS,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 今天把math库中最大的对象Matrix4注释完了,发现之前好多的注释理解的不太正确,还有好多的注释因为马虎,好多小错误.能改的都在github上更新了,不过大概意思,