提交 b287fd1d 编写于 作者: Z zz85

curves

上级 0819fc65
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* Extensible Curve Object
*
**/
THREE.Curve = function() {
};
/* Basic function to overwrite and implement */
THREE.Curve.prototype.getPoint = function ( t /* between 0 .. 1 */) {
console.log("Warning, getPoint() not implemented!");
return null;
};
/* getPointAt returns as a porportion of arc length instead of formula */
THREE.Curve.prototype.getPointAt = function ( u /* between 0 .. 1 */) {
var t = this.getUtoTmapping(u);
return this.getPoint(t);
};
/* Get Points using getPoint(t) */
THREE.Curve.prototype.getPoints = function (divisions) {
if (!divisions) divisions = 5;
var d, pts = [];
for (d=0;d<=divisions;d++) {
pts.push(this.getPoint(d/divisions));
};
return pts;
};
/* Get Points using getPointAt(u) */
THREE.Curve.prototype.getSpacedPoints = function (divisions) {
if (!divisions) divisions = 5;
var d, pts = [];
for (d=0;d<=divisions;d++) {
pts.push(this.getPointAt(d/divisions));
};
return pts;
};
THREE.Curve.prototype.getLength = function () {
var lengths = this.getLengths();
return lengths[lengths.length-1];
};
THREE.Curve.prototype.getLengths = function(divisions) {
if (!divisions) divisions = 200;
if (this.cacheLengths && (this.cacheLengths.length==divisions)) {
console.log("catched",this.cacheLengths);
return this.cacheLengths;
}
var cache = [];
var p=1;
var last = this.getPoint(0), current;
var sum = 0;
for (; p <= divisions; p++) {
current = this.getPoint (p/divisions);
sum += current.distanceTo(last);
cache.push(sum);
last = current;
}
this.cacheLengths = cache;
return cache; //{sums: cache, sum:sum}; Sum is in the last element.
};
/* Given u (0..1), get a t to find p. This gives you pt which are equi distance */
THREE.Curve.prototype.getUtoTmapping = function(u, distance) {
var lengths = this.getLengths();
var i = 0,il = lengths.length;
var distanceForU;
if (distance) {
distanceForU = distance;
} else {
distanceForU = u * lengths[il-1];
}
// TODO Should do binary search + sub division + interpolation when needed
while (i<il) {
if (lengths[i]>distanceForU) break;
i++;
}
var t= i/il;
return t;
};
THREE.StraightCurve = function (x1, y1, x2, y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
};
THREE.StraightCurve.prototype = new THREE.Curve();
THREE.StraightCurve.prototype.constructor = THREE.StraightCurve;
/* Basic function to overwrite and implement */
THREE.StraightCurve.prototype.getPoint = function ( t /* between 0 .. 1 */) {
var dx = this.x2 - this.x1;
var dy = this.y2 - this.y1;
var tx = this.x1 + dx * t;
var ty = this.y1 + dy * t;
return new THREE.Vector2( tx, ty );
};
THREE.QuadraticBezierCurve = function ( x0, y0, x1, y1, x2, y2 ) {
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
};
THREE.QuadraticBezierCurve.prototype = new THREE.Curve();
THREE.QuadraticBezierCurve.prototype.constructor = THREE.QuadraticBezierCurve;
/* Basic function to overwrite and implement */
THREE.QuadraticBezierCurve.prototype.getPoint = function ( t /* between 0 .. 1 */) {
var tx, ty;
tx = THREE.FontUtils.b2( t, this.x0, this.x1, this.x2 );
ty = THREE.FontUtils.b2( t, this.y0, this.y1, this.y2 );
return new THREE.Vector2( tx, ty );
};
THREE.CubicBezierCurve = function ( x0, y0, x1, y1, x2, y2, x3, y3 ) {
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.x3 = x3;
this.y3 = y3;
};
THREE.CubicBezierCurve.prototype = new THREE.Curve();
THREE.CubicBezierCurve.prototype.constructor = THREE.CubicBezierCurve;
/* Basic function to overwrite and implement */
THREE.CubicBezierCurve.prototype.getPoint = function ( t /* between 0 .. 1 */) {
var tx, ty;
tx = THREE.FontUtils.b2( t, this.x0, this.x1, this.x2 );
ty = THREE.FontUtils.b2( t, this.y0, this.y1, this.y2 );
return new THREE.Vector2( tx, ty );
};
THREE.SplineCurve = function ( points ) {
this.points = points;
};
THREE.SplineCurve.prototype = new THREE.Curve();
THREE.SplineCurve.prototype.constructor = THREE.CubicBezierCurve;
/* Basic function to overwrite and implement */
THREE.SplineCurve.prototype.getPoint = function ( t /* between 0 .. 1 */) {
var v = new THREE.Vector2();
var c = [];
var points = this.points, point, intPoint, weight;
point = ( points.length - 1 ) * t;
intPoint = Math.floor( point );
weight = point - intPoint;
c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
c[ 1 ] = intPoint;
c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;
v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
return v;
}
THREE.Curve.Utils = {
// Catmull-Rom
interpolate: function( p0, p1, p2, p3, t ) {
var v0 = ( p2 - p0 ) * 0.5;
var v1 = ( p3 - p1 ) * 0.5;
var t2 = t * t;
var t3 = t * t2;
return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
}
};
/*
getPoint DONE
getLength DONE
getLengths DONE
curve.getPoints(); DONE
curve.getPointAtArcLength(t); DONE
curve.transform(params);
curve.getTangentAt(t)
*/
\ No newline at end of file
......@@ -55,15 +55,29 @@ THREE.Path.prototype.moveTo = function( x, y ) {
THREE.Path.prototype.lineTo = function( x, y ) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.LINE_TO, args: args } );
var lastargs = this.actions[ this.actions.length - 1 ].args;
var x0 = lastargs[ lastargs.length - 2 ];
var y0 = lastargs[ lastargs.length - 1 ];
var curve = new THREE.StraightCurve( x0, y0, x, y );
this.actions.push( { action: THREE.PathActions.LINE_TO, args: args, curve:curve } );
};
THREE.Path.prototype.quadraticCurveTo = function( aCPx, aCPy, aX, aY ) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.QUADRATIC_CURVE_TO, args: args });
var lastargs = this.actions[ this.actions.length - 1 ].args;
var x0 = lastargs[ lastargs.length - 2 ];
var y0 = lastargs[ lastargs.length - 1 ];
var curve = new THREE.QuadraticBezierCurve( x0, y0, aCPx, aCPy, aX, aY );
this.actions.push( { action: THREE.PathActions.QUADRATIC_CURVE_TO, args: args, curve:curve });
//console.log(curve, curve.getPoints(), curve.getSpacedPoints());
//console.log(curve.getPointAt(0), curve.getPointAt(0),curve.getUtoTmapping(0), curve.getSpacedPoints());
};
THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y,
......@@ -71,14 +85,31 @@ THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y,
aX, aY) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.BEZIER_CURVE_TO, args: args } );
var lastargs = this.actions[ this.actions.length - 1 ].args;
var x0 = lastargs[ lastargs.length - 2 ];
var y0 = lastargs[ lastargs.length - 1 ];
var curve = new THREE.QuadraticBezierCurve( x0, y0, aCP1x, aCP1y,
aCP2x, aCP2y,
aX, aY );
this.actions.push( { action: THREE.PathActions.BEZIER_CURVE_TO, args: args, curve:curve });
};
THREE.Path.prototype.splineThru = function( pts /*Array of Vector*/ ) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.CSPLINE_THRU, args: args } );
var lastargs = this.actions[ this.actions.length - 1 ].args;
var x0 = lastargs[ lastargs.length - 2 ];
var y0 = lastargs[ lastargs.length - 1 ];
pts.unshift(new THREE.Vector2(x0, y0));
var curve = new THREE.SplineCurve( pts );
this.actions.push( { action: THREE.PathActions.CSPLINE_THRU, args: args,curve:curve } );
//console.log(curve, curve.getPoints(), curve.getSpacedPoints());
}
......@@ -378,57 +409,33 @@ THREE.Path.prototype.createPathGeometry = function(divisions, lineMaterial) {
// 3. Get t for the curve
// 4. Return curve.getPointAt(t')
THREE.Path.prototype.getPoint = function(t) {
var d = t * this.getLength();
// loop where sum != 0, sum > d , sum+1 <d
};
// Compute Lengths and Cache Them
THREE.Path.prototype.getLength = function() {
// Loop all actions/path
// Push sums into cached array
var lengths = [], sums = 0;
var i=0, il = this.actions.length, curve;
for (;i<il;i++) {
curve = this.actions[il].curve;
if (curve) {
sums += curve.getLength();
lengths.push(sums);
} else {
lengths.push(0);
}
}
return sums;
};
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;
};
/*
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;
x0 = this.actions[0].args[0];
y0 = this.actions[0].args[1];
x1 = this.actions[1].args[0];
y1 = this.actions[1].args[1];
x2 = this.actions[1].args[2];
y2 = this.actions[1].args[3];
var tx, ty;
tx = THREE.FontUtils.b2( t, x0, x1, x2 );
ty = THREE.FontUtils.b2( t, y0, y1, y2 );
return new THREE.Vector2( tx, ty );
};
THREE.Path.prototype.getNormalVector = function(t) {
// iterate sub segments
......@@ -454,48 +461,6 @@ THREE.Path.prototype.getNormalVector = function(t) {
};
THREE.Path.prototype.cacheArcLengths = function() {
var divisions = 200;
var cache = [];
var p=1;
var last = this.getPoint(0), current;
var sum = 0;
for (; p <= divisions; p++) {
current = this.getPoint (p/divisions);
sum += current.distanceTo(last);
cache.push(sum);
last = current;
}
this.arcLengthCache = cache;
return {sums: cache, sum:sum};
};
/* Given u (0..1), get a t to find p. This gives you pt which are equi distance */
THREE.Path.prototype.getUtoTmapping = function(u, distance) {
//var arcs = this.cacheArcLengths();
var cache = this.arcLengthCache;
var i = 0,il = cache.length;
var distanceForU = u * cache[cache.length-1];
if (distance) distanceForU = distance;
// Should do binary search + sub division + interpolation if needed
while (i<il) {
if (cache[i]>distanceForU) break;
i++;
}
var t= i/il;
return t;
};
var tangentQuad = function (t, p0, p1, p2 ) {
return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 ) ;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册