source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/src/math/Spline.js@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

File size: 3.8 KB
Line 
1/**
2 * Spline from Tween.js, slightly optimized (and trashed)
3 * http://sole.github.com/tween.js/examples/05_spline.html
4 *
5 * @author mrdoob / http://mrdoob.com/
6 * @author alteredq / http://alteredqualia.com/
7 */
8
9THREE.Spline = function ( points ) {
10
11 this.points = points;
12
13 var c = [], v3 = { x: 0, y: 0, z: 0 },
14 point, intPoint, weight, w2, w3,
15 pa, pb, pc, pd;
16
17 this.initFromArray = function( a ) {
18
19 this.points = [];
20
21 for ( var i = 0; i < a.length; i++ ) {
22
23 this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };
24
25 }
26
27 };
28
29 this.getPoint = function ( k ) {
30
31 point = ( this.points.length - 1 ) * k;
32 intPoint = Math.floor( point );
33 weight = point - intPoint;
34
35 c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
36 c[ 1 ] = intPoint;
37 c[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;
38 c[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;
39
40 pa = this.points[ c[ 0 ] ];
41 pb = this.points[ c[ 1 ] ];
42 pc = this.points[ c[ 2 ] ];
43 pd = this.points[ c[ 3 ] ];
44
45 w2 = weight * weight;
46 w3 = weight * w2;
47
48 v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );
49 v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );
50 v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );
51
52 return v3;
53
54 };
55
56 this.getControlPointsArray = function () {
57
58 var i, p, l = this.points.length,
59 coords = [];
60
61 for ( i = 0; i < l; i ++ ) {
62
63 p = this.points[ i ];
64 coords[ i ] = [ p.x, p.y, p.z ];
65
66 }
67
68 return coords;
69
70 };
71
72 // approximate length by summing linear segments
73
74 this.getLength = function ( nSubDivisions ) {
75
76 var i, index, nSamples, position,
77 point = 0, intPoint = 0, oldIntPoint = 0,
78 oldPosition = new THREE.Vector3(),
79 tmpVec = new THREE.Vector3(),
80 chunkLengths = [],
81 totalLength = 0;
82
83 // first point has 0 length
84
85 chunkLengths[ 0 ] = 0;
86
87 if ( !nSubDivisions ) nSubDivisions = 100;
88
89 nSamples = this.points.length * nSubDivisions;
90
91 oldPosition.copy( this.points[ 0 ] );
92
93 for ( i = 1; i < nSamples; i ++ ) {
94
95 index = i / nSamples;
96
97 position = this.getPoint( index );
98 tmpVec.copy( position );
99
100 totalLength += tmpVec.distanceTo( oldPosition );
101
102 oldPosition.copy( position );
103
104 point = ( this.points.length - 1 ) * index;
105 intPoint = Math.floor( point );
106
107 if ( intPoint != oldIntPoint ) {
108
109 chunkLengths[ intPoint ] = totalLength;
110 oldIntPoint = intPoint;
111
112 }
113
114 }
115
116 // last point ends with total length
117
118 chunkLengths[ chunkLengths.length ] = totalLength;
119
120 return { chunks: chunkLengths, total: totalLength };
121
122 };
123
124 this.reparametrizeByArcLength = function ( samplingCoef ) {
125
126 var i, j,
127 index, indexCurrent, indexNext,
128 linearDistance, realDistance,
129 sampling, position,
130 newpoints = [],
131 tmpVec = new THREE.Vector3(),
132 sl = this.getLength();
133
134 newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );
135
136 for ( i = 1; i < this.points.length; i++ ) {
137
138 //tmpVec.copy( this.points[ i - 1 ] );
139 //linearDistance = tmpVec.distanceTo( this.points[ i ] );
140
141 realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];
142
143 sampling = Math.ceil( samplingCoef * realDistance / sl.total );
144
145 indexCurrent = ( i - 1 ) / ( this.points.length - 1 );
146 indexNext = i / ( this.points.length - 1 );
147
148 for ( j = 1; j < sampling - 1; j++ ) {
149
150 index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );
151
152 position = this.getPoint( index );
153 newpoints.push( tmpVec.copy( position ).clone() );
154
155 }
156
157 newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );
158
159 }
160
161 this.points = newpoints;
162
163 };
164
165 // Catmull-Rom
166
167 function interpolate( p0, p1, p2, p3, t, t2, t3 ) {
168
169 var v0 = ( p2 - p0 ) * 0.5,
170 v1 = ( p3 - p1 ) * 0.5;
171
172 return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
173
174 };
175
176};
Note: See TracBrowser for help on using the repository browser.