source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/src/extras/core/CurvePath.js

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

GUI front-end to server base plus web page content

File size: 6.5 KB
Line 
1/**
2 * @author zz85 / http://www.lab4games.net/zz85/blog
3 *
4 **/
5
6/**************************************************************
7 * Curved Path - a curve path is simply a array of connected
8 * curves, but retains the api of a curve
9 **************************************************************/
10
11THREE.CurvePath = function () {
12
13 this.curves = [];
14 this.bends = [];
15
16 this.autoClose = false; // Automatically closes the path
17};
18
19THREE.CurvePath.prototype = Object.create( THREE.Curve.prototype );
20
21THREE.CurvePath.prototype.add = function ( curve ) {
22
23 this.curves.push( curve );
24
25};
26
27THREE.CurvePath.prototype.checkConnection = function() {
28 // TODO
29 // If the ending of curve is not connected to the starting
30 // or the next curve, then, this is not a real path
31};
32
33THREE.CurvePath.prototype.closePath = function() {
34 // TODO Test
35 // and verify for vector3 (needs to implement equals)
36 // Add a line curve if start and end of lines are not connected
37 var startPoint = this.curves[0].getPoint(0);
38 var endPoint = this.curves[this.curves.length-1].getPoint(1);
39
40 if (!startPoint.equals(endPoint)) {
41 this.curves.push( new THREE.LineCurve(endPoint, startPoint) );
42 }
43
44};
45
46// To get accurate point with reference to
47// entire path distance at time t,
48// following has to be done:
49
50// 1. Length of each sub path have to be known
51// 2. Locate and identify type of curve
52// 3. Get t for the curve
53// 4. Return curve.getPointAt(t')
54
55THREE.CurvePath.prototype.getPoint = function( t ) {
56
57 var d = t * this.getLength();
58 var curveLengths = this.getCurveLengths();
59 var i = 0, diff, curve;
60
61 // To think about boundaries points.
62
63 while ( i < curveLengths.length ) {
64
65 if ( curveLengths[ i ] >= d ) {
66
67 diff = curveLengths[ i ] - d;
68 curve = this.curves[ i ];
69
70 var u = 1 - diff / curve.getLength();
71
72 return curve.getPointAt( u );
73
74 break;
75 }
76
77 i ++;
78
79 }
80
81 return null;
82
83 // loop where sum != 0, sum > d , sum+1 <d
84
85};
86
87/*
88THREE.CurvePath.prototype.getTangent = function( t ) {
89};*/
90
91
92// We cannot use the default THREE.Curve getPoint() with getLength() because in
93// THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
94// getPoint() depends on getLength
95
96THREE.CurvePath.prototype.getLength = function() {
97
98 var lens = this.getCurveLengths();
99 return lens[ lens.length - 1 ];
100
101};
102
103// Compute lengths and cache them
104// We cannot overwrite getLengths() because UtoT mapping uses it.
105
106THREE.CurvePath.prototype.getCurveLengths = function() {
107
108 // We use cache values if curves and cache array are same length
109
110 if ( this.cacheLengths && this.cacheLengths.length == this.curves.length ) {
111
112 return this.cacheLengths;
113
114 };
115
116 // Get length of subsurve
117 // Push sums into cached array
118
119 var lengths = [], sums = 0;
120 var i, il = this.curves.length;
121
122 for ( i = 0; i < il; i ++ ) {
123
124 sums += this.curves[ i ].getLength();
125 lengths.push( sums );
126
127 }
128
129 this.cacheLengths = lengths;
130
131 return lengths;
132
133};
134
135
136
137// Returns min and max coordinates, as well as centroid
138
139THREE.CurvePath.prototype.getBoundingBox = function () {
140
141 var points = this.getPoints();
142
143 var maxX, maxY, maxZ;
144 var minX, minY, minZ;
145
146 maxX = maxY = Number.NEGATIVE_INFINITY;
147 minX = minY = Number.POSITIVE_INFINITY;
148
149 var p, i, il, sum;
150
151 var v3 = points[0] instanceof THREE.Vector3;
152
153 sum = v3 ? new THREE.Vector3() : new THREE.Vector2();
154
155 for ( i = 0, il = points.length; i < il; i ++ ) {
156
157 p = points[ i ];
158
159 if ( p.x > maxX ) maxX = p.x;
160 else if ( p.x < minX ) minX = p.x;
161
162 if ( p.y > maxY ) maxY = p.y;
163 else if ( p.y < minY ) minY = p.y;
164
165 if ( v3 ) {
166
167 if ( p.z > maxZ ) maxZ = p.z;
168 else if ( p.z < minZ ) minZ = p.z;
169
170 }
171
172 sum.add( p );
173
174 }
175
176 var ret = {
177
178 minX: minX,
179 minY: minY,
180 maxX: maxX,
181 maxY: maxY,
182 centroid: sum.divideScalar( il )
183
184 };
185
186 if ( v3 ) {
187
188 ret.maxZ = maxZ;
189 ret.minZ = minZ;
190
191 }
192
193 return ret;
194
195};
196
197/**************************************************************
198 * Create Geometries Helpers
199 **************************************************************/
200
201/// Generate geometry from path points (for Line or ParticleSystem objects)
202
203THREE.CurvePath.prototype.createPointsGeometry = function( divisions ) {
204
205 var pts = this.getPoints( divisions, true );
206 return this.createGeometry( pts );
207
208};
209
210// Generate geometry from equidistance sampling along the path
211
212THREE.CurvePath.prototype.createSpacedPointsGeometry = function( divisions ) {
213
214 var pts = this.getSpacedPoints( divisions, true );
215 return this.createGeometry( pts );
216
217};
218
219THREE.CurvePath.prototype.createGeometry = function( points ) {
220
221 var geometry = new THREE.Geometry();
222
223 for ( var i = 0; i < points.length; i ++ ) {
224
225 geometry.vertices.push( new THREE.Vector3( points[ i ].x, points[ i ].y, points[ i ].z || 0) );
226
227 }
228
229 return geometry;
230
231};
232
233
234/**************************************************************
235 * Bend / Wrap Helper Methods
236 **************************************************************/
237
238// Wrap path / Bend modifiers?
239
240THREE.CurvePath.prototype.addWrapPath = function ( bendpath ) {
241
242 this.bends.push( bendpath );
243
244};
245
246THREE.CurvePath.prototype.getTransformedPoints = function( segments, bends ) {
247
248 var oldPts = this.getPoints( segments ); // getPoints getSpacedPoints
249 var i, il;
250
251 if ( !bends ) {
252
253 bends = this.bends;
254
255 }
256
257 for ( i = 0, il = bends.length; i < il; i ++ ) {
258
259 oldPts = this.getWrapPoints( oldPts, bends[ i ] );
260
261 }
262
263 return oldPts;
264
265};
266
267THREE.CurvePath.prototype.getTransformedSpacedPoints = function( segments, bends ) {
268
269 var oldPts = this.getSpacedPoints( segments );
270
271 var i, il;
272
273 if ( !bends ) {
274
275 bends = this.bends;
276
277 }
278
279 for ( i = 0, il = bends.length; i < il; i ++ ) {
280
281 oldPts = this.getWrapPoints( oldPts, bends[ i ] );
282
283 }
284
285 return oldPts;
286
287};
288
289// This returns getPoints() bend/wrapped around the contour of a path.
290// Read http://www.planetclegg.com/projects/WarpingTextToSplines.html
291
292THREE.CurvePath.prototype.getWrapPoints = function ( oldPts, path ) {
293
294 var bounds = this.getBoundingBox();
295
296 var i, il, p, oldX, oldY, xNorm;
297
298 for ( i = 0, il = oldPts.length; i < il; i ++ ) {
299
300 p = oldPts[ i ];
301
302 oldX = p.x;
303 oldY = p.y;
304
305 xNorm = oldX / bounds.maxX;
306
307 // If using actual distance, for length > path, requires line extrusions
308 //xNorm = path.getUtoTmapping(xNorm, oldX); // 3 styles. 1) wrap stretched. 2) wrap stretch by arc length 3) warp by actual distance
309
310 xNorm = path.getUtoTmapping( xNorm, oldX );
311
312 // check for out of bounds?
313
314 var pathPt = path.getPoint( xNorm );
315 var normal = path.getTangent( xNorm );
316 normal.set( -normal.y, normal.x ).multiplyScalar( oldY );
317
318 p.x = pathPt.x + normal.x;
319 p.y = pathPt.y + normal.y;
320
321 }
322
323 return oldPts;
324
325};
326
Note: See TracBrowser for help on using the repository browser.