Browse Source

messing with new curve object

zz85 14 years ago
parent
commit
0819fc65b8
3 changed files with 168 additions and 24 deletions
  1. 112 19
      src/extras/geometries/Path.js
  2. 54 3
      src/extras/geometries/Shape.js
  3. 2 2
      src/extras/geometries/TextGeometry.js

+ 112 - 19
src/extras/geometries/Path.js

@@ -1,6 +1,7 @@
 /**
  * @author zz85 / http://www.lab4games.net/zz85/blog
- * Creates free form path.
+ * Creates free form 2d path using series of points, lines or curves.
+ *
  **/
 
 THREE.Path = function ( points ) {
@@ -19,12 +20,15 @@ THREE.PathActions = {
 
 	MOVE_TO: 'moveTo',
 	LINE_TO: 'lineTo',
-	QUADRATIC_CURVE_TO: 'quadraticCurveTo', // BEZIER quadratic CURVE
-	BEZIER_CURVE_TO: 'bezierCurveTo', 		// BEZIER cubic CURVE
-	CSPLINE_THRU: 'splineThru' 				// TODO cardinal splines
+	QUADRATIC_CURVE_TO: 'quadraticCurveTo', // Bezier quadratic curve
+	BEZIER_CURVE_TO: 'bezierCurveTo', 		// Bezier cubic curve
+	CSPLINE_THRU: 'splineThru',				// Catmull-rom spline
+	ARC: 'arc'								// Circle
 
 };
 
+//TODO Clean up PATH API
+
 /* Create path using straight lines to connect all points */
 
 THREE.Path.prototype.fromPoints = function( vectors /*Array of Vector*/ ) {
@@ -78,21 +82,34 @@ THREE.Path.prototype.splineThru = function( pts /*Array of Vector*/ ) {
 
 }
 
+// FUTURE: Change the API or follow canvas API?
 // TODO ARC (x,y, x-radius, y-radius, startAngle, endAngle)
-THREE.Path.prototype.arc = function() {
+THREE.Path.prototype.arc = function(aX, aY, aRadius,
+                                 aStartAngle, aEndAngle, aClockwise) {
 	
-};
-
-// TODO
+	var args = Array.prototype.slice.call( arguments );
+	this.actions.push( { action: THREE.PathActions.ARC, args: args } );
+   
+
+ };
+
+/*
+// FUTURE ENHANCEMENTS
+example usage?
+Path.addExprFunc('sineCurveTo', sineCurveGetPtFunction)
+Path.sineCurveTo(x,y, amptitude);
+sineCurve.getPoint(t); 
+return sine(disnt) * ampt
 // Create a new func eg. sin (theta) x
 THREE.Path.prototype.addExprFunc = function(exprName, func) {
 };
+*/
 	
 /* Return an array of vectors based on contour of the path */
 
 THREE.Path.prototype.getPoints = function( divisions ) {
 
-	divisions = divisions || 4;
+	divisions = divisions || 12;
 
 	var points = [];
 
@@ -220,8 +237,30 @@ THREE.Path.prototype.getPoints = function( divisions ) {
 			}
 
 			break;
+		case THREE.PathActions.ARC:
+			
+			laste = this.actions[ i - 1 ].args;
+			var aX = args[0], aY = args[1], aRadius = args[2],
+			            aStartAngle = args[3], aEndAngle = args[4], aClockwise = args[5];
+			
+			var lastx = laste[ laste.length - 2 ],
+				lasty = laste[ laste.length - 1 ] ;
+				
+			var deltaAngle = aEndAngle - aStartAngle;
+			var angle;
+			for ( j = 1; j <= divisions * 2; j ++ ) {
+				angle = aStartAngle + j/divisions/2 * deltaAngle;
+				
+				
+				 tx = lastx + aX + aRadius * Math.cos(angle);
+				 ty = lasty + aY + aRadius * Math.sin(angle);
 
-		}
+				points.push( new THREE.Vector2( tx, ty ) );
+			}
+
+		  break;
+
+		} // end switch
 
 	}
 
