Dart DocumentationthreeCubicBezierCurve

CubicBezierCurve class

class CubicBezierCurve extends Curve2D {
 Vector2 v0, v1, v2, v3;

 CubicBezierCurve( this.v0, this.v1, this.v2, this.v3 ) : super();

 getPoint ( t ) {

   var tx, ty;

   tx = ShapeUtils.b3( t, v0.x, v1.x, v2.x, v3.x );
   ty = ShapeUtils.b3( t, v0.y, v1.y, v2.y, v3.y );

   return new Vector2( tx, ty );

 }

 getTangent( t ) {

   var tx, ty;

   tx = CurveUtils.tangentCubicBezier( t, v0.x, v1.x, v2.x, v3.x );
   ty = CurveUtils.tangentCubicBezier( t, v0.y, v1.y, v2.y, v3.y );

   return new Vector2( tx, ty ).normalize();

 }
}

Extends

Curve<Vector2> > Curve2D > CubicBezierCurve

Constructors

new CubicBezierCurve(Vector2 v0, Vector2 v1, Vector2 v2, Vector2 v3) #

Creates a new Object instance.

Object instances have no meaningful state, and are only useful through their identity. An Object instance is equal to itself only.

docs inherited from Object
CubicBezierCurve( this.v0, this.v1, this.v2, this.v3 ) : super();

Properties

List cacheArcLengths #

inherited from Curve
List cacheArcLengths = null

final num length #

inherited from Curve
num get length => getLengths().last;

bool needsUpdate #

inherited from Curve
bool needsUpdate = false

Vector2 v0 #

Vector2 v0

Vector2 v1 #

Vector2 v0, v1

Vector2 v2 #

Vector2 v0, v1, v2

Vector2 v3 #

Vector2 v0, v1, v2, v3

Methods

List getLengths({num divisions: null}) #

inherited from Curve
List getLengths( {num divisions: null} ) {

		if (divisions == null) divisions = (_arcLengthDivisions != null) ? (_arcLengthDivisions): 200;

		if ( cacheArcLengths != null
			&& ( cacheArcLengths.length == divisions + 1 )
			&& !needsUpdate) {

			//console.log( "cached", this.cacheArcLengths );
			return cacheArcLengths;
		}

		needsUpdate = false;

		var cache = [];
		var current;
		var last = getPoint( 0.0 );
		var sum = 0;

		cache.add( 0 );

		for ( var p = 1; p <= divisions; p ++ ) {

			current = getPoint ( p / divisions );

			var distance;

			// TODO(nelsonsilva) - Must move distanceTo to IVector interface os create a new IHasDistance
			if (current is Vector3) {
			  distance = (current as Vector3).absoluteError( last as Vector3 );
			} else {
      distance = (current as Vector2).absoluteError( last as Vector2);
    }

			sum += distance;
			cache.add( sum );
			last = current;

		}

		cacheArcLengths = cache;

		return cache; // { sums: cache, sum:sum }; Sum is in the last element.
	}

Vector2 getNormalVector(t) #

inherited from Curve2D
Vector2 getNormalVector( t ) {
 var vec = this.getTangent( t );
 return new Vector2( -vec.y , vec.x );
}

dynamic getPoint(t) #

getPoint ( t ) {

 var tx, ty;

 tx = ShapeUtils.b3( t, v0.x, v1.x, v2.x, v3.x );
 ty = ShapeUtils.b3( t, v0.y, v1.y, v2.y, v3.y );

 return new Vector2( tx, ty );

}

V getPointAt(u) #

inherited from Curve
V getPointAt( u ) {
		var t = getUtoTmapping( u );
		return getPoint( t );
	}

List<V> getPoints([num divisions = null, closedPath = false]) #

inherited from Curve
List<V> getPoints( [num divisions = null, closedPath = false] ) {

	  if (divisions == null) divisions = 5;

		var d, pts = [];

		for ( d = 0; d <= divisions; d ++ ) {
			pts.add( this.getPoint( d / divisions ) );
		}

		return pts;
	}

List<V> getSpacedPoints([num divisions = 5, closedPath = false]) #

inherited from Curve
List<V> getSpacedPoints( [num divisions = 5, closedPath = false] ) {


		var d, pts = [];

		for ( d = 0; d <= divisions; d ++ ) {
			pts.add( this.getPointAt( d / divisions ) );
		}

		return pts;
	}

dynamic getTangent(t) #

getTangent( t ) {

 var tx, ty;

 tx = CurveUtils.tangentCubicBezier( t, v0.x, v1.x, v2.x, v3.x );
 ty = CurveUtils.tangentCubicBezier( t, v0.y, v1.y, v2.y, v3.y );

 return new Vector2( tx, ty ).normalize();

}

V getTangentAt(u) #

inherited from Curve
V getTangentAt( u ) {
		var t = getUtoTmapping( u );
		return getTangent( t );
	}

List<V> getUPoints([List uList, closedPath = false]) #

inherited from Curve
List<V> getUPoints( [List uList , closedPath = false] ) {
 var pts = [];

 for ( var u in uList ) {
   pts.add( this.getPointAt( u ) );
 }

 return pts;
}

dynamic getUtoTmapping(u, {distance: null}) #

inherited from Curve
getUtoTmapping( u, {distance: null} ) {

		var arcLengths = getLengths();

		int i = 0, il = arcLengths.length;

		var targetArcLength; // The targeted u distance value to get

		if (distance != null) {
			targetArcLength = distance;
		} else {
			targetArcLength = u * arcLengths[ il - 1 ];
		}

		//var time = Date.now();

		// binary search for the index with largest value smaller than target u distance

		var low = 0, high = il - 1, comparison;

		while ( low <= high ) {

			i = ( low + ( high - low ) / 2 ).floor().toInt(); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats

			comparison = arcLengths[ i ] - targetArcLength;

			if ( comparison < 0 ) {

				low = i + 1;
				continue;

			} else if ( comparison > 0 ) {

				high = i - 1;
				continue;

			} else {

				high = i;
				break;

				// DONE

			}

		}

		i = high;

		//console.log('b' , i, low, high, Date.now()- time);

		if ( arcLengths[ i ] == targetArcLength ) {

			var t = i / ( il - 1 );
			return t;

		}

		// we could get finer grain at lengths, or use simple interpolatation between two points

		var lengthBefore = arcLengths[ i ];
	    var lengthAfter = arcLengths[ i + 1 ];

	    var segmentLength = lengthAfter - lengthBefore;

	    // determine where we are between the 'before' and 'after' points

	    var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;

	    // add that fractional amount to t

	    var t = ( i + segmentFraction ) / ( il -1 );

		return t;
	}

dynamic updateArcLengths() #

inherited from Curve
updateArcLengths() {
		needsUpdate = true;
		getLengths();
	}