Bladeren bron

Merge pull request #7686 from zz85/closed_spline

CatmullRomCurve3 supports .closed property
Mr.doob 9 jaren geleden
bovenliggende
commit
d05bd4fd4d

+ 60 - 0
docs/api/extras/curves/CatmullRomCurve3.html

@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Curve] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">Create a smooth 3d spline curve from a series of points using the Catmull-Rom algorithm</div>
+
+		<h2>Example</h2>
+
+<code>
+//Create a closed wavey loop
+var curve = new THREE.CatmullRomCurve3( [
+	new THREE.Vector3( -10, 0, 10 ),
+	new THREE.Vector3( -5, 5, 5 ),
+	new THREE.Vector3( 0, 0, 0 ),
+	new THREE.Vector3( 5, -5, 5 ),
+	new THREE.Vector3( 10, 0, 10 )
+] );
+
+var geometry = new THREE.Geometry();
+geometry.vertices = curve.getPoints( 50 );
+
+var material = new THREE.LineBasicMaterial( { color : 0xff0000 } );
+</code>
+
+		<h3>[example:webgl_geometry_extrude_splines geometry / extrude / splines]</h3>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]( [page:Array points] )</h3>
+		<div>points – An array of [page:Vector3] points</div>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Array points]</h3>
+		
+		<h3>[property:Boolean closed] – curve loops back onto itself when true. False by default.</h3>
+		
+		<h3>[property:String type] - possible values are `centripetal` (default), `chordal` and `catmullrom`
+			
+		<h3>[property:float tension] - when type is `catmullrom`, defines catmullrom's tension. Defaults to 0.5
+
+		<h2>Methods</h2>
+
+		<h3>See [page:Curve] for inherited methods</h3>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 2 - 2
docs/api/extras/curves/ClosedSplineCurve3.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -12,7 +12,7 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">Create a smooth 3d spline curve from a series of points that loops back onto itself</div>
+		<div class="desc">Create a smooth 3d spline curve from a series of points that loops back onto itself. THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3</div>
 
 		<h2>Example</h2>
 

+ 1 - 0
docs/list.js

