Dart DocumentationthreeSplineCurve3

SplineCurve3 class


Spline 3D curve


class SplineCurve3 extends Curve3D {

 List<Vector3> points;

 SplineCurve3( [this.points] ) : super() {
   if (points == null) points = [];
 }

 Vector3 getPoint( t ) {

   var v = new Vector3.zero();
   var c = new List<int>(4);
   var point = ( points.length - 1 ) * t,
       intPoint = point.floor().toInt(),
       weight = point - intPoint;

   c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
   c[ 1 ] = intPoint;
   c[ 2 ] = intPoint  > points.length - 2 ? points.length - 1 : intPoint + 1;
   c[ 3 ] = intPoint  > points.length - 3 ? points.length - 1 : intPoint + 2;

   var pt0 = points[ c[0] ],
     pt1 = points[ c[1] ],
     pt2 = points[ c[2] ],
     pt3 = points[ c[3] ];

   v.x = CurveUtils.interpolate(pt0.x, pt1.x, pt2.x, pt3.x, weight);
   v.y = CurveUtils.interpolate(pt0.y, pt1.y, pt2.y, pt3.y, weight);
   v.z = CurveUtils.interpolate(pt0.z, pt1.z, pt2.z, pt3.z, weight);

   return v;

 }

}

Extends

Curve<Vector3> > Curve3D > SplineCurve3

Constructors

new SplineCurve3([List<Vector3> points]) #

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
SplineCurve3( [this.points] ) : super() {
 if (points == null) points = [];
}

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

List<Vector3> points #

List<Vector3> points

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.
	}

Vector3 getPoint(t) #

Vector3 getPoint( t ) {

 var v = new Vector3.zero();
 var c = new List<int>(4);
 var point = ( points.length - 1 ) * t,
     intPoint = point.floor().toInt(),
     weight = point - intPoint;

 c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
 c[ 1 ] = intPoint;
 c[ 2 ] = intPoint  > points.length - 2 ? points.length - 1 : intPoint + 1;
 c[ 3 ] = intPoint  > points.length - 3 ? points.length - 1 : intPoint + 2;

 var pt0 = points[ c[0] ],
   pt1 = points[ c[1] ],
   pt2 = points[ c[2] ],
   pt3 = points[ c[3] ];

 v.x = CurveUtils.interpolate(pt0.x, pt1.x, pt2.x, pt3.x, weight);
 v.y = CurveUtils.interpolate(pt0.y, pt1.y, pt2.y, pt3.y, weight);
 v.z = CurveUtils.interpolate(pt0.z, pt1.z, pt2.z, pt3.z, weight);

 return v;

}

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;
	}

V getTangent(t) #

inherited from Curve
V getTangent( t ) {

		var delta = 0.0001;
		var t1 = t - delta;
		var t2 = t + delta;

		// Capping in case of danger

		if ( t1 < 0 ) t1 = 0;
		if ( t2 > 1 ) t2 = 1;

		var pt1 = getPoint( t1 );
		var pt2 = getPoint( t2 );

		var vec = pt2 - pt1;
		return vec.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();
	}