1 /**
2 * @author zz85 / http://www.lab4games.net/zz85/blog
3 * Extensible curve object
4 *
5 * Some common of Curve methods
6 * .getPoint(t), getTangent(t)
7 * .getPointAt(u), getTagentAt(u)
8 * .getPoints(), .getSpacedPoints()
9 * .getLength()
10 * .updateArcLengths()
11 *
12 * This file contains following classes:
13 *
14 * -- 2d classes --
15 * THREE.Curve
16 * THREE.LineCurve
17 * THREE.QuadraticBezierCurve
18 * THREE.CubicBezierCurve
19 * THREE.SplineCurve
20 * THREE.ArcCurve
21 * THREE.EllipseCurve
22 *
23 * -- 3d classes --
24 * THREE.LineCurve3
25 * THREE.QuadraticBezierCurve3
26 * THREE.CubicBezierCurve3
27 * THREE.SplineCurve3
28 * THREE.ClosedSplineCurve3
29 *
30 * A series of curves can be represented as a THREE.CurvePath
31 *
32 **/
33
34 /**************************************************************
35 * Abstract Curve base class
36 **************************************************************/
37
38 /**@constructor*/
39 THREE.Curve = function () {
40
41 };
42
43 // Virtual base class method to overwrite and implement in subclasses
44 // - t [0 .. 1]
45
46 THREE.Curve.prototype.getPoint = function ( t ) {
47
48 console.log( "Warning, getPoint() not implemented!" );
49 return null;
50
51 };
52
53 // Get point at relative position in curve according to arc length
54 // - u [0 .. 1]
55
56 THREE.Curve.prototype.getPointAt = function ( u ) {
57
58 var t = this.getUtoTmapping( u );
59 return this.getPoint( t );
60
61 };
62
63 // Get sequence of points using getPoint( t )
64
65 THREE.Curve.prototype.getPoints = function ( divisions ) {
66
67 if ( !divisions ) divisions = 5;
68
69 var d, pts = [];
70
71 for ( d = 0; d <= divisions; d ++ ) {
72
73 pts.push( this.getPoint( d / divisions ) );
74
75 }
76
77 return pts;
78
79 };
80
81 // Get sequence of points using getPointAt( u )
82
83 THREE.Curve.prototype.getSpacedPoints = function ( divisions ) {
84
85 if ( !divisions ) divisions = 5;
86
87 var d, pts = [];
88
89 for ( d = 0; d <= divisions; d ++ ) {
90
91 pts.push( this.getPointAt( d / divisions ) );
92
93 }
94
95 return pts;
96
97 };
98
99 // Get total curve arc length
100
101 THREE.Curve.prototype.getLength = function () {
102
103 var lengths = this.getLengths();
104 return lengths[ lengths.length - 1 ];
105
106 };
107
108 // Get list of cumulative segment lengths
109
110 THREE.Curve.prototype.getLengths = function ( divisions ) {
111
112 if ( !divisions ) divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions): 200;
113
114 if ( this.cacheArcLengths
115 && ( this.cacheArcLengths.length == divisions + 1 )
116 && !this.needsUpdate) {
117
118 //console.log( "cached", this.cacheArcLengths );
119 return this.cacheArcLengths;
120
121 }
122
123 this.needsUpdate = false;
124
125 var cache = [];
126 var current, last = this.getPoint( 0 );
127 var p, sum = 0;
128
129 cache.push( 0 );
130
131 for ( p = 1; p <= divisions; p ++ ) {
132
133 current = this.getPoint ( p / divisions );
134 sum += current.distanceTo( last );
135 cache.push( sum );
136 last = current;
137
138 }
139
140 this.cacheArcLengths = cache;
141
142 return cache; // { sums: cache, sum:sum }; Sum is in the last element.
143
144 };
145
146
147 THREE.Curve.prototype.updateArcLengths = function() {
148 this.needsUpdate = true;
149 this.getLengths();
150 };
151
152 // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equi distance
153
154 THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) {
155
156 var arcLengths = this.getLengths();
157
158 var i = 0, il = arcLengths.length;
159
160 var targetArcLength; // The targeted u distance value to get
161
162 if ( distance ) {
163
164 targetArcLength = distance;
165
166 } else {
167
168 targetArcLength = u * arcLengths[ il - 1 ];
169
170 }
171
172 //var time = Date.now();
173
174 // binary search for the index with largest value smaller than target u distance
175
176 var low = 0, high = il - 1, comparison;
177
178 while ( low <= high ) {
179
180 i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
181
182 comparison = arcLengths[ i ] - targetArcLength;
183
184 if ( comparison < 0 ) {
185
186 low = i + 1;
187 continue;
188
189 } else if ( comparison > 0 ) {
190
191 high = i - 1;
192 continue;
193
194 } else {
195
196 high = i;
197 break;
198
199 // DONE
200
201 }
202
203 }
204
205 i = high;
206
207 //console.log('b' , i, low, high, Date.now()- time);
208
209 if ( arcLengths[ i ] == targetArcLength ) {
210
211 var t = i / ( il - 1 );
212 return t;
213
214 }
215
216 // we could get finer grain at lengths, or use simple interpolatation between two points
217
218 var lengthBefore = arcLengths[ i ];
219 var lengthAfter = arcLengths[ i + 1 ];
220
221 var segmentLength = lengthAfter - lengthBefore;
222
223 // determine where we are between the 'before' and 'after' points
224
225 var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
226
227 // add that fractional amount to t
228
229 var t = ( i + segmentFraction ) / ( il -1 );
230
231 return t;
232
233 };
234
235
236 // In 2D space, there are actually 2 normal vectors,
237 // and in 3D space, infinte
238 // TODO this should be depreciated.
239 THREE.Curve.prototype.getNormalVector = function( t ) {
240
241 var vec = this.getTangent( t );
242
243 return new THREE.Vector2( -vec.y , vec.x );
244
245 };
246
247 // Returns a unit vector tangent at t
248 // In case any sub curve does not implement its tangent / normal finding,
249 // we get 2 points with a small delta and find a gradient of the 2 points
250 // which seems to make a reasonable approximation
251
252 THREE.Curve.prototype.getTangent = function( t ) {
253
254 var delta = 0.0001;
255 var t1 = t - delta;
256 var t2 = t + delta;
257
258 // Capping in case of danger
259
260 if ( t1 < 0 ) t1 = 0;
261 if ( t2 > 1 ) t2 = 1;
262
263 var pt1 = this.getPoint( t1 );
264 var pt2 = this.getPoint( t2 );
265
266 var vec = pt2.clone().subSelf(pt1);
267 return vec.normalize();
268
269 };
270
271
272 THREE.Curve.prototype.getTangentAt = function ( u ) {
273
274 var t = this.getUtoTmapping( u );
275 return this.getTangent( t );
276
277 };
278
279 /**************************************************************
280 * Line
281 **************************************************************/
282
283 /**@constructor*/
284 THREE.LineCurve = function ( v1, v2 ) {
285
286 this.v1 = v1;
287 this.v2 = v2;
288
289 };
290
291 THREE.LineCurve.prototype = Object.create( THREE.Curve.prototype );
292
293 THREE.LineCurve.prototype.getPoint = function ( t ) {
294
295 var point = this.v2.clone().subSelf(this.v1);
296 point.multiplyScalar( t ).addSelf( this.v1 );
297
298 return point;
299
300 };
301
302 // Line curve is linear, so we can overwrite default getPointAt
303
304 THREE.LineCurve.prototype.getPointAt = function ( u ) {
305
306 return this.getPoint( u );
307
308 };
309
310 THREE.LineCurve.prototype.getTangent = function( t ) {
311
312 var tangent = this.v2.clone().subSelf(this.v1);
313
314 return tangent.normalize();
315
316 };
317
318 /**************************************************************
319 * Quadratic Bezier curve
320 **************************************************************/
321
322
323 /**@constructor*/
324 THREE.QuadraticBezierCurve = function ( v0, v1, v2 ) {
325
326 this.v0 = v0;
327 this.v1 = v1;
328 this.v2 = v2;
329
330 };
331
332 THREE.QuadraticBezierCurve.prototype = Object.create( THREE.Curve.prototype );
333
334
335 THREE.QuadraticBezierCurve.prototype.getPoint = function ( t ) {
336
337 var tx, ty;
338
339 tx = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x );
340 ty = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y );
341
342 return new THREE.Vector2( tx, ty );
343
344 };
345
346
347 THREE.QuadraticBezierCurve.prototype.getTangent = function( t ) {
348
349 var tx, ty;
350
351 tx = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x );
352 ty = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y );
353
354 // returns unit vector
355
356 var tangent = new THREE.Vector2( tx, ty );
357 tangent.normalize();
358
359 return tangent;
360
361 };
362
363
364 /**************************************************************
365 * Cubic Bezier curve
366 **************************************************************/
367
368 /**@constructor*/
369 THREE.CubicBezierCurve = function ( v0, v1, v2, v3 ) {
370
371 this.v0 = v0;
372 this.v1 = v1;
373 this.v2 = v2;
374 this.v3 = v3;
375
376 };
377
378 THREE.CubicBezierCurve.prototype = Object.create( THREE.Curve.prototype );
379
380 THREE.CubicBezierCurve.prototype.getPoint = function ( t ) {
381
382 var tx, ty;
383
384 tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
385 ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
386
387 return new THREE.Vector2( tx, ty );
388
389 };
390
391 THREE.CubicBezierCurve.prototype.getTangent = function( t ) {
392
393 var tx, ty;
394
395 tx = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
396 ty = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
397
398 var tangent = new THREE.Vector2( tx, ty );
399 tangent.normalize();
400
401 return tangent;
402
403 };
404
405
406 /**************************************************************
407 * Spline curve
408 **************************************************************/
409
410 /**@constructor*/
411 THREE.SplineCurve = function ( points /* array of Vector2 */ ) {
412
413 this.points = (points == undefined) ? [] : points;
414
415 };
416
417 THREE.SplineCurve.prototype = Object.create( THREE.Curve.prototype );
418
419 THREE.SplineCurve.prototype.getPoint = function ( t ) {
420
421 var v = new THREE.Vector2();
422 var c = [];
423 var points = this.points, point, intPoint, weight;
424 point = ( points.length - 1 ) * t;
425
426 intPoint = Math.floor( point );
427 weight = point - intPoint;
428
429 c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
430 c[ 1 ] = intPoint;
431 c[ 2 ] = intPoint > points.length - 2 ? points.length -1 : intPoint + 1;
432 c[ 3 ] = intPoint > points.length - 3 ? points.length -1 : intPoint + 2;
433
434 v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
435 v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
436
437 return v;
438
439 };
440
441 /**************************************************************
442 * Ellipse curve
443 **************************************************************/
444
445 /**@constructor*/
446 THREE.EllipseCurve = function ( aX, aY, xRadius, yRadius,
447 aStartAngle, aEndAngle,
448 aClockwise ) {
449
450 this.aX = aX;
451 this.aY = aY;
452
453 this.xRadius = xRadius;
454 this.yRadius = yRadius;
455
456 this.aStartAngle = aStartAngle;
457 this.aEndAngle = aEndAngle;
458
459 this.aClockwise = aClockwise;
460
461 };
462
463 THREE.EllipseCurve.prototype = Object.create( THREE.Curve.prototype );
464
465 THREE.EllipseCurve.prototype.getPoint = function ( t ) {
466
467 var deltaAngle = this.aEndAngle - this.aStartAngle;
468
469 if ( !this.aClockwise ) {
470
471 t = 1 - t;
472
473 }
474
475 var angle = this.aStartAngle + t * deltaAngle;
476
477 var tx = this.aX + this.xRadius * Math.cos( angle );
478 var ty = this.aY + this.yRadius * Math.sin( angle );
479
480 return new THREE.Vector2( tx, ty );
481
482 };
483
484 /**************************************************************
485 * Arc curve
486 **************************************************************/
487
488 /**@constructor*/
489 THREE.ArcCurve = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
490
491 THREE.EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
492 };
493
494 THREE.ArcCurve.prototype = Object.create( THREE.EllipseCurve.prototype );
495
496
497 /**************************************************************
498 * Utils
499 **************************************************************/
500
501 THREE.Curve.Utils = {
502
503 tangentQuadraticBezier: function ( t, p0, p1, p2 ) {
504
505 return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );
506
507 },
508
509 // Puay Bing, thanks for helping with this derivative!
510
511 tangentCubicBezier: function (t, p0, p1, p2, p3 ) {
512
513 return -3 * p0 * (1 - t) * (1 - t) +
514 3 * p1 * (1 - t) * (1-t) - 6 *t *p1 * (1-t) +
515 6 * t * p2 * (1-t) - 3 * t * t * p2 +
516 3 * t * t * p3;
517 },
518
519
520 tangentSpline: function ( t, p0, p1, p2, p3 ) {
521
522 // To check if my formulas are correct
523
524 var h00 = 6 * t * t - 6 * t; // derived from 2t^3 − 3t^2 + 1
525 var h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t
526 var h01 = -6 * t * t + 6 * t; // − 2t3 + 3t2
527 var h11 = 3 * t * t - 2 * t; // t3 − t2
528
529 return h00 + h10 + h01 + h11;
530
531 },
532
533 // Catmull-Rom
534
535 interpolate: function( p0, p1, p2, p3, t ) {
536
537 var v0 = ( p2 - p0 ) * 0.5;
538 var v1 = ( p3 - p1 ) * 0.5;
539 var t2 = t * t;
540 var t3 = t * t2;
541 return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
542
543 }
544
545 };
546
547
548 // TODO: Transformation for Curves?
549
550 /**************************************************************
551 * 3D Curves
552 **************************************************************/
553
554 // A Factory method for creating new curve subclasses
555
556 THREE.Curve.create = function ( constructor, getPointFunc ) {
557
558 constructor.prototype = Object.create( THREE.Curve.prototype );
559 constructor.prototype.getPoint = getPointFunc;
560
561 return constructor;
562
563 };
564
565
566 /**************************************************************
567 * Line3D
568 **************************************************************/
569
570 /**@memberOf THREE.Curve
571 @function
572 @name LineCurve3*/
573 THREE.LineCurve3 = THREE.Curve.create(
574
575 function ( v1, v2 ) {
576
577 this.v1 = v1;
578 this.v2 = v2;
579
580 },
581
582 function ( t ) {
583
584 var r = new THREE.Vector3();
585
586
587 r.sub( this.v2, this.v1 ); // diff
588 r.multiplyScalar( t );
589 r.addSelf( this.v1 );
590
591 return r;
592
593 }
594
595 );
596
597
598 /**************************************************************
599 * Quadratic Bezier 3D curve
600 **************************************************************/
601
602 /**@memberOf THREE.Curve
603 @function
604 @name QuadraticBezierCurve3*/
605 THREE.QuadraticBezierCurve3 = THREE.Curve.create(
606
607 function ( v0, v1, v2 ) {
608
609 this.v0 = v0;
610 this.v1 = v1;
611 this.v2 = v2;
612
613 },
614
615 function ( t ) {
616
617 var tx, ty, tz;
618
619 tx = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x );
620 ty = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y );
621 tz = THREE.Shape.Utils.b2( t, this.v0.z, this.v1.z, this.v2.z );
622
623 return new THREE.Vector3( tx, ty, tz );
624
625 }
626
627 );
628
629
630
631 /**************************************************************
632 * Cubic Bezier 3D curve
633 **************************************************************/
634
635 /**@memberOf THREE.Curve
636 @function
637 @name CubicBezierCurve3*/
638 THREE.CubicBezierCurve3 = THREE.Curve.create(
639
640 function ( v0, v1, v2, v3 ) {
641
642 this.v0 = v0;
643 this.v1 = v1;
644 this.v2 = v2;
645 this.v3 = v3;
646
647 },
648
649 function ( t ) {
650
651 var tx, ty, tz;
652
653 tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
654 ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
655 tz = THREE.Shape.Utils.b3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z );
656
657 return new THREE.Vector3( tx, ty, tz );
658
659 }
660
661 );
662
663
664
665 /**************************************************************
666 * Spline 3D curve
667 **************************************************************/
668
669
670 /**@memberOf THREE.Curve
671 @function
672 @name SplineCurve3*/
673 THREE.SplineCurve3 = THREE.Curve.create(
674
675 function ( points /* array of Vector3 */) {
676
677 this.points = (points == undefined) ? [] : points;
678
679 },
680
681 function ( t ) {
682
683 var v = new THREE.Vector3();
684 var c = [];
685 var points = this.points, point, intPoint, weight;
686 point = ( points.length - 1 ) * t;
687
688 intPoint = Math.floor( point );
689 weight = point - intPoint;
690
691 c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
692 c[ 1 ] = intPoint;
693 c[ 2 ] = intPoint > points.length - 2 ? points.length - 1 : intPoint + 1;
694 c[ 3 ] = intPoint > points.length - 3 ? points.length - 1 : intPoint + 2;
695
696 var pt0 = points[ c[0] ],
697 pt1 = points[ c[1] ],
698 pt2 = points[ c[2] ],
699 pt3 = points[ c[3] ];
700
701 v.x = THREE.Curve.Utils.interpolate(pt0.x, pt1.x, pt2.x, pt3.x, weight);
702 v.y = THREE.Curve.Utils.interpolate(pt0.y, pt1.y, pt2.y, pt3.y, weight);
703 v.z = THREE.Curve.Utils.interpolate(pt0.z, pt1.z, pt2.z, pt3.z, weight);
704
705 return v;
706
707 }
708
709 );
710
711
712 // THREE.SplineCurve3.prototype.getTangent = function(t) {
713 // var v = new THREE.Vector3();
714 // var c = [];
715 // var points = this.points, point, intPoint, weight;
716 // point = ( points.length - 1 ) * t;
717
718 // intPoint = Math.floor( point );
719 // weight = point - intPoint;
720
721 // c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
722 // c[ 1 ] = intPoint;
723 // c[ 2 ] = intPoint > points.length - 2 ? points.length - 1 : intPoint + 1;
724 // c[ 3 ] = intPoint > points.length - 3 ? points.length - 1 : intPoint + 2;
725
726 // var pt0 = points[ c[0] ],
727 // pt1 = points[ c[1] ],
728 // pt2 = points[ c[2] ],
729 // pt3 = points[ c[3] ];
730
731 // // t = weight;
732 // v.x = THREE.Curve.Utils.tangentSpline( t, pt0.x, pt1.x, pt2.x, pt3.x );
733 // v.y = THREE.Curve.Utils.tangentSpline( t, pt0.y, pt1.y, pt2.y, pt3.y );
734 // v.z = THREE.Curve.Utils.tangentSpline( t, pt0.z, pt1.z, pt2.z, pt3.z );
735
736 // return v;
737
738 // }
739
740 /**************************************************************
741 * Closed Spline 3D curve
742 **************************************************************/
743
744
745 /**@memberOf THREE.Curve
746 @function
747 @name ClosedSplineCurve3*/
748 THREE.ClosedSplineCurve3 = THREE.Curve.create(
749
750 function ( points /* array of Vector3 */) {
751
752 this.points = (points == undefined) ? [] : points;
753
754 },
755
756 function ( t ) {
757
758 var v = new THREE.Vector3();
759 var c = [];
760 var points = this.points, point, intPoint, weight;
761 point = ( points.length - 0 ) * t;
762 // This needs to be from 0-length +1
763
764 intPoint = Math.floor( point );
765 weight = point - intPoint;
766
767 intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;
768 c[ 0 ] = ( intPoint - 1 ) % points.length;
769 c[ 1 ] = ( intPoint ) % points.length;
770 c[ 2 ] = ( intPoint + 1 ) % points.length;
771 c[ 3 ] = ( intPoint + 2 ) % points.length;
772
773 v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
774 v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
775 v.z = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].z, points[ c[ 1 ] ].z, points[ c[ 2 ] ].z, points[ c[ 3 ] ].z, weight );
776
777 return v;
778
779 }
780
781 );
782
nike free rn
new balance hombre baratas
cinturones gucci
ugg rebajas
cinturon gucci
ray ban baratas
nike cortez
peuterey mujer
christian louboutin madrid
mbt zapatos
gafas ray ban baratas
mbt ofertas
air max blancas
mbt barcelona
nike air max 90
woolrich barcelona
nike mujer
botas ugg
gafas de sol carrera aratas
air max 2016 baratas
oakley baratas
nike air max 2016