天天看點

three.js 源碼注釋(八十三)extras/geometries/TorusKnotGeometry.js

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

本文遵循“署名-非商業用途-保持一緻”創作公用協定

轉載請保留此句:商域無疆 -  本部落格專注于 靈活開發及移動和物聯裝置研究:資料可視化、GOLANG、Html5、WEBGL、THREE.JS,否則,出自本部落格的文章拒絕轉載或再轉載,謝謝合作。

俺也是剛開始學,好多地兒肯定不對還請見諒.

以下代碼是THREE.JS 源碼檔案中extras/geometries/TorusKnotGeometry.js檔案的注釋.

更多更新在 : https://github.com/omni360/three.js.sourcecode

/**
 * @author oosmoxiecode
 * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
 */
/*
///TorusKnotGeometryy用來在三維空間内建立一個圓環結或者環形結對象.是由圓環體通過打結構成的擴充三維幾何體,常用于制作管狀,纏繞.帶囊腫類的造型.
/// 關于環形結的幾何特征,參考:http://en.wikipedia.org/wiki/Torus_knot
/// 各種漂亮的demo:http://katlas.math.toronto.edu/wiki/36_Torus_Knots
///
///	用法: var geometry = new THREE.TorusKnotGeometry(5,32,32);	
/// 	  var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
/// 	  var sphere = new THREE.Mesh(geometry,material);
/// 	  scene.add(sphere);
*/
///<summary>TorusKnotGeometry</summary>
///<param name ="radius" type="float">環形結半徑</param>
///<param name ="tube" type="float">環形結彎管半徑</param>
///<param name ="radialSegments" type="int">環形結圓周上細分線段數</param>
///<param name ="tubularSegments" type="int">環形結彎管圓周上的細分線段數</param>
///<param name ="p" type="float">p\Q:對knot(節)狀方式有效,控制曲線路徑纏繞的圈數,P決定垂直方向的參數.</param>
///<param name ="q" type="float">p\Q:對knot(節)狀方式有效,控制曲線路徑纏繞的圈數,Q決定水準方向的參數.</param>
///<param name ="heightScale" type="float">環形結高方向上的縮放.預設值是1</param>
THREE.TorusKnotGeometry = function ( radius, tube, radialSegments, tubularSegments, p, q, heightScale ) {

	THREE.Geometry.call( this );	//調用Geometry對象的call方法,将原本屬于Geometry的方法交給目前對象TorusKnotGeometry來使用.

	this.parameters = {
		radius: radius,	//環形結半徑
		tube: tube,	//環形結彎管半徑
		radialSegments: radialSegments,	//環形結圓周上細分線段數
		tubularSegments: tubularSegments,	//環形結彎管圓周上的細分線段數
		p: p,	//p\Q:對knot(節)狀方式有效,控制曲線路徑纏繞的圈數,P決定垂直方向的參數.
		q: q,	//p\Q:對knot(節)狀方式有效,控制曲線路徑纏繞的圈數,Q決定水準方向的參數.
		heightScale: heightScale	//環形結高方向上的縮放.預設值是1
	};

	radius = radius || 100;	//環形結半徑,預設初始化為100
	tube = tube || 40;	//環形結彎管半徑,預設初始化為40
	radialSegments = radialSegments || 64;	//環形結圓周上細分線段數,預設初始化為64
	tubularSegments = tubularSegments || 8;	//環形結彎管圓周上的細分線段數,預設初始化為8
	p = p || 2;	//p\Q:對knot(節)狀方式有效,控制曲線路徑纏繞的圈數,P決定垂直方向的參數.預設初始化為2
	q = q || 3;	//p\Q:對knot(節)狀方式有效,控制曲線路徑纏繞的圈數,Q決定水準方向的參數.預設初始化為3
	heightScale = heightScale || 1;	//環形結高方向上的縮放.預設值是1
	
	var grid = new Array( radialSegments );
	var tang = new THREE.Vector3();
	var n = new THREE.Vector3();
	var bitan = new THREE.Vector3();
	//計算頂點資料,壓入vertices數組
	for ( var i = 0; i < radialSegments; ++ i ) {

		grid[ i ] = new Array( tubularSegments );
		var u = i / radialSegments * 2 * p * Math.PI;
		var p1 = getPos( u, q, p, radius, heightScale );
		var p2 = getPos( u + 0.01, q, p, radius, heightScale );
		tang.subVectors( p2, p1 );
		n.addVectors( p2, p1 );

		bitan.crossVectors( tang, n );
		n.crossVectors( bitan, tang );
		bitan.normalize();
		n.normalize();

		for ( var j = 0; j < tubularSegments; ++ j ) {

			var v = j / tubularSegments * 2 * Math.PI;
			var cx = - tube * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
			var cy = tube * Math.sin( v );

			var pos = new THREE.Vector3();
			pos.x = p1.x + cx * n.x + cy * bitan.x;
			pos.y = p1.y + cx * n.y + cy * bitan.y;
			pos.z = p1.z + cx * n.z + cy * bitan.z;

			grid[ i ][ j ] = this.vertices.push( pos ) - 1;

		}

	}
	//計算三角面,以及貼圖uv
	for ( var i = 0; i < radialSegments; ++ i ) {

		for ( var j = 0; j < tubularSegments; ++ j ) {

			var ip = ( i + 1 ) % radialSegments;
			var jp = ( j + 1 ) % tubularSegments;

			var a = grid[ i ][ j ];
			var b = grid[ ip ][ j ];
			var c = grid[ ip ][ jp ];
			var d = grid[ i ][ jp ];

			var uva = new THREE.Vector2( i / radialSegments, j / tubularSegments );
			var uvb = new THREE.Vector2( ( i + 1 ) / radialSegments, j / tubularSegments );
			var uvc = new THREE.Vector2( ( i + 1 ) / radialSegments, ( j + 1 ) / tubularSegments );
			var uvd = new THREE.Vector2( i / radialSegments, ( j + 1 ) / tubularSegments );

			this.faces.push( new THREE.Face3( a, b, d ) );
			this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] );

			this.faces.push( new THREE.Face3( b, c, d ) );
			this.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] );

		}
	}

	this.computeFaceNormals();	//計算面的法線
	this.computeVertexNormals();	//計算頂點法線
	/*
	///getPos方法,已知u,in_q,in_p,radius,heightScale,獲得頂點坐标的具體實作.
	*/
	///<summary>getPos</summary>
	///<param name ="u" type="float">圓周上細分線段,目前分段占等分總長度到起點的距離.</param>
	///<param name ="in_p" type="float">p\Q:對knot(節)狀方式有效,控制曲線路徑纏繞的圈數,P決定垂直方向的參數.</param>
	///<param name ="in_q" type="float">p\Q:對knot(節)狀方式有效,控制曲線路徑纏繞的圈數,Q決定水準方向的參數.</param>
	///<param name ="radius" type="float">環形結半徑</param>
	///<param name ="heightScale" type="float">環形結高方向上的縮放.</param>
	function getPos( u, in_q, in_p, radius, heightScale ) {

		var cu = Math.cos( u );
		var su = Math.sin( u );
		var quOverP = in_q / in_p * u;
		var cs = Math.cos( quOverP );

		var tx = radius * ( 2 + cs ) * 0.5 * cu;
		var ty = radius * ( 2 + cs ) * su * 0.5;
		var tz = heightScale * radius * Math.sin( quOverP ) * 0.5;

		return new THREE.Vector3( tx, ty, tz );

	}

};
/*************************************************
****下面是TorusKnotGeometry對象的方法屬性定義,繼承自Geometry對象.
**************************************************/
THREE.TorusKnotGeometry.prototype = Object.create( THREE.Geometry.prototype );
           

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

本文遵循“署名-非商業用途-保持一緻”創作公用協定

轉載請保留此句:商域無疆 -  本部落格專注于 靈活開發及移動和物聯裝置研究:資料可視化、GOLANG、Html5、WEBGL、THREE.JS,否則,出自本部落格的文章拒絕轉載或再轉載,謝謝合作。

以下代碼是THREE.JS 源碼檔案中extras/geometries/TorusKnotGeometry.js檔案的注釋.

更多更新在 : https://github.com/omni360/three.js.sourcecode

繼續閱讀