未验证 提交 6588fd2a 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #18985 from Mugen87/dev3

Curve: Add optional target to getTangent() and getTangentAt().
......@@ -79,15 +79,23 @@
using [page:.getPoint].
</p>
<h3>[method:Vector getTangent]( [param:Float t] )</h3>
<h3>[method:Vector getTangent]( [param:Float t, [param:Vector optionalTarget] ] )</h3>
<p>
[page:Float t] - A position on the curve. Must be in the range [ 0, 1 ]. <br>
[page:Vector optionalTarget] — (optional) If specified, the result will be copied into this Vector,
otherwise a new Vector will be created. <br /><br />
Returns a unit vector tangent at t. If the derived curve does not implement its
tangent derivation, two points a small delta apart will be used to find its gradient
which seems to give a reasonable approximation.
</p>
<h3>[method:Vector getTangentAt]( [param:Float u] )</h3>
<h3>[method:Vector getTangentAt]( [param:Float u, [param:Vector optionalTarget] ] )</h3>
<p>
[page:Float u] - A position on the curve according to the arc length. Must be in the range [ 0, 1 ]. <br>
[page:Vector optionalTarget] — (optional) If specified, the result will be copied into this Vector,
otherwise a new Vector will be created. <br /><br />
Returns tangent at a point which is equidistant to the ends of the curve from the
point given in [page:.getTangent].
</p>
......
......@@ -77,17 +77,25 @@
Given u in the range ( 0 .. 1 ), returns [page:Float t] also in the range ( 0 .. 1 ).
u and t can then be used to give you points which are equidistant from the ends of the curve,
using [page:.getPoint].
</p>
</p>
<h3>[method:Vector getTangent]( [param:Float t] )</h3>
<h3>[method:Vector getTangent]( [param:Float t, [param:Vector optionalTarget] ] )</h3>
<p>
[page:Float t] - A position on the curve. Must be in the range [ 0, 1 ]. <br>
[page:Vector optionalTarget] — (optional) If specified, the result will be copied into this Vector,
otherwise a new Vector will be created. <br /><br />
Returns a unit vector tangent at t. If the derived curve does not implement its
tangent derivation, two points a small delta apart will be used to find its gradient
which seems to give a reasonable approximation.
</p>
<h3>[method:Vector getTangentAt]( [param:Float u] )</h3>
<h3>[method:Vector getTangentAt]( [param:Float u, [param:Vector optionalTarget] ] )</h3>
<p>
[page:Float u] - A position on the curve according to the arc length. Must be in the range [ 0, 1 ]. <br>
[page:Vector optionalTarget] — (optional) If specified, the result will be copied into this Vector,
otherwise a new Vector will be created. <br /><br />
Returns tangent at a point which is equidistant to the ends of the curve from the
point given in [page:.getTangent].
</p>
......
......@@ -59,12 +59,13 @@ THREE.NURBSCurve.prototype.getPoint = function ( t, optionalTarget ) {
};
THREE.NURBSCurve.prototype.getTangent = function ( t ) {
THREE.NURBSCurve.prototype.getTangent = function ( t, optionalTarget ) {
var tangent = optionalTarget || new THREE.Vector3();
var u = this.knots[ 0 ] + t * ( this.knots[ this.knots.length - 1 ] - this.knots[ 0 ] );
var ders = THREE.NURBSUtils.calcNURBSDerivatives( this.degree, this.knots, this.controlPoints, u, 1 );
var tangent = ders[ 1 ].clone();
tangent.normalize();
tangent.copy( ders[ 1 ] ).normalize();
return tangent;
......
......@@ -66,12 +66,13 @@ NURBSCurve.prototype.getPoint = function ( t, optionalTarget ) {
};
NURBSCurve.prototype.getTangent = function ( t ) {
NURBSCurve.prototype.getTangent = function ( t, optionalTarget ) {
var tangent = optionalTarget || new Vector3();
var u = this.knots[ 0 ] + t * ( this.knots[ this.knots.length - 1 ] - this.knots[ 0 ] );
var ders = NURBSUtils.calcNURBSDerivatives( this.degree, this.knots, this.controlPoints, u, 1 );
var tangent = ders[ 1 ].clone();
tangent.normalize();
tangent.copy( ders[ 1 ] ).normalize();
return tangent;
......
......@@ -37,6 +37,7 @@
var camera, scene, renderer, splineCamera, cameraHelper, cameraEye;
var direction = new THREE.Vector3();
var binormal = new THREE.Vector3();
var normal = new THREE.Vector3();
var position = new THREE.Vector3();
......@@ -305,10 +306,10 @@
binormal.subVectors( tubeGeometry.binormals[ pickNext ], tubeGeometry.binormals[ pick ] );
binormal.multiplyScalar( pickt - pick ).add( tubeGeometry.binormals[ pick ] );
var dir = tubeGeometry.parameters.path.getTangentAt( t );
tubeGeometry.parameters.path.getTangentAt( t, direction );
var offset = 15;
normal.copy( binormal ).cross( dir );
normal.copy( binormal ).cross( direction );
// we move on a offset on its binormal
......@@ -324,7 +325,7 @@
// camera orientation 2 - up orientation via normal
if ( ! params.lookAhead ) lookAt.copy( position ).add( dir );
if ( ! params.lookAhead ) lookAt.copy( position ).add( direction );
splineCamera.matrix.lookAt( splineCamera.position, lookAt, normal );
splineCamera.quaternion.setFromRotationMatrix( splineCamera.matrix );
......
......@@ -17,13 +17,13 @@ export class Curve<T extends Vector> {
/**
* Returns a vector for point t of the curve where t is between 0 and 1
* getPoint(t: number): T;
* getPoint(t: number, optionalTarget?: T): T;
*/
getPoint( t: number, optionalTarget?: T ): T;
/**
* Returns a vector for point at relative position in curve according to arc length
* getPointAt(u: number): T;
* getPointAt(u: number, optionalTarget?: T): T;
*/
getPointAt( u: number, optionalTarget?: T ): T;
......@@ -61,15 +61,15 @@ export class Curve<T extends Vector> {
/**
* Returns a unit vector tangent at t. If the subclassed curve do not implement its tangent derivation, 2 points a small delta apart will be used to find its gradient which seems to give a reasonable approximation
* getTangent(t: number): T;
* getTangent(t: number, optionalTarget?: T): T;
*/
getTangent( t: number ): T;
getTangent( t: number, optionalTarget?: T ): T;
/**
* Returns tangent at equidistance point u on the curve
* getTangentAt(u: number): T;
* getTangentAt(u: number, optionalTarget?: T): T;
*/
getTangentAt( u: number ): T;
getTangentAt( u: number, optionalTarget?: T ): T;
/**
* @deprecated since r84.
......
import { MathUtils } from '../../math/MathUtils.js';
import { Vector2 } from '../../math/Vector2.js';
import { Vector3 } from '../../math/Vector3.js';
import { Matrix4 } from '../../math/Matrix4.js';
......@@ -7,8 +8,8 @@ import { Matrix4 } from '../../math/Matrix4.js';
* Extensible curve object
*
* Some common of curve methods:
* .getPoint( t, optionalTarget ), .getTangent( t )
* .getPointAt( u, optionalTarget ), .getTangentAt( u )
* .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget )
* .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget )
* .getPoints(), .getSpacedPoints()
* .getLength()
* .updateArcLengths()
......@@ -237,7 +238,7 @@ Object.assign( Curve.prototype, {
// 2 points a small delta apart will be used to find its gradient
// which seems to give a reasonable approximation
getTangent: function ( t ) {
getTangent: function ( t, optionalTarget ) {
var delta = 0.0001;
var t1 = t - delta;
......@@ -251,15 +252,18 @@ Object.assign( Curve.prototype, {
var pt1 = this.getPoint( t1 );
var pt2 = this.getPoint( t2 );
var vec = pt2.clone().sub( pt1 );
return vec.normalize();
var tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() );
tangent.copy( pt2 ).sub( pt1 ).normalize();
return tangent;
},
getTangentAt: function ( u ) {
getTangentAt: function ( u, optionalTarget ) {
var t = this.getUtoTmapping( u );
return this.getTangent( t );
return this.getTangent( t, optionalTarget );
},
......@@ -284,7 +288,7 @@ Object.assign( Curve.prototype, {
u = i / segments;
tangents[ i ] = this.getTangentAt( u );
tangents[ i ] = this.getTangentAt( u, new Vector3() );
tangents[ i ].normalize();
}
......
......@@ -45,11 +45,13 @@ LineCurve.prototype.getPointAt = function ( u, optionalTarget ) {
};
LineCurve.prototype.getTangent = function ( /* t */ ) {
LineCurve.prototype.getTangent = function ( t, optionalTarget ) {
var tangent = this.v2.clone().sub( this.v1 );
var tangent = optionalTarget || new Vector2();
return tangent.normalize();
var tangent = tangent.copy( this.v2 ).sub( this.v1 ).normalize();
return tangent;
};
......
......@@ -232,10 +232,10 @@ export default QUnit.module( 'Extras', () => {
];
var points = [
curve.getPointAt( 0 ),
curve.getPointAt( 0.3 ),
curve.getPointAt( 0.5 ),
curve.getPointAt( 1 )
curve.getPointAt( 0, new Vector3() ),
curve.getPointAt( 0.3, new Vector3() ),
curve.getPointAt( 0.5, new Vector3() ),
curve.getPointAt( 1, new Vector3() )
];
assert.deepEqual( points, expectedPoints, "Correct points" );
......@@ -256,11 +256,11 @@ export default QUnit.module( 'Extras', () => {
];
var tangents = [
curve.getTangent( 0 ),
curve.getTangent( 0.25 ),
curve.getTangent( 0.5 ),
curve.getTangent( 0.75 ),
curve.getTangent( 1 )
curve.getTangent( 0, new Vector3() ),
curve.getTangent( 0.25, new Vector3() ),
curve.getTangent( 0.5, new Vector3() ),
curve.getTangent( 0.75, new Vector3() ),
curve.getTangent( 1, new Vector3() )
];
expectedTangents.forEach( function ( exp, i ) {
......@@ -274,7 +274,7 @@ export default QUnit.module( 'Extras', () => {
//
var expectedTangents = [
expectedTangents = [
new Vector3( 0, 1, 0 ),
new Vector3( - 0.10709018822205997, 0.9884651653817284, 0.10709018822205997 ),
new Vector3( 0.6396363672964268, - 0.4262987629159402, - 0.6396363672964268 ),
......@@ -282,12 +282,12 @@ export default QUnit.module( 'Extras', () => {
new Vector3( - 0.00019991333100812723, - 0.9999999600346592, 0.00019991333100812723 )
];
var tangents = [
curve.getTangentAt( 0 ),
curve.getTangentAt( 0.25 ),
curve.getTangentAt( 0.5 ),
curve.getTangentAt( 0.75 ),
curve.getTangentAt( 1 )
tangents = [
curve.getTangentAt( 0, new Vector3() ),
curve.getTangentAt( 0.25, new Vector3() ),
curve.getTangentAt( 0.5, new Vector3() ),
curve.getTangentAt( 0.75, new Vector3() ),
curve.getTangentAt( 1, new Vector3() )
];
expectedTangents.forEach( function ( exp, i ) {
......
......@@ -116,10 +116,10 @@ export default QUnit.module( 'Extras', () => {
];
var points = [
curve.getPointAt( 0 ),
curve.getPointAt( 0.3 ),
curve.getPointAt( 0.5 ),
curve.getPointAt( 1 )
curve.getPointAt( 0, new Vector2() ),
curve.getPointAt( 0.3, new Vector2() ),
curve.getPointAt( 0.5, new Vector2() ),
curve.getPointAt( 1, new Vector2() )
];
assert.deepEqual( points, expectedPoints, "Correct points" );
......@@ -137,11 +137,11 @@ export default QUnit.module( 'Extras', () => {
];
var tangents = [
curve.getTangent( 0 ),
curve.getTangent( 0.25 ),
curve.getTangent( 0.5 ),
curve.getTangent( 0.75 ),
curve.getTangent( 1 )
curve.getTangent( 0, new Vector2() ),
curve.getTangent( 0.25, new Vector2() ),
curve.getTangent( 0.5, new Vector2() ),
curve.getTangent( 0.75, new Vector2() ),
curve.getTangent( 1, new Vector2() )
];
expectedTangents.forEach( function ( exp, i ) {
......@@ -164,11 +164,11 @@ export default QUnit.module( 'Extras', () => {
];
var tangents = [
curve.getTangentAt( 0 ),
curve.getTangentAt( 0.25 ),
curve.getTangentAt( 0.5 ),
curve.getTangentAt( 0.75 ),
curve.getTangentAt( 1 )
curve.getTangentAt( 0, new Vector2() ),
curve.getTangentAt( 0.25, new Vector2() ),
curve.getTangentAt( 0.5, new Vector2() ),
curve.getTangentAt( 0.75, new Vector2() ),
curve.getTangentAt( 1, new Vector2() )
];
expectedTangents.forEach( function ( exp, i ) {
......
......@@ -116,10 +116,10 @@ export default QUnit.module( 'Extras', () => {
];
var points = [
curve.getPointAt( 0 ),
curve.getPointAt( 0.3 ),
curve.getPointAt( 0.5 ),
curve.getPointAt( 1 )
curve.getPointAt( 0, new Vector3() ),
curve.getPointAt( 0.3, new Vector3() ),
curve.getPointAt( 0.5, new Vector3() ),
curve.getPointAt( 1, new Vector3() )
];
assert.deepEqual( points, expectedPoints, "Correct points" );
......@@ -137,11 +137,11 @@ export default QUnit.module( 'Extras', () => {
];
var tangents = [
curve.getTangent( 0 ),
curve.getTangent( 0.25 ),
curve.getTangent( 0.5 ),
curve.getTangent( 0.75 ),
curve.getTangent( 1 )
curve.getTangent( 0, new Vector3() ),
curve.getTangent( 0.25, new Vector3() ),
curve.getTangent( 0.5, new Vector3() ),
curve.getTangent( 0.75, new Vector3() ),
curve.getTangent( 1, new Vector3() )
];
expectedTangents.forEach( function ( exp, i ) {
......@@ -164,11 +164,11 @@ export default QUnit.module( 'Extras', () => {
];
tangents = [
curve.getTangentAt( 0 ),
curve.getTangentAt( 0.25 ),
curve.getTangentAt( 0.5 ),
curve.getTangentAt( 0.75 ),
curve.getTangentAt( 1 )
curve.getTangentAt( 0, new Vector3() ),
curve.getTangentAt( 0.25, new Vector3() ),
curve.getTangentAt( 0.5, new Vector3() ),
curve.getTangentAt( 0.75, new Vector3() ),
curve.getTangentAt( 1, new Vector3() )
];
expectedTangents.forEach( function ( exp, i ) {
......
......@@ -107,13 +107,16 @@ export default QUnit.module( 'Extras', () => {
var testValues = [ 0, 0.3, 0.5, 0.7, 1 ];
testValues.forEach( function ( val, i ) {
var p = new Vector2();
var a = new Vector2();
testValues.forEach( function ( val ) {
var expectedX = Math.cos( val * Math.PI * 2 ) * 10;
var expectedY = Math.sin( val * Math.PI * 2 ) * 10;
var p = curve.getPoint( val );
var a = curve.getPointAt( val );
curve.getPoint( val, p );
curve.getPointAt( val, a );
assert.numEqual( p.x, expectedX, "getPoint(" + val + ").x correct" );
assert.numEqual( p.y, expectedY, "getPoint(" + val + ").y correct" );
......@@ -136,11 +139,11 @@ export default QUnit.module( 'Extras', () => {
];
var tangents = [
curve.getTangent( 0 ),
curve.getTangent( 0.25 ),
curve.getTangent( 0.5 ),
curve.getTangent( 0.75 ),
curve.getTangent( 1 )
curve.getTangent( 0, new Vector2() ),
curve.getTangent( 0.25, new Vector2() ),
curve.getTangent( 0.5, new Vector2() ),
curve.getTangent( 0.75, new Vector2() ),
curve.getTangent( 1, new Vector2() )
];
expectedTangents.forEach( function ( exp, i ) {
......
......@@ -66,10 +66,10 @@ export default QUnit.module( 'Extras', () => {
];
var points = [
curve.getPointAt( 0 ),
curve.getPointAt( 0.3 ),
curve.getPointAt( 0.5 ),
curve.getPointAt( 1 )
curve.getPointAt( 0, new Vector2() ),
curve.getPointAt( 0.3, new Vector2() ),
curve.getPointAt( 0.5, new Vector2() ),
curve.getPointAt( 1, new Vector2() )
];
assert.deepEqual( points, expectedPoints, "Correct points" );
......@@ -79,8 +79,9 @@ export default QUnit.module( 'Extras', () => {
QUnit.test( "getTangent", ( assert ) => {
var curve = _curve;
var tangent = new Vector2();
var tangent = curve.getTangent( 0 );
curve.getTangent( 0, tangent );
var expectedTangent = Math.sqrt( 0.5 );
assert.numEqual( tangent.x, expectedTangent, "tangent.x correct" );
......
......@@ -66,10 +66,10 @@ export default QUnit.module( 'Extras', () => {
];
var points = [
curve.getPointAt( 0 ),
curve.getPointAt( 0.3 ),
curve.getPointAt( 0.5 ),
curve.getPointAt( 1 )
curve.getPointAt( 0, new Vector3() ),
curve.getPointAt( 0.3, new Vector3() ),
curve.getPointAt( 0.5, new Vector3() ),
curve.getPointAt( 1, new Vector3() )
];
assert.deepEqual( points, expectedPoints, "Correct getPointAt points" );
......@@ -145,8 +145,9 @@ export default QUnit.module( 'Extras', () => {
QUnit.test( "getTangent/getTangentAt", ( assert ) => {
var curve = _curve;
var tangent = new Vector3();
var tangent = curve.getTangent( 0.5 );
curve.getTangent( 0.5, tangent );
var expectedTangent = Math.sqrt( 1 / 3 );
assert.numEqual( tangent.x, expectedTangent, "tangent.x correct" );
......
......@@ -120,10 +120,10 @@ export default QUnit.module( 'Extras', () => {
];
var points = [
curve.getPointAt( 0 ),
curve.getPointAt( 0.3 ),
curve.getPointAt( 0.5 ),
curve.getPointAt( 1 )
curve.getPointAt( 0, new Vector2() ),
curve.getPointAt( 0.3, new Vector2() ),
curve.getPointAt( 0.5, new Vector2() ),
curve.getPointAt( 1, new Vector2() )
];
assert.deepEqual( points, expectedPoints, "Correct points" );
......@@ -143,11 +143,11 @@ export default QUnit.module( 'Extras', () => {
];
var tangents = [
curve.getTangent( 0 ),
curve.getTangent( 0.25 ),
curve.getTangent( 0.5 ),
curve.getTangent( 0.75 ),
curve.getTangent( 1 )
curve.getTangent( 0, new Vector2() ),
curve.getTangent( 0.25, new Vector2() ),
curve.getTangent( 0.5, new Vector2() ),
curve.getTangent( 0.75, new Vector2() ),
curve.getTangent( 1, new Vector2() )
];
expectedTangents.forEach( function ( exp, i ) {
......@@ -170,11 +170,11 @@ export default QUnit.module( 'Extras', () => {
];
tangents = [
curve.getTangentAt( 0 ),
curve.getTangentAt( 0.25 ),
curve.getTangentAt( 0.5 ),
curve.getTangentAt( 0.75 ),
curve.getTangentAt( 1 )
curve.getTangentAt( 0, new Vector2() ),
curve.getTangentAt( 0.25, new Vector2() ),
curve.getTangentAt( 0.5, new Vector2() ),
curve.getTangentAt( 0.75, new Vector2() ),
curve.getTangentAt( 1, new Vector2() )
];
expectedTangents.forEach( function ( exp, i ) {
......
......@@ -120,10 +120,10 @@ export default QUnit.module( 'Extras', () => {
];
var points = [
curve.getPointAt( 0 ),
curve.getPointAt( 0.3 ),
curve.getPointAt( 0.5 ),
curve.getPointAt( 1 )
curve.getPointAt( 0, new Vector3() ),
curve.getPointAt( 0.3, new Vector3() ),
curve.getPointAt( 0.5, new Vector3() ),
curve.getPointAt( 1, new Vector3() )
];
assert.deepEqual( points, expectedPoints, "Correct points" );
......@@ -143,11 +143,11 @@ export default QUnit.module( 'Extras', () => {
];
var tangents = [
curve.getTangent( 0 ),
curve.getTangent( 0.25 ),
curve.getTangent( 0.5 ),
curve.getTangent( 0.75 ),
curve.getTangent( 1 )
curve.getTangent( 0, new Vector3() ),
curve.getTangent( 0.25, new Vector3() ),
curve.getTangent( 0.5, new Vector3() ),
curve.getTangent( 0.75, new Vector3() ),
curve.getTangent( 1, new Vector3() )
];
expectedTangents.forEach( function ( exp, i ) {
......@@ -170,11 +170,11 @@ export default QUnit.module( 'Extras', () => {
];
tangents = [
curve.getTangentAt( 0 ),
curve.getTangentAt( 0.25 ),
curve.getTangentAt( 0.5 ),
curve.getTangentAt( 0.75 ),
curve.getTangentAt( 1 )
curve.getTangentAt( 0, new Vector3() ),
curve.getTangentAt( 0.25, new Vector3() ),
curve.getTangentAt( 0.5, new Vector3() ),
curve.getTangentAt( 0.75, new Vector3() ),
curve.getTangentAt( 1, new Vector3() )
];
expectedTangents.forEach( function ( exp, i ) {
......
......@@ -111,13 +111,15 @@ export default QUnit.module( 'Extras', () => {
QUnit.test( "getPointAt", ( assert ) => {
var curve = _curve;
var point = new Vector2();
assert.ok( curve.getPointAt( 0 ).equals( curve.points[ 0 ] ), "PointAt 0.0 correct" );
assert.ok( curve.getPointAt( 1 ).equals( curve.points[ 4 ] ), "PointAt 1.0 correct" );
assert.ok( curve.getPointAt( 0, point ).equals( curve.points[ 0 ] ), "PointAt 0.0 correct" );
assert.ok( curve.getPointAt( 1, point ).equals( curve.points[ 4 ] ), "PointAt 1.0 correct" );
var pointAt = curve.getPointAt( 0.5 );
assert.numEqual( pointAt.x, 0.0, "PointAt 0.5 x correct" );
assert.numEqual( pointAt.y, 0.0, "PointAt 0.5 y correct" );
curve.getPointAt( 0.5, point );
assert.numEqual( point.x, 0.0, "PointAt 0.5 x correct" );
assert.numEqual( point.y, 0.0, "PointAt 0.5 y correct" );
} );
......@@ -132,9 +134,9 @@ export default QUnit.module( 'Extras', () => {
];
var tangents = [
curve.getTangent( 0 ),
curve.getTangent( 0.5 ),
curve.getTangent( 1 )
curve.getTangent( 0, new Vector2() ),
curve.getTangent( 0.5, new Vector2() ),
curve.getTangent( 1, new Vector2() )
];
tangents.forEach( function ( tangent, i ) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册