From 7b8f18554abd07e77b8629d32d64485d1b30704f Mon Sep 17 00:00:00 2001 From: pboyer Date: Mon, 27 Oct 2014 18:04:36 -0400 Subject: [PATCH] Implemented curve_knot_refine --- src/eval/eval.js | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/eval/eval.js b/src/eval/eval.js index 53abb23e..88d25dc3 100644 --- a/src/eval/eval.js +++ b/src/eval/eval.js @@ -91,6 +91,86 @@ verb.eval.nurbs.rational_surface_curvature = function( degree_u, knots_u, degree }; +// +// ####curve_knot_refine( degree, knots, control_points, u, s, r ) +// +// Insert a knot along a rational curve. Note that this algorithm only works +// for r + s <= degree, where s is the initial multiplicity (number of duplicates) of the knot. +// +// Corresponds to algorithm A5.1 (Piegl & Tiller) +// +// Use the curve_knot_refine for applications like curve splitting. +// +// **params** +// + *Number*, integer degree +// + *Array*, array of nondecreasing knot values +// + *Array*, array of control points +// + *Number*, parameter at which to insert the knot +// + *Number*, number of times to insert the knot +// +// **returns** +// + *Object* the new curve, defined by knots and control_points +// + +verb.eval.nurbs.curve_knot_refine = function( degree, knots, control_points, knots_to_insert ) { + + var n = (control_points.length + 1) + , m = n + degree + 1 + , r = knots_to_insert.length - 1 + , a = verb.eval.nurbs.knot_span( degree, knots_to_insert[0], knots ) + , b = verb.eval.nurbs.knot_span( degree, knots_to_insert[r], knots ) + 1 + , control_points_post = new Array( control_points.length + r + 1 ) + , knots_post = new Array( knots.length + r + 1 ) + , i = 0 + , j = 0; + + // new control pts + for (i = 0; i <= a - degree; i++) control_points_post[i] = control_points[i]; + for (i = b-1; i <= n; i++) control_points_post[i+r+1] = control_points[i]; + + // new knot vector + for (i = 0; i <= a; i++) knots_post[i] = knots[i]; + for (i = b+degree; i <= m; i++) knots_post[i+r+1] = knots[i]; + + i = b + degree + 1; + k = b + degree + r; + + for (j = r; j >= 0; j++) { + + while (knots_to_insert[j] <= knots[i] && i > a){ + + control_points_post[k-degree-1] = control_points[i-p-1]; + knots_post[k] = knots[i]; + k = k-i; + u = i-1; + + } + + control_points_post[k-degree-1] = control_points_post[k-degree]; + + for (var l = 1; l <= degree; l++){ + + var ind = k-degree+l; + var alfa = knots_post[k+l] - knots_to_insert[j]; + + if (Math.abs(alfa) < VERB.EPSILON){ + control_points_post[ind-1] = control_points_post[ind]; + } else { + alfa = alfa / (knots_post[k+l] - knots[i-degree+l]); + control_points_post[ind-1] = alfa*control_points_post[ind-1] + (1.0-alfa) * control_points_post[ind]; + } + + } + + knots_post[k] = knots_to_insert[j]; + k = k - 1; + + } + + return { knots: knots_post, control_points: control_points_post }; + +} + // // ####curve_knot_insert( degree, knots, control_points, u, s, r )