def test_kink(self):
        # Should refuse to differentiate splines with kinks

        spl2 = insert(0.5, self.spl, m=2)
        splder(spl2, 2)  # Should work
        assert_raises(ValueError, splder, spl2, 3)

        spl2 = insert(0.5, self.spl, m=3)
        splder(spl2, 1)  # Should work
        assert_raises(ValueError, splder, spl2, 2)

        spl2 = insert(0.5, self.spl, m=4)
        assert_raises(ValueError, splder, spl2, 1)
Exemplo n.º 2
0
    def test_kink(self):
        # Should refuse to differentiate splines with kinks

        spl2 = insert(0.5, self.spl, m=2)
        splder(spl2, 2)  # Should work
        assert_raises(ValueError, splder, spl2, 3)

        spl2 = insert(0.5, self.spl, m=3)
        splder(spl2, 1)  # Should work
        assert_raises(ValueError, splder, spl2, 2)

        spl2 = insert(0.5, self.spl, m=4)
        assert_raises(ValueError, splder, spl2, 1)
Exemplo n.º 3
0
    def to_bezier(self, match_curves_to_points=False, smooth=True):
        """Convert the contour into a sequence of cubic Bezier curves.

        NOTE: There may be fewer Bezier curves than points in the contour, if the
        contour is sufficiently smooth. To ensure that each point interval in the
        contour corresponds to a returned curve, set 'match_curves_to_points' to
        True.

        Output:
            A list of cubic Bezier curves.
            Each Bezier curve is an array of shape (4,2); thus the curve includes the
            starting point, the two control points, and the endpoint.
        """
        if smooth:
            size = self.size().max()
            s = 0.00001 * size
        else:
            s = 0
        tck, u = self.to_spline(smoothing=s)
        if match_curves_to_points:
            #to_insert = numpy.setdiff1d(u, numpy_compat.unique(tck[0]))#-------note wwk------the numpy_compat.py are removed
            to_insert = numpy.setdiff1d(u, numpy.unique(tck[0]))
            for i in to_insert:
                tck = fitpack.insert(i, tck, per=True)
        return utility_tools.b_spline_to_bezier_series(tck, per=True)
Exemplo n.º 4
0
def b_spline_to_bezier_series(tck, per=False):
    """Convert a parametric b-spline into a sequence of Bezier curves of the same degree.
 
  Inputs:
    tck : (t,c,k) tuple of b-spline knots, coefficients, and degree returned by splprep.
    per : if tck was created as a periodic spline, per *must* be true, else per *must* be false.
 
  Output:
    A list of Bezier curves of degree k that is equivalent to the input spline.
    Each Bezier curve is an array of shape (k+1,d) where d is the dimension of the
    space; thus the curve includes the starting point, the k-1 internal control
    points, and the endpoint, where each point is of d dimensions.


    from http://mail.scipy.org/pipermail/scipy-dev/2007-February/006651.html
    (actually, I got it from http://old.nabble.com/bezier-curve-through-set-of-2D-points-td27158642.html
    
  """
    from scipy.interpolate.fitpack import insert
    from numpy import asarray, unique, split, sum, transpose
    t, c, k = tck
    t = asarray(t)
    try:
        c[0][0]
    except:
        # I can't figure out a simple way to convert nonparametric splines to
        # parametric splines. Oh well.
        raise TypeError("Only parametric b-splines are supported.")
    new_tck = tck
    if per:
        # ignore the leading and trailing k knots that exist to enforce periodicity
        knots_to_consider = unique(t[k:-k])
    else:
        # the first and last k+1 knots are identical in the non-periodic case, so
        # no need to consider them when increasing the knot multiplicities below
        knots_to_consider = unique(t[k + 1:-k - 1])
    # For each unique knot, bring it's multiplicity up to the next multiple of k+1
    # This removes all continuity constraints between each of the original knots,
    # creating a set of independent Bezier curves.
    desired_multiplicity = k + 1
    for x in knots_to_consider:
        current_multiplicity = sum(t == x)
        remainder = current_multiplicity % desired_multiplicity
        if remainder != 0:
            # add enough knots to bring the current multiplicity up to the desired multiplicity
            number_to_insert = desired_multiplicity - remainder
            new_tck = insert(x, new_tck, number_to_insert, per)
    tt, cc, kk = new_tck
    # strip off the last k+1 knots, as they are redundant after knot insertion
    bezier_points = transpose(cc)[:-desired_multiplicity]
    if per:
        # again, ignore the leading and trailing k knots
        bezier_points = bezier_points[k:-k]
    # group the points into the desired bezier curves
    return split(bezier_points,
                 len(bezier_points) / desired_multiplicity,
                 axis=0)
Exemplo n.º 5
0
def b_spline_to_bezier_series(tck, per=False):
    """Convert a parametric b-spline into a sequence of Bezier curves of the same degree.
    
    By Zachary Pincus, from http://mail.scipy.org/pipermail/scipy-dev/2007-February/006651.html
    
    Inputs:
        tck : (t,c,k) tuple of b-spline knots, coefficients, and degree returned by splprep.
        per : if tck was created as a periodic spline, per *must* be true, else per *must* be false.
    
    Output:
        A list of Bezier curves of degree k that is equivalent to the input spline.
        Each Bezier curve is an array of shape (k+1,d) where d is the dimension of the
        space; thus the curve includes the starting point, the k-1 internal control
        points, and the endpoint, where each point is of d dimensions.
    """
    t, c, k = tck
    t = np.asarray(t)
    try:
        c[0][0]
    except:
        # I can't figure out a simple way to convert nonparametric splines to
        # parametric splines. Oh well.
        raise TypeError("Only parametric b-splines are supported.")
    new_tck = tck
    if per:
        # ignore the leading and trailing k knots that exist to enforce periodicity
        knots_to_consider = np.unique(t[k:-k])
    else:
        # the first and last k+1 knots are identical in the non-periodic case, so
        # no need to consider them when increasing the knot multiplicities below
        knots_to_consider = np.unique(t[k + 1:-k - 1])
    # For each np.unique knot, bring it's multiplicity up to the next multiple of k+1
    # This removes all continuity constraints between each of the original knots,
    # creating a set of independent Bezier curves.
    desired_multiplicity = k + 1
    for x in knots_to_consider:
        current_multiplicity = np.sum(t == x)
        remainder = current_multiplicity % desired_multiplicity
        if remainder != 0:
            # add enough knots to bring the current multiplicity up to the desired multiplicity
            number_to_insert = desired_multiplicity - remainder
            new_tck = fitpack.insert(x, new_tck, number_to_insert, per)
    tt, cc, kk = new_tck
    # strip off the last k+1 knots, as they are redundant after knot insertion
    # correction: except for short curves -LK
    bezier_points = np.transpose(cc)
    if len(bezier_points)>desired_multiplicity:
        bezier_points = bezier_points[:-desired_multiplicity]
        
    if per:
        # again, ignore the leading and trailing k knots
        bezier_points = bezier_points[k:-k]
    # group the points into the desired bezier curves
    return np.split(bezier_points, len(bezier_points) / desired_multiplicity, axis=0)