def fit_bezier_spline(points, bezier_func, n): '''Fit the current points with a spline made by the following bezier function. n representes the number of bezier function to be used.''' n_params = utils.get_number_arguments(bezier_func) - 2 chunks = list(split_list(points, len(points) // n)) cpoints = [] for chunk in chunks: # We force the passage from the first and last point to grant continuity. first_knot = tuple(chunk[0]) last_knot = tuple(chunk[-1]) shadow_functions = [ lambda t, *params: bezier_func( t, *((first_knot[0], ) + params + (last_knot[0], ))), lambda t, *params: bezier_func( t, *((first_knot[1], ) + params + (last_knot[1], ))), lambda t, *params: bezier_func( t, *((first_knot[2], ) + params + (last_knot[2], ))) ] estimated_cpoints = __fit_bezier_curve_funcs( chunk, shadow_functions, [[1.0] * n_params, [1.0] * n_params, [1.0] * n_params]) cpoints += [[first_knot] + estimated_cpoints + [last_knot]] return cpoints
def generate_spline(cpoints, func): '''Generate a spline from a series of control points and a function''' nargs = utils.get_number_arguments(func) result = [] for cps in __split_cpoints(cpoints, nargs): if len(cps) == nargs: result.append(BaseCurve(cps, func)) else: #TODO This is bad. This just fixes the number of verts, but it should be managed properly. added_verts = tuple([cps[-1]] * (nargs - len(cps))) result.append(BaseCurve(cps + added_verts, func)) return SuperCurve(result)
def test_get_arguments(self): self.assertEquals(utils.get_number_arguments(mmath.bezier_curve_2), 3) self.assertEquals(utils.get_number_arguments(mmath.bezier_curve_3), 4)