@@ -271,6 +310,7 @@ var Spline2 = function () {
 };
 
 
+
 THREE.Path.prototype.getMinAndMax = function() {
 
 	var points = this.getPoints();
@@ -295,7 +335,7 @@ THREE.Path.prototype.getMinAndMax = function() {
 
 	}
 
-	// TODO find mid-pt?
+	// TODO Include CG or find mid-pt?
 
 	return {
 
@@ -308,6 +348,8 @@ THREE.Path.prototype.getMinAndMax = function() {
 
 };
 
+
+// TODO. Test
 // createPathGeometry by SolarCoordinates
 /* Returns Object3D with line segments stored as children  */
 THREE.Path.prototype.createPathGeometry = function(divisions, lineMaterial) {
@@ -327,8 +369,49 @@ THREE.Path.prototype.createPathGeometry = function(divisions, lineMaterial) {
     return(pathGeometry);
 };
 
+// To get accurate point with reference to
+// entire path distance at time t,
+// following has to be done
+
+// 1. Length of each sub path have to be known
+// 2. Locate and identify type of curve
+// 3. Get t for the curve
+// 4. Return curve.getPointAt(t')
+THREE.Path.prototype.getPoint = function(t) {
+};
+
+// Compute Lengths and Cache Them
+THREE.Path.prototype.getLength = function() {
+	// Loop all actions/path
+	// Push sums into cached array
+};
+
+THREE.Line = function (x1, y1, x2, y2) {
+	this.x1 = x1;
+	this.y1 = y1;
+	this.x2 = x2;
+	this.y2 = y2;
+};
+
+THREE.Line.prototype.getPoints(divisions) {
+	if (!divisions) divisions = 200;
+	var d, pts = [];
+	for (d=0;d<divisions;d++) {
+		pts.push(this.getPoint(d/divisions));
+	};
+	return pts;
+};
+
 
-// ALL THINGS BELOW TO BE REFACTORSED
+/*
+curve.getPoints();
+curve.getPoint(t);
+curve.getPointAtArcLength(t);
+curve.transform(params);
+curve.getTangentAt(t)
+*/
+
+// ALL THINGS BELOW TO BE REFACTORED
 // QN: Transform final pts or transform ACTIONS or add transform filters?
 THREE.Path.prototype.getPoint = function(t) {
 	var x0, y0, x1, y1, x2, y2;
@@ -423,7 +506,7 @@ var tangentQuad = function (t, p0, p1, p2 ) {
 THREE.Path.prototype.transform = function(path) {
 	path = new THREE.Path();
 	path.moveTo(0,0);
-	path.quadraticCurveTo(200,20, 240,80);
+	path.quadraticCurveTo(100,20, 140,80);
 	
 	console.log(path.cacheArcLengths());
 	
@@ -437,7 +520,8 @@ THREE.Path.prototype.transform = function(path) {
 		oldY = p.y;
 		var xNorm = oldX/ thisBounds.maxX;
 		
-		xNorm = path.getUtoTmapping(xNorm, oldX); // 3 styles. 1) wrap stretched. 2) wrap stretch by arc length 3) warp by actual distance
+		// If using actual distance, for length > path, requires line extrusions
+		//xNorm = path.getUtoTmapping(xNorm, oldX); // 3 styles. 1) wrap stretched. 2) wrap stretch by arc length 3) warp by actual distance
 		
 		var pathPt = path.getPoint(xNorm);
 		var normal = path.getNormalVector(xNorm).multiplyScalar(oldY);;
@@ -455,9 +539,16 @@ THREE.Path.prototype.transform = function(path) {
 };
 
 // Read http://www.tinaja.com/glib/nonlingr.pdf
-//nonlinear transforms
-THREE.Path.prototype.nltransform = function(a,b,c,d,e,f) {
+// nonlinear transforms
 
+THREE.Path.prototype.nltransform = function(a,b,c,d,e,f) {
+		// a - horiztonal size 
+		// b - lean 
+		// c - x offset
+		// d - vertical size
+		// e - climb
+		// f - y offset
+		
 	var oldPts = this.getPoints();
 	var i, il, p, oldX, oldY;
 	for (i=0,il=oldPts.length; i< il;i++){
@@ -472,12 +563,13 @@ THREE.Path.prototype.nltransform = function(a,b,c,d,e,f) {
 	
 };
 
+
+// FUTURE Export JSON Format
+
 /* Draws this path onto a 2d canvas easily */
 
 THREE.Path.prototype.debug = function( canvas ) {
 
-	// JUST A STUB
-
 	var bounds = this.getMinAndMax();
 
 	if ( !canvas ) {
@@ -548,10 +640,11 @@ THREE.Path.prototype.debug = function( canvas ) {
 	ctx.stroke();
 	ctx.closePath();
 
-	// DebugPoints
+	// Debug Points
 
 	ctx.strokeStyle = "red";
 
+	/* TO CLEAN UP */
 	//var p, points = this.getPoints();
 	var theta = -90 /180 * Math.PI;
 	var p, points = this.transform(0.866, - 0.866,0, 0.500 , 0.50,-50);

+ 54 - 3
src/extras/geometries/Shape.js

@@ -22,19 +22,70 @@ THREE.Shape.prototype.constructor = THREE.Path;
 /* Returns vertices of triangulated faces | get faces */
 
 THREE.Shape.prototype.triangulate = function() {
-
+	
 	var pts = this.getPoints();
-
+	
+	/* */
 	if ( THREE.FontUtils.Triangulate.area( pts ) > 0 ) {
 
 		pts = pts.reverse();
 
 	};
 
+//	return this.triangulate2(pts);
 	return THREE.FontUtils.Triangulate( pts, true );
-
 };
 
+
+THREE.Shape.prototype.triangulate2 = function(pts) {
+	// For Poly2Tri.js 
+	
+	//var pts = this.getPoints();
+	var shape = [];
+	for (var p in pts) {
+		shape.push(new js.poly2tri.Point(pts[p].x, pts[p].y))
+	}
+
+	var swctx = new js.poly2tri.SweepContext(shape);
+	/*
+		for (var idx in holes)
+		{
+			swctx.AddHole(holes[idx]);
+		}
+	*/
+	var find;
+	var findIndexForPt = function (pt) {
+		find = new THREE.Vector2(pt.x, pt.y);
+		var p;
+		for (p=0, pl = pts.length; p<pl; p++) {
+			if (pts[p].equals(find)) return p;
+		}
+		return -1;
+	};
+	// triangulate
+	js.poly2tri.sweep.Triangulate(swctx);
+
+	var triangles =  swctx.GetTriangles();
+	var tr ;
+	var facesPts = [];
+	for (var t in triangles) {
+		tr =  triangles[t];
+		facesPts.push([
+			findIndexForPt(tr.GetPoint(0)), 
+			findIndexForPt(tr.GetPoint(1)), 
+			findIndexForPt(tr.GetPoint(2))
+				]); 
+	}
+
+
+	console.log(facesPts);
+	console.log("triangles", triangles.length, triangles);
+
+	// Returns array of faces with 3 element each
+	return facesPts;
+
+	
+};
 /* Convenience method to return ExtrudeGeometry */
 
 THREE.Shape.prototype.extrude = function( options ) {

+ 2 - 2
src/extras/geometries/TextGeometry.js

@@ -677,7 +677,7 @@ THREE.FontUtils = {
 			
 		}
 		
-		path.debug(document.getElementById("boo"));
+		//path.debug(document.getElementById("boo"));
 		console.log(path);
 		
 
@@ -880,7 +880,7 @@ THREE.FontUtils = {
 			for ( i = 0; i < length; ) {
 
 				action = outline[ i++ ];
-				console.log(action);
+				//console.log(action);
 				switch( action ) {
 
 				case 'm':