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

来源:互联网 发布:电脑用什么优化软件好 编辑:程序博客网 时间:2024/05/17 22:56

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

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

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


俺也是刚开始学,好多地儿肯定不对还请见谅.

以下代码是THREE.JS 源码文件中Math/Spline.js文件的注释.

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


/** * Spline from Tween.js, slightly optimized (and trashed) * http://sole.github.com/tween.js/examples/05_spline.html * * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ *//*///Spline对象的构造函数.用来在三维空间内通过参数points(Vector3数组)创建一个样条曲线对象..//////定义:样条曲线是经过一系列给定点的光滑曲线。最初,样条曲线都是借助于物理样条得到的,放样员把富有弹性的细木条(或有机玻璃条),/// 用压铁固定在曲线应该通过的给定型值点处,样条做自然弯曲所绘制出来的曲线就是样条曲线。样条曲线不仅通过各有序型值点,/// 并且在各型值点处的一阶和二阶导数连续,也即该曲线具有连续的、曲率变化均匀的特点。///NOTE:参考百度百科http://baike.baidu.com/view/1896463.htm?fr=aladdin/// NOTE:关于三次样条插值,参考百度百科http://baike.baidu.com/view/2326225.htm?fr=aladdin/// NOTE:关于更多样条曲线插值,参考维基百科http://zh.wikipedia.org/wiki/%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9A/// NOTE:关于样条曲线,参考维基百科http://zh.wikipedia.org/wiki/%E6%A0%B7%E6%9D%A1%E5%87%BD%E6%95%B0/////////用法: var a = new Vector3(0,0,0),b = new Vector3(1,1,1),c = new Vector3(2,2,2); var points = new Array(a,b,c); var spline = new Spline(points);///创建一个a,b,c三点组成的样条曲线对象.*////<summary>Spline</summary>///<param name ="points" type="Vector3Array">Vector3对象组成的points数组对象</param>THREE.Spline = function ( points ) {this.points = points;//将参数points设置给当前样条对象的points属性var c = [], v3 = { x: 0, y: 0, z: 0 },point, intPoint, weight, w2, w3,pa, pb, pc, pd;/********************************************下面是Spline对象提供的功能函数.****************************************//*///initFromArray方法通过Vector3对象组成的数组(参数a),重新设置当前样条曲线.*////<summary>initFromArray</summary>///<param name ="a" type="Vector3Array">Vector3对象组成的points数组对象</param>///<returns type="Spline">返回新的样条曲线</returns>this.initFromArray = function ( a ) {this.points = [];for ( var i = 0; i < a.length; i ++ ) {//获得数组长度,并将数组中元素赋值给当前样条曲线的points属性.this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };}};/*///getPoint方法将当前样条曲线作为一个整体,返回位于当前样条曲线k位置上的点坐标./// NOTE:getPoint()方法中k值取值范围是0.0-1.0.*////<summary>getPoint</summary>///<param name ="k" type="Float">返回位于当前样条曲线k位置上的点坐标</param>///<returns type="Spline">返回新的样条曲线</returns>this.getPoint = function ( k ) {point = ( this.points.length - 1 ) * k;//获得k大概位于当前样条曲线的第几个节点后,得出结果可能是小数(例如样条曲线有9个节点,参数k为0.4,得出结果3.2说明参数k位于当前样条曲线第三个节点到第四个节点长度20%的位置),赋值给pointintPoint = Math.floor( point );//调用Math.floor()方法,获得整数,第三个节点,赋值给intPointweight = point - intPoint;//或得权值,赋值给weightc[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;//三次样条曲线的起始点c[0]c[ 1 ] = intPoint;//三次样条曲线的控制点c[1]c[ 2 ] = intPoint  > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;//三次样条曲线的控制点c[2]c[ 3 ] = intPoint  > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;//三次样条曲线的结束点c[3]pa = this.points[ c[ 0 ] ];pb = this.points[ c[ 1 ] ];pc = this.points[ c[ 2 ] ];pd = this.points[ c[ 3 ] ];w2 = weight * weight;//权值的平方w3 = weight * w2;//权值的立方v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );//调用interpolate方法是样条插值函数,返回计算位于参数值t的曲线点x坐标v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );//调用interpolate方法是样条插值函数,返回计算位于参数值t的曲线点y坐标v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );//调用interpolate方法是样条插值函数,返回计算位于参数值t的曲线点z坐标return v3;//返回位于当前样条曲线k位置上的点坐标};/*///getControlPointsArray方法返回当前样条曲线节点坐标构成的数组*////<summary>getControlPointsArray</summary>///<returns type="Vector3Array">返回当前样条曲线节点坐标构成的数组</returns>this.getControlPointsArray = function () {var i, p, l = this.points.length,coords = [];for ( i = 0; i < l; i ++ ) {//遍历当前样条曲线points属性p = this.points[ i ];coords[ i ] = [ p.x, p.y, p.z ];//将points属性直接赋值给coords数组}return coords;//返回当前样条曲线节点坐标构成的数组};/*///getLength方法返回被参数nSubDivisions(将当前样条曲线等分成多少段)等分当前样条曲线的长度数组和总长度组成的对象.*////<summary>getLength</summary>///<param name ="nSubDivisions" type="Number">分段数</param>///<returns type="Spline">返回被参数nSubDivisions(将当前样条曲线等分成多少段)等分当前样条曲线的长度数组和总长度组成的对象</returns>// approximate length by summing linear segments//汇总线性线段获得近似长度this.getLength = function ( nSubDivisions ) {var i, index, nSamples, position,point = 0, intPoint = 0, oldIntPoint = 0,oldPosition = new THREE.Vector3(),tmpVec = new THREE.Vector3(),chunkLengths = [],totalLength = 0;// first point has 0 length// 第一个起点长度是0chunkLengths[ 0 ] = 0;if ( ! nSubDivisions ) nSubDivisions = 100;nSamples = this.points.length * nSubDivisions;oldPosition.copy( this.points[ 0 ] );for ( i = 1; i < nSamples; i ++ ) {index = i / nSamples;position = this.getPoint( index );//调用getPoint()方法,获得当前段数的位置坐标.tmpVec.copy( position );totalLength += tmpVec.distanceTo( oldPosition );//求当前段数长度.oldPosition.copy( position );point = ( this.points.length - 1 ) * index;intPoint = Math.floor( point );if ( intPoint != oldIntPoint ) {chunkLengths[ intPoint ] = totalLength;oldIntPoint = intPoint;}}// last point ends with total length//最后一个结束点,返回总长度.chunkLengths[ chunkLengths.length ] = totalLength;return { chunks: chunkLengths, total: totalLength };};this.reparametrizeByArcLength = function ( samplingCoef ) {var i, j,index, indexCurrent, indexNext,linearDistance, realDistance,sampling, position,newpoints = [],tmpVec = new THREE.Vector3(),sl = this.getLength();newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );for ( i = 1; i < this.points.length; i ++ ) {//tmpVec.copy( this.points[ i - 1 ] );//linearDistance = tmpVec.distanceTo( this.points[ i ] );realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];sampling = Math.ceil( samplingCoef * realDistance / sl.total );indexCurrent = ( i - 1 ) / ( this.points.length - 1 );indexNext = i / ( this.points.length - 1 );for ( j = 1; j < sampling - 1; j ++ ) {index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );position = this.getPoint( index );newpoints.push( tmpVec.copy( position ).clone() );}newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );}this.points = newpoints;};// Catmull-Rom/*///interpolate方法是传说中的样条插值函数,这里是三次样条插值算法,返回计算位于参数值t的曲线点./// NOTE:关于三次样条插值,参考百度百科http://baike.baidu.com/view/2326225.htm?fr=aladdin/// NOTE:关于更多样条曲线插值,参考维基百科http://zh.wikipedia.org/wiki/%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9A///  http://zh.wikipedia.org/wiki/%E6%A0%B7%E6%9D%A1%E6%8F%92%E5%80%BC/// NOTE:关于样条曲线,参考维基百科http://zh.wikipedia.org/wiki/%E6%A0%B7%E6%9D%A1%E5%87%BD%E6%95%B0*////<summary>interpolate</summary>///<param name ="p0" type="Float">样条曲线起始点p0</param>///<param name ="p1" type="Float">样条曲线控制点p1</param>///<param name ="p2" type="Float">样条曲线控制点p2</param>///<param name ="p3" type="Float">样条曲线结束点p3</param>///<param name ="t" type="Float">t为参数值,0<=t<=1</param>///<param name ="t2" type="Float">t2是参数值t的平方</param>///<param name ="t3" type="Float">t3是参数值t的立方</param>///<returns type="Spline">返回计算位于参数值t的曲线点</returns>function interpolate( p0, p1, p2, p3, t, t2, t3 ) {var v0 = ( p2 - p0 ) * 0.5,v1 = ( p3 - p1 ) * 0.5;return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;//返回计算位于参数值t的曲线点};};


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

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

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


以下代码是THREE.JS 源码文件中Math/Spline.js文件的注释.

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

0 0
原创粉丝点击