initial commit
This commit is contained in:
18
lib/extras/curves/ArcCurve.js
Normal file
18
lib/extras/curves/ArcCurve.js
Normal file
@ -0,0 +1,18 @@
|
||||
import { EllipseCurve } from './EllipseCurve.js';
|
||||
|
||||
|
||||
function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
|
||||
|
||||
EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
|
||||
|
||||
this.type = 'ArcCurve';
|
||||
|
||||
}
|
||||
|
||||
ArcCurve.prototype = Object.create( EllipseCurve.prototype );
|
||||
ArcCurve.prototype.constructor = ArcCurve;
|
||||
|
||||
ArcCurve.prototype.isArcCurve = true;
|
||||
|
||||
|
||||
export { ArcCurve };
|
255
lib/extras/curves/CatmullRomCurve3.js
Normal file
255
lib/extras/curves/CatmullRomCurve3.js
Normal file
@ -0,0 +1,255 @@
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
import { Curve } from '../core/Curve.js';
|
||||
|
||||
/**
|
||||
* @author zz85 https://github.com/zz85
|
||||
*
|
||||
* Centripetal CatmullRom Curve - which is useful for avoiding
|
||||
* cusps and self-intersections in non-uniform catmull rom curves.
|
||||
* http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
|
||||
*
|
||||
* curve.type accepts centripetal(default), chordal and catmullrom
|
||||
* curve.tension is used for catmullrom which defaults to 0.5
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Based on an optimized c++ solution in
|
||||
- http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/
|
||||
- http://ideone.com/NoEbVM
|
||||
|
||||
This CubicPoly class could be used for reusing some variables and calculations,
|
||||
but for three.js curve use, it could be possible inlined and flatten into a single function call
|
||||
which can be placed in CurveUtils.
|
||||
*/
|
||||
|
||||
function CubicPoly() {
|
||||
|
||||
var c0 = 0, c1 = 0, c2 = 0, c3 = 0;
|
||||
|
||||
/*
|
||||
* Compute coefficients for a cubic polynomial
|
||||
* p(s) = c0 + c1*s + c2*s^2 + c3*s^3
|
||||
* such that
|
||||
* p(0) = x0, p(1) = x1
|
||||
* and
|
||||
* p'(0) = t0, p'(1) = t1.
|
||||
*/
|
||||
function init( x0, x1, t0, t1 ) {
|
||||
|
||||
c0 = x0;
|
||||
c1 = t0;
|
||||
c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;
|
||||
c3 = 2 * x0 - 2 * x1 + t0 + t1;
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
initCatmullRom: function ( x0, x1, x2, x3, tension ) {
|
||||
|
||||
init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );
|
||||
|
||||
},
|
||||
|
||||
initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {
|
||||
|
||||
// compute tangents when parameterized in [t1,t2]
|
||||
var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;
|
||||
var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;
|
||||
|
||||
// rescale tangents for parametrization in [0,1]
|
||||
t1 *= dt1;
|
||||
t2 *= dt1;
|
||||
|
||||
init( x1, x2, t1, t2 );
|
||||
|
||||
},
|
||||
|
||||
calc: function ( t ) {
|
||||
|
||||
var t2 = t * t;
|
||||
var t3 = t2 * t;
|
||||
return c0 + c1 * t + c2 * t2 + c3 * t3;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var tmp = new Vector3();
|
||||
var px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly();
|
||||
|
||||
function CatmullRomCurve3( points, closed, curveType, tension ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'CatmullRomCurve3';
|
||||
|
||||
this.points = points || [];
|
||||
this.closed = closed || false;
|
||||
this.curveType = curveType || 'centripetal';
|
||||
this.tension = tension || 0.5;
|
||||
|
||||
}
|
||||
|
||||
CatmullRomCurve3.prototype = Object.create( Curve.prototype );
|
||||
CatmullRomCurve3.prototype.constructor = CatmullRomCurve3;
|
||||
|
||||
CatmullRomCurve3.prototype.isCatmullRomCurve3 = true;
|
||||
|
||||
CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector3();
|
||||
|
||||
var points = this.points;
|
||||
var l = points.length;
|
||||
|
||||
var p = ( l - ( this.closed ? 0 : 1 ) ) * t;
|
||||
var intPoint = Math.floor( p );
|
||||
var weight = p - intPoint;
|
||||
|
||||
if ( this.closed ) {
|
||||
|
||||
intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l;
|
||||
|
||||
} else if ( weight === 0 && intPoint === l - 1 ) {
|
||||
|
||||
intPoint = l - 2;
|
||||
weight = 1;
|
||||
|
||||
}
|
||||
|
||||
var p0, p1, p2, p3; // 4 points
|
||||
|
||||
if ( this.closed || intPoint > 0 ) {
|
||||
|
||||
p0 = points[ ( intPoint - 1 ) % l ];
|
||||
|
||||
} else {
|
||||
|
||||
// extrapolate first point
|
||||
tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
|
||||
p0 = tmp;
|
||||
|
||||
}
|
||||
|
||||
p1 = points[ intPoint % l ];
|
||||
p2 = points[ ( intPoint + 1 ) % l ];
|
||||
|
||||
if ( this.closed || intPoint + 2 < l ) {
|
||||
|
||||
p3 = points[ ( intPoint + 2 ) % l ];
|
||||
|
||||
} else {
|
||||
|
||||
// extrapolate last point
|
||||
tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
|
||||
p3 = tmp;
|
||||
|
||||
}
|
||||
|
||||
if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) {
|
||||
|
||||
// init Centripetal / Chordal Catmull-Rom
|
||||
var pow = this.curveType === 'chordal' ? 0.5 : 0.25;
|
||||
var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
|
||||
var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
|
||||
var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
|
||||
|
||||
// safety check for repeated points
|
||||
if ( dt1 < 1e-4 ) dt1 = 1.0;
|
||||
if ( dt0 < 1e-4 ) dt0 = dt1;
|
||||
if ( dt2 < 1e-4 ) dt2 = dt1;
|
||||
|
||||
px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
|
||||
py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
|
||||
pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
|
||||
|
||||
} else if ( this.curveType === 'catmullrom' ) {
|
||||
|
||||
px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension );
|
||||
py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension );
|
||||
pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension );
|
||||
|
||||
}
|
||||
|
||||
point.set(
|
||||
px.calc( weight ),
|
||||
py.calc( weight ),
|
||||
pz.calc( weight )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
};
|
||||
|
||||
CatmullRomCurve3.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.points = [];
|
||||
|
||||
for ( var i = 0, l = source.points.length; i < l; i ++ ) {
|
||||
|
||||
var point = source.points[ i ];
|
||||
|
||||
this.points.push( point.clone() );
|
||||
|
||||
}
|
||||
|
||||
this.closed = source.closed;
|
||||
this.curveType = source.curveType;
|
||||
this.tension = source.tension;
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
CatmullRomCurve3.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.points = [];
|
||||
|
||||
for ( var i = 0, l = this.points.length; i < l; i ++ ) {
|
||||
|
||||
var point = this.points[ i ];
|
||||
data.points.push( point.toArray() );
|
||||
|
||||
}
|
||||
|
||||
data.closed = this.closed;
|
||||
data.curveType = this.curveType;
|
||||
data.tension = this.tension;
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
CatmullRomCurve3.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.points = [];
|
||||
|
||||
for ( var i = 0, l = json.points.length; i < l; i ++ ) {
|
||||
|
||||
var point = json.points[ i ];
|
||||
this.points.push( new Vector3().fromArray( point ) );
|
||||
|
||||
}
|
||||
|
||||
this.closed = json.closed;
|
||||
this.curveType = json.curveType;
|
||||
this.tension = json.tension;
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { CatmullRomCurve3 };
|
79
lib/extras/curves/CubicBezierCurve.js
Normal file
79
lib/extras/curves/CubicBezierCurve.js
Normal file
@ -0,0 +1,79 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { CubicBezier } from '../core/Interpolations.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
|
||||
function CubicBezierCurve( v0, v1, v2, v3 ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'CubicBezierCurve';
|
||||
|
||||
this.v0 = v0 || new Vector2();
|
||||
this.v1 = v1 || new Vector2();
|
||||
this.v2 = v2 || new Vector2();
|
||||
this.v3 = v3 || new Vector2();
|
||||
|
||||
}
|
||||
|
||||
CubicBezierCurve.prototype = Object.create( Curve.prototype );
|
||||
CubicBezierCurve.prototype.constructor = CubicBezierCurve;
|
||||
|
||||
CubicBezierCurve.prototype.isCubicBezierCurve = true;
|
||||
|
||||
CubicBezierCurve.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector2();
|
||||
|
||||
var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
|
||||
|
||||
point.set(
|
||||
CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
|
||||
CubicBezier( t, v0.y, v1.y, v2.y, v3.y )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
};
|
||||
|
||||
CubicBezierCurve.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.v0.copy( source.v0 );
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
this.v3.copy( source.v3 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
CubicBezierCurve.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.v0 = this.v0.toArray();
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
data.v3 = this.v3.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
CubicBezierCurve.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.v0.fromArray( json.v0 );
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
this.v3.fromArray( json.v3 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { CubicBezierCurve };
|
80
lib/extras/curves/CubicBezierCurve3.js
Normal file
80
lib/extras/curves/CubicBezierCurve3.js
Normal file
@ -0,0 +1,80 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { CubicBezier } from '../core/Interpolations.js';
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
|
||||
|
||||
function CubicBezierCurve3( v0, v1, v2, v3 ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'CubicBezierCurve3';
|
||||
|
||||
this.v0 = v0 || new Vector3();
|
||||
this.v1 = v1 || new Vector3();
|
||||
this.v2 = v2 || new Vector3();
|
||||
this.v3 = v3 || new Vector3();
|
||||
|
||||
}
|
||||
|
||||
CubicBezierCurve3.prototype = Object.create( Curve.prototype );
|
||||
CubicBezierCurve3.prototype.constructor = CubicBezierCurve3;
|
||||
|
||||
CubicBezierCurve3.prototype.isCubicBezierCurve3 = true;
|
||||
|
||||
CubicBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector3();
|
||||
|
||||
var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
|
||||
|
||||
point.set(
|
||||
CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
|
||||
CubicBezier( t, v0.y, v1.y, v2.y, v3.y ),
|
||||
CubicBezier( t, v0.z, v1.z, v2.z, v3.z )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
};
|
||||
|
||||
CubicBezierCurve3.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.v0.copy( source.v0 );
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
this.v3.copy( source.v3 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
CubicBezierCurve3.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.v0 = this.v0.toArray();
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
data.v3 = this.v3.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
CubicBezierCurve3.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.v0.fromArray( json.v0 );
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
this.v3.fromArray( json.v3 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { CubicBezierCurve3 };
|
10
lib/extras/curves/Curves.js
Normal file
10
lib/extras/curves/Curves.js
Normal file
@ -0,0 +1,10 @@
|
||||
export { ArcCurve } from './ArcCurve.js';
|
||||
export { CatmullRomCurve3 } from './CatmullRomCurve3.js';
|
||||
export { CubicBezierCurve } from './CubicBezierCurve.js';
|
||||
export { CubicBezierCurve3 } from './CubicBezierCurve3.js';
|
||||
export { EllipseCurve } from './EllipseCurve.js';
|
||||
export { LineCurve } from './LineCurve.js';
|
||||
export { LineCurve3 } from './LineCurve3.js';
|
||||
export { QuadraticBezierCurve } from './QuadraticBezierCurve.js';
|
||||
export { QuadraticBezierCurve3 } from './QuadraticBezierCurve3.js';
|
||||
export { SplineCurve } from './SplineCurve.js';
|
158
lib/extras/curves/EllipseCurve.js
Normal file
158
lib/extras/curves/EllipseCurve.js
Normal file
@ -0,0 +1,158 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
|
||||
function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'EllipseCurve';
|
||||
|
||||
this.aX = aX || 0;
|
||||
this.aY = aY || 0;
|
||||
|
||||
this.xRadius = xRadius || 1;
|
||||
this.yRadius = yRadius || 1;
|
||||
|
||||
this.aStartAngle = aStartAngle || 0;
|
||||
this.aEndAngle = aEndAngle || 2 * Math.PI;
|
||||
|
||||
this.aClockwise = aClockwise || false;
|
||||
|
||||
this.aRotation = aRotation || 0;
|
||||
|
||||
}
|
||||
|
||||
EllipseCurve.prototype = Object.create( Curve.prototype );
|
||||
EllipseCurve.prototype.constructor = EllipseCurve;
|
||||
|
||||
EllipseCurve.prototype.isEllipseCurve = true;
|
||||
|
||||
EllipseCurve.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector2();
|
||||
|
||||
var twoPi = Math.PI * 2;
|
||||
var deltaAngle = this.aEndAngle - this.aStartAngle;
|
||||
var samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
|
||||
|
||||
// ensures that deltaAngle is 0 .. 2 PI
|
||||
while ( deltaAngle < 0 ) deltaAngle += twoPi;
|
||||
while ( deltaAngle > twoPi ) deltaAngle -= twoPi;
|
||||
|
||||
if ( deltaAngle < Number.EPSILON ) {
|
||||
|
||||
if ( samePoints ) {
|
||||
|
||||
deltaAngle = 0;
|
||||
|
||||
} else {
|
||||
|
||||
deltaAngle = twoPi;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( this.aClockwise === true && ! samePoints ) {
|
||||
|
||||
if ( deltaAngle === twoPi ) {
|
||||
|
||||
deltaAngle = - twoPi;
|
||||
|
||||
} else {
|
||||
|
||||
deltaAngle = deltaAngle - twoPi;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var angle = this.aStartAngle + t * deltaAngle;
|
||||
var x = this.aX + this.xRadius * Math.cos( angle );
|
||||
var y = this.aY + this.yRadius * Math.sin( angle );
|
||||
|
||||
if ( this.aRotation !== 0 ) {
|
||||
|
||||
var cos = Math.cos( this.aRotation );
|
||||
var sin = Math.sin( this.aRotation );
|
||||
|
||||
var tx = x - this.aX;
|
||||
var ty = y - this.aY;
|
||||
|
||||
// Rotate the point about the center of the ellipse.
|
||||
x = tx * cos - ty * sin + this.aX;
|
||||
y = tx * sin + ty * cos + this.aY;
|
||||
|
||||
}
|
||||
|
||||
return point.set( x, y );
|
||||
|
||||
};
|
||||
|
||||
EllipseCurve.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.aX = source.aX;
|
||||
this.aY = source.aY;
|
||||
|
||||
this.xRadius = source.xRadius;
|
||||
this.yRadius = source.yRadius;
|
||||
|
||||
this.aStartAngle = source.aStartAngle;
|
||||
this.aEndAngle = source.aEndAngle;
|
||||
|
||||
this.aClockwise = source.aClockwise;
|
||||
|
||||
this.aRotation = source.aRotation;
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
EllipseCurve.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.aX = this.aX;
|
||||
data.aY = this.aY;
|
||||
|
||||
data.xRadius = this.xRadius;
|
||||
data.yRadius = this.yRadius;
|
||||
|
||||
data.aStartAngle = this.aStartAngle;
|
||||
data.aEndAngle = this.aEndAngle;
|
||||
|
||||
data.aClockwise = this.aClockwise;
|
||||
|
||||
data.aRotation = this.aRotation;
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
EllipseCurve.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.aX = json.aX;
|
||||
this.aY = json.aY;
|
||||
|
||||
this.xRadius = json.xRadius;
|
||||
this.yRadius = json.yRadius;
|
||||
|
||||
this.aStartAngle = json.aStartAngle;
|
||||
this.aEndAngle = json.aEndAngle;
|
||||
|
||||
this.aClockwise = json.aClockwise;
|
||||
|
||||
this.aRotation = json.aRotation;
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { EllipseCurve };
|
90
lib/extras/curves/LineCurve.js
Normal file
90
lib/extras/curves/LineCurve.js
Normal file
@ -0,0 +1,90 @@
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
import { Curve } from '../core/Curve.js';
|
||||
|
||||
|
||||
function LineCurve( v1, v2 ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'LineCurve';
|
||||
|
||||
this.v1 = v1 || new Vector2();
|
||||
this.v2 = v2 || new Vector2();
|
||||
|
||||
}
|
||||
|
||||
LineCurve.prototype = Object.create( Curve.prototype );
|
||||
LineCurve.prototype.constructor = LineCurve;
|
||||
|
||||
LineCurve.prototype.isLineCurve = true;
|
||||
|
||||
LineCurve.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector2();
|
||||
|
||||
if ( t === 1 ) {
|
||||
|
||||
point.copy( this.v2 );
|
||||
|
||||
} else {
|
||||
|
||||
point.copy( this.v2 ).sub( this.v1 );
|
||||
point.multiplyScalar( t ).add( this.v1 );
|
||||
|
||||
}
|
||||
|
||||
return point;
|
||||
|
||||
};
|
||||
|
||||
// Line curve is linear, so we can overwrite default getPointAt
|
||||
|
||||
LineCurve.prototype.getPointAt = function ( u, optionalTarget ) {
|
||||
|
||||
return this.getPoint( u, optionalTarget );
|
||||
|
||||
};
|
||||
|
||||
LineCurve.prototype.getTangent = function ( /* t */ ) {
|
||||
|
||||
var tangent = this.v2.clone().sub( this.v1 );
|
||||
|
||||
return tangent.normalize();
|
||||
|
||||
};
|
||||
|
||||
LineCurve.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
LineCurve.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
LineCurve.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { LineCurve };
|
82
lib/extras/curves/LineCurve3.js
Normal file
82
lib/extras/curves/LineCurve3.js
Normal file
@ -0,0 +1,82 @@
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
import { Curve } from '../core/Curve.js';
|
||||
|
||||
|
||||
function LineCurve3( v1, v2 ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'LineCurve3';
|
||||
|
||||
this.v1 = v1 || new Vector3();
|
||||
this.v2 = v2 || new Vector3();
|
||||
|
||||
}
|
||||
|
||||
LineCurve3.prototype = Object.create( Curve.prototype );
|
||||
LineCurve3.prototype.constructor = LineCurve3;
|
||||
|
||||
LineCurve3.prototype.isLineCurve3 = true;
|
||||
|
||||
LineCurve3.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector3();
|
||||
|
||||
if ( t === 1 ) {
|
||||
|
||||
point.copy( this.v2 );
|
||||
|
||||
} else {
|
||||
|
||||
point.copy( this.v2 ).sub( this.v1 );
|
||||
point.multiplyScalar( t ).add( this.v1 );
|
||||
|
||||
}
|
||||
|
||||
return point;
|
||||
|
||||
};
|
||||
|
||||
// Line curve is linear, so we can overwrite default getPointAt
|
||||
|
||||
LineCurve3.prototype.getPointAt = function ( u, optionalTarget ) {
|
||||
|
||||
return this.getPoint( u, optionalTarget );
|
||||
|
||||
};
|
||||
|
||||
LineCurve3.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
LineCurve3.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
LineCurve3.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { LineCurve3 };
|
75
lib/extras/curves/QuadraticBezierCurve.js
Normal file
75
lib/extras/curves/QuadraticBezierCurve.js
Normal file
@ -0,0 +1,75 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { QuadraticBezier } from '../core/Interpolations.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
|
||||
function QuadraticBezierCurve( v0, v1, v2 ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'QuadraticBezierCurve';
|
||||
|
||||
this.v0 = v0 || new Vector2();
|
||||
this.v1 = v1 || new Vector2();
|
||||
this.v2 = v2 || new Vector2();
|
||||
|
||||
}
|
||||
|
||||
QuadraticBezierCurve.prototype = Object.create( Curve.prototype );
|
||||
QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;
|
||||
|
||||
QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true;
|
||||
|
||||
QuadraticBezierCurve.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector2();
|
||||
|
||||
var v0 = this.v0, v1 = this.v1, v2 = this.v2;
|
||||
|
||||
point.set(
|
||||
QuadraticBezier( t, v0.x, v1.x, v2.x ),
|
||||
QuadraticBezier( t, v0.y, v1.y, v2.y )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
};
|
||||
|
||||
QuadraticBezierCurve.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.v0.copy( source.v0 );
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
QuadraticBezierCurve.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.v0 = this.v0.toArray();
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
QuadraticBezierCurve.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.v0.fromArray( json.v0 );
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { QuadraticBezierCurve };
|
76
lib/extras/curves/QuadraticBezierCurve3.js
Normal file
76
lib/extras/curves/QuadraticBezierCurve3.js
Normal file
@ -0,0 +1,76 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { QuadraticBezier } from '../core/Interpolations.js';
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
|
||||
|
||||
function QuadraticBezierCurve3( v0, v1, v2 ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'QuadraticBezierCurve3';
|
||||
|
||||
this.v0 = v0 || new Vector3();
|
||||
this.v1 = v1 || new Vector3();
|
||||
this.v2 = v2 || new Vector3();
|
||||
|
||||
}
|
||||
|
||||
QuadraticBezierCurve3.prototype = Object.create( Curve.prototype );
|
||||
QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;
|
||||
|
||||
QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true;
|
||||
|
||||
QuadraticBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector3();
|
||||
|
||||
var v0 = this.v0, v1 = this.v1, v2 = this.v2;
|
||||
|
||||
point.set(
|
||||
QuadraticBezier( t, v0.x, v1.x, v2.x ),
|
||||
QuadraticBezier( t, v0.y, v1.y, v2.y ),
|
||||
QuadraticBezier( t, v0.z, v1.z, v2.z )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
};
|
||||
|
||||
QuadraticBezierCurve3.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.v0.copy( source.v0 );
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
QuadraticBezierCurve3.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.v0 = this.v0.toArray();
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
QuadraticBezierCurve3.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.v0.fromArray( json.v0 );
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { QuadraticBezierCurve3 };
|
98
lib/extras/curves/SplineCurve.js
Normal file
98
lib/extras/curves/SplineCurve.js
Normal file
@ -0,0 +1,98 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { CatmullRom } from '../core/Interpolations.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
|
||||
function SplineCurve( points /* array of Vector2 */ ) {
|
||||
|
||||
Curve.call( this );
|
||||
|
||||
this.type = 'SplineCurve';
|
||||
|
||||
this.points = points || [];
|
||||
|
||||
}
|
||||
|
||||
SplineCurve.prototype = Object.create( Curve.prototype );
|
||||
SplineCurve.prototype.constructor = SplineCurve;
|
||||
|
||||
SplineCurve.prototype.isSplineCurve = true;
|
||||
|
||||
SplineCurve.prototype.getPoint = function ( t, optionalTarget ) {
|
||||
|
||||
var point = optionalTarget || new Vector2();
|
||||
|
||||
var points = this.points;
|
||||
var p = ( points.length - 1 ) * t;
|
||||
|
||||
var intPoint = Math.floor( p );
|
||||
var weight = p - intPoint;
|
||||
|
||||
var p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];
|
||||
var p1 = points[ intPoint ];
|
||||
var p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
|
||||
var p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
|
||||
|
||||
point.set(
|
||||
CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ),
|
||||
CatmullRom( weight, p0.y, p1.y, p2.y, p3.y )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
};
|
||||
|
||||
SplineCurve.prototype.copy = function ( source ) {
|
||||
|
||||
Curve.prototype.copy.call( this, source );
|
||||
|
||||
this.points = [];
|
||||
|
||||
for ( var i = 0, l = source.points.length; i < l; i ++ ) {
|
||||
|
||||
var point = source.points[ i ];
|
||||
|
||||
this.points.push( point.clone() );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
SplineCurve.prototype.toJSON = function () {
|
||||
|
||||
var data = Curve.prototype.toJSON.call( this );
|
||||
|
||||
data.points = [];
|
||||
|
||||
for ( var i = 0, l = this.points.length; i < l; i ++ ) {
|
||||
|
||||
var point = this.points[ i ];
|
||||
data.points.push( point.toArray() );
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
SplineCurve.prototype.fromJSON = function ( json ) {
|
||||
|
||||
Curve.prototype.fromJSON.call( this, json );
|
||||
|
||||
this.points = [];
|
||||
|
||||
for ( var i = 0, l = json.points.length; i < l; i ++ ) {
|
||||
|
||||
var point = json.points[ i ];
|
||||
this.points.push( new Vector2().fromArray( point ) );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
|
||||
export { SplineCurve };
|
Reference in New Issue
Block a user