@@ -178,6 +178,7 @@ var list = {
 
 		"Extras / Curves": [
 			[ "ArcCurve", "api/extras/curves/ArcCurve" ],
+			[ "CatmullRomCurve3", "api/extras/curves/CatmullRomCurve3" ],
 			[ "ClosedSplineCurve3", "api/extras/curves/ClosedSplineCurve3" ],
 			[ "CubicBezierCurve", "api/extras/curves/CubicBezierCurve" ],
 			[ "CubicBezierCurve3", "api/extras/curves/CubicBezierCurve3" ],

+ 18 - 13
src/extras/curves/CatmullRomCurve3.js

@@ -84,6 +84,7 @@ THREE.CatmullRomCurve3 = ( function() {
 		function ( p /* array of Vector3 */ ) {
 
 			this.points = p || [];
+			this.closed = false;
 
 		},
 
@@ -96,37 +97,41 @@ THREE.CatmullRomCurve3 = ( function() {
 
 			if ( l < 2 ) console.log( 'duh, you need at least 2 points' );
 
-			point = ( l - 1 ) * t;
+			point = ( l - ( this.closed ? 0 : 1 ) ) * t;
 			intPoint = Math.floor( point );
 			weight = point - intPoint;
-
-			if ( weight === 0 && intPoint === l - 1 ) {
+			
+			if ( this.closed ) {
+				
+				intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;
+				
+			} else if ( weight === 0 && intPoint === l - 1 ) {
 
 				intPoint = l - 2;
 				weight = 1;
 
 			}
 
-			var p0, p1, p2, p3;
+			var p0, p1, p2, p3; // 4 points
 
-			if ( intPoint === 0 ) {
+			if ( this.closed || intPoint > 0 ) {
 
-				// extrapolate first point
-				tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
-				p0 = tmp;
+				p0 = points[ ( intPoint - 1 ) % l ];
 
 			} else {
 
-				p0 = points[ intPoint - 1 ];
+				// extrapolate first point
+				tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
+				p0 = tmp;
 
 			}
 
-			p1 = points[ intPoint ];
-			p2 = points[ intPoint + 1 ];
+			p1 = points[ intPoint % l ];
+			p2 = points[ ( intPoint + 1 ) % l ];
 
-			if ( intPoint + 2 < l ) {
+			if ( this.closed || intPoint + 2 < l ) {
 
-				p3 = points[ intPoint + 2 ]
+				p3 = points[ ( intPoint + 2 ) % l ]
 
 			} else {
 

+ 8 - 32
src/extras/curves/ClosedSplineCurve3.js

@@ -3,37 +3,13 @@
  **************************************************************/
 
 
-THREE.ClosedSplineCurve3 = THREE.Curve.create(
+THREE.ClosedSplineCurve3 = function ( points ) {
 
-	function ( points /* array of Vector3 */ ) {
+	console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.' );
+	THREE.CatmullRomCurve3.call( this, points );
+	this.type = 'catmullrom';
+	this.closed = true;
+	
+};
 
-		this.points = ( points == undefined ) ? [] : points;
-
-	},
-
-	function ( t ) {
-
-		var points = this.points;
-		var point = ( points.length - 0 ) * t; // This needs to be from 0-length +1
-
-		var intPoint = Math.floor( point );
-		var weight = point - intPoint;
-
-		intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;
-
-		var point0 = points[ ( intPoint - 1 ) % points.length ];
-		var point1 = points[ ( intPoint     ) % points.length ];
-		var point2 = points[ ( intPoint + 1 ) % points.length ];
-		var point3 = points[ ( intPoint + 2 ) % points.length ];
-
-		var interpolate = THREE.CurveUtils.interpolate;
-
-		return new THREE.Vector3(
-			interpolate( point0.x, point1.x, point2.x, point3.x, weight ),
-			interpolate( point0.y, point1.y, point2.y, point3.y, weight ),
-			interpolate( point0.z, point1.z, point2.z, point3.z, weight )
-		);
-
-	}
-
-);
+THREE.ClosedSplineCurve3.prototype = Object.create( THREE.CatmullRomCurve3.prototype );

+ 125 - 0
test/unit/extras/curves/CatmullRomCurve3.js

@@ -0,0 +1,125 @@
+/**
+ * @author zz85 / http://joshuakoo.com
+ */
+
+module( "CatmullRomCurve3" );
+
+var positions = [
+	new THREE.Vector3( - 60, - 100,  60 ),
+	new THREE.Vector3( - 60,   20,  60 ),
+	new THREE.Vector3( - 60,  120,  60 ),
+	new THREE.Vector3(  60,   20, - 60 ),
+	new THREE.Vector3(  60, - 100, - 60 )
+];
+
+test( "catmullrom check", function() {
+
+	var curve = new THREE.CatmullRomCurve3( positions );
+	curve.type = 'catmullrom';
+
+	var catmullPoints = [
+
+		new THREE.Vector3( - 60, - 100, 60 ),
+		new THREE.Vector3( - 60, - 51.04, 60 ),
+		new THREE.Vector3( - 60, - 2.7199999999999998, 60 ),
+		new THREE.Vector3( - 61.92, 44.48, 61.92 ),
+		new THREE.Vector3( - 68.64, 95.36000000000001, 68.64 ),
+		new THREE.Vector3( - 60, 120, 60 ),
+		new THREE.Vector3( - 14.880000000000017, 95.36000000000001, 14.880000000000017 ),
+		new THREE.Vector3( 41.75999999999997, 44.48000000000003, - 41.75999999999997 ),
+		new THREE.Vector3( 67.68, - 4.640000000000025, - 67.68 ),
+		new THREE.Vector3( 65.75999999999999, - 59.68000000000002, - 65.75999999999999 ),
+		new THREE.Vector3( 60, - 100, - 60 )
+
+	];
+
+	var getPoints = curve.getPoints( 10 );
+	var error = vectorsAreEqual( getPoints, catmullPoints );
+	ok( getPoints.length == 11, 'getPoints should be equal.' );
+	var desc = error ? ' ' + error : '';
+	ok( ! error, 'Lists of Vectors3 should be equal.' + desc );
+
+} );
+
+test( "chordal basic check", function() {
+
+	var curve = new THREE.CatmullRomCurve3( positions );
+
+	curve.type = 'chordal';
+
+	var chordalPoints = [
+		new THREE.Vector3( - 60, - 100, 60 ),
+		new THREE.Vector3( - 60, - 52, 60 ),
+		new THREE.Vector3( - 60, - 4, 60 ),
+		new THREE.Vector3( - 60.656435889910924, 41.62455386421379, 60.656435889910924 ),
+		new THREE.Vector3( - 62.95396150459915, 87.31049238896205, 62.95396150459915 ),
+		new THREE.Vector3( - 60, 120, 60 ),
+		new THREE.Vector3( - 16.302568199486444, 114.1500463116312, 16.302568199486444 ),
+		new THREE.Vector3( 42.998098664956586, 54.017050116427455, - 42.998098664956586 ),
+		new THREE.Vector3( 63.542500175682434, - 3.0571533975463856, - 63.542500175682434 ),
+		new THREE.Vector3( 62.65687513176183, - 58.49286504815978, - 62.65687513176183 ),
+		new THREE.Vector3( 60.00000000000001, - 100, - 60.00000000000001 )
+	];
+
+	var getPoints = curve.getPoints( 10 );
+	var error = vectorsAreEqual( getPoints, chordalPoints );
+	ok( getPoints.length == 11, 'getPoints should be equal.' );
+	var desc = error ? ' ' + error : '';
+	ok( ! error, 'Lists of Vectors3 should be equal.' + desc );
+
+} );
+
+test( "centripetal basic check", function() {
+
+	var curve = new THREE.CatmullRomCurve3( positions );
+	curve.type = 'centripetal';
+
+	var centripetalPoints = [
+		new THREE.Vector3( - 60, - 100, 60 ),
+		new THREE.Vector3( - 60, - 51.47527724919028, 60 ),
+		new THREE.Vector3( - 60, - 3.300369665587032, 60 ),
+		new THREE.Vector3( - 61.13836565863938, 42.86306307781241, 61.13836565863938 ),
+		new THREE.Vector3( - 65.1226454638772, 90.69743905511538, 65.1226454638772 ),
+		new THREE.Vector3( - 60, 120, 60 ),
+		new THREE.Vector3( - 15.620412575504497, 103.10790870179872, 15.620412575504497 ),
+		new THREE.Vector3( 42.384384731047874, 48.35477686933143, - 42.384384731047874 ),
+		new THREE.Vector3( 65.25545512241153, - 3.5662509660683424, - 65.25545512241153 ),
+		new THREE.Vector3( 63.94159134180865, - 58.87468822455125, - 63.94159134180865 ),
+		new THREE.Vector3( 59.99999999999999, - 100, - 59.99999999999999 ),
+	];
+
+	var getPoints = curve.getPoints( 10 );
+	var error = vectorsAreEqual( getPoints, centripetalPoints );
+	ok( getPoints.length == 11, 'getPoints should be equal.' );
+	var desc = error ? ' ' + error : '';
+	ok( ! error, 'Lists of Vectors3 should be equal.' + desc );
+
+} );
+
+test( "closed catmullrom basic check", function() {
+
+	var curve = new THREE.CatmullRomCurve3( positions );
+	curve.type = 'catmullrom';
+	curve.closed = true;
+
+	var closedSplinePoints = [
+		new THREE.Vector3( - 60, - 100, 60 ),
+		new THREE.Vector3( - 67.5, - 46.25, 67.5 ),
+		new THREE.Vector3( - 60, 20, 60 ),
+		new THREE.Vector3( - 67.5, 83.75, 67.5 ),
+		new THREE.Vector3( - 60, 120, 60 ),
+		new THREE.Vector3( 0, 83.75, 0 ),
+		new THREE.Vector3( 60, 20, - 60 ),
+		new THREE.Vector3( 75, - 46.25, - 75 ),
+		new THREE.Vector3( 60, - 100, - 60 ),
+		new THREE.Vector3( 0, - 115, 0 ),
+		new THREE.Vector3( - 60, - 100, 60 ),
+	];
+
+	var getPoints = curve.getPoints( 10 );
+	var error = vectorsAreEqual( getPoints, closedSplinePoints );
+	ok( getPoints.length == 11, 'getPoints should be equal.' );
+	var desc = error ? ' ' + error : '';
+	ok( ! error, 'Lists of Vectors3 should be equal.' + desc );
+
+} );

+ 57 - 0
test/unit/extras/curves/ClosedSplineCurve3.js

@@ -0,0 +1,57 @@
+/**
+ * @author zz85 / http://joshuakoo.com
+ */
+
+module( "ClosedSplineCurve3" );
+
+var threshold = 0.000001;
+
+function vectorsAreEqual( check, that ) {
+
+	if ( check.length !== that.length ) return 'Length not equal';
+
+	for ( var i = 0; i < check.length; i ++ ) {
+
+		var a = check[ i ], b = that[ i ];
+		if ( a.distanceToSquared( b ) > threshold ) {
+
+			return 'Vector differs at index ' + i +
+				'. Should be ' + [ a.x, a.y, a.z ] +
+				' instead of ' + [ b.x, b.y, b.z ];
+		}
+	}
+
+	return;
+}
+
+test( "basic check", function() {
+
+	var closedSpline = new THREE.ClosedSplineCurve3( [
+		new THREE.Vector3( -60, -100,  60 ),
+		new THREE.Vector3( -60,   20,  60 ),
+		new THREE.Vector3( -60,  120,  60 ),
+		new THREE.Vector3(  60,   20, -60 ),
+		new THREE.Vector3(  60, -100, -60 )
+	] );
+
+	var closedSplinePoints = [
+		new THREE.Vector3(-60,-100,60),
+		new THREE.Vector3(-67.5,-46.25,67.5),
+		new THREE.Vector3(-60,20,60),
+		new THREE.Vector3(-67.5,83.75,67.5),
+		new THREE.Vector3(-60,120,60),
+		new THREE.Vector3(0,83.75,0),
+		new THREE.Vector3(60,20,-60),
+		new THREE.Vector3(75,-46.25,-75),
+		new THREE.Vector3(60,-100,-60),
+		new THREE.Vector3(0,-115,0),
+		new THREE.Vector3(-60,-100,60),
+	];
+
+	var getPoints = closedSpline.getPoints(10);
+	var error = vectorsAreEqual( getPoints , closedSplinePoints );
+	ok( getPoints.length == 11, 'getPoints should be equal.');
+	var desc = error ? ' ' + error : '';
+	ok( !error, 'Lists of Vectors3 should be equal.' + desc );
+
+});

+ 8 - 0
test/unit/unittests_sources.html

@@ -33,6 +33,11 @@
   <script src="../../src/math/Triangle.js"></script>
   <script src="../../src/math/Interpolant.js"></script>
 
+  <script src="../../src/extras/core/Curve.js"></script>
+  <script src="../../src/extras/CurveUtils.js"></script>
+  <script src="../../src/extras/curves/CatmullRomCurve3.js"></script>
+  <script src="../../src/extras/curves/ClosedSplineCurve3.js"></script>
+
   <!-- add class-based unit tests below -->
 
   <script src="math/Constants.js"></script>
@@ -55,5 +60,8 @@
   <script src="math/Color.js"></script>
   <script src="math/Interpolant.js"></script>
 
+  <script src="extras/curves/ClosedSplineCurve3.js"></script>
+  <script src="extras/curves/CatmullRomCurve3.js"></script>
+
 </body>
 </html>