Exemple #1
0
    def get_mult_and_knots(self, d):
        """
        Get an array of unique knot values for the curve and their
        multiplicities in the specified direction.

        :param str d: Direction to get knot multiplicities and values ('u'
            or 'v').

        :return: Number of unique knots, multiplicities, and the knots
            (nu, um, uq) in specified direction.
        :rtype: tuple
        """
        if d.lower() in ['u']:
            return find_mult_knots(self._n, self._p, self._uk)
        else:
            return find_mult_knots(self._m, self._q, self._vk)
Exemple #2
0
    def get_mult_and_knots(self):
        """
        Get an array of unique knots values for the curve and their
        multiplicities.

        :return: Number of unique knots, multiplicities, and the knots
            (nu, um, uq).
        :rtype: tuple
        """
        return find_mult_knots(self._n, self._p, self._uk)
Exemple #3
0
def elevate_nurbs_curve_degree(n, p, uk, cpw, t=1):
    """
    Elevate the degree of a NURBS curve *t* times.

    :param int n:
    :param int p:
    :param ndarray uk:
    :param ndarray cpw:
    :param int t:

    :return: New number of control points - 1, new knot vector, and the new
        control points of NURBS curve with elevated degree (nq, uq, qw).
    :rtype: tuple

    *Reference:* Algorithm A5.9 from "The NURBS Book."
    """
    m = n + p + 1
    ph = p + t
    ph2 = int(floor(ph / 2))
    bezalfs = zeros((p + t + 1, p + 1), dtype=float64)
    bezalfs[0, 0], bezalfs[ph, p] = 1.0, 1.0
    for i in range(1, ph2 + 1):
        inv = 1.0 / bin_coeff(ph, i)
        mpi = min(p, i)
        for j in range(max(0, i - t), mpi + 1):
            bezalfs[i, j] = inv * bin_coeff(p, j) * bin_coeff(t, i - j)
    for i in range(ph2 + 1, ph):
        mpi = min(p, i)
        for j in range(max(0, i - t), mpi + 1):
            bezalfs[i, j] = bezalfs[ph - i, p - j]
    mh = ph
    kind = ph + 1
    r = -1
    a = p
    b = p + 1
    cind = 1
    ua = uk[0]
    _, mult, _ = find_mult_knots(n, p, uk)
    s = mh
    for mi in mult[1:-1]:
        s += mi + t
    qw = zeros((s + 1, 4), dtype=float64)
    uq = zeros(s + ph + 2, dtype=float64)
    bpts = zeros((p + 1, 4), dtype=float64)
    nextbpts = zeros((p - 1, 4), dtype=float64)
    ebpts = zeros((p + t + 1, 4), dtype=float64)
    qw[0] = cpw[0]
    for i in range(0, ph + 1):
        uq[i] = ua
    for i in range(0, p + 1):
        bpts[i] = cpw[i]
    while b < m:
        i = b
        # while b < m and uk[b] == uk[b + 1]:
        while b < m and CmpFlt.eq(uk[b], uk[b + 1], Settings.ptol):
            b += 1
        mul = b - i + 1
        mh += mul + t
        ub = uk[b]
        oldr = r
        r = p - mul
        # Insert knot u[b] r times.
        if oldr > 0:
            lbz = int(floor((oldr + 2) / 2))
        else:
            lbz = 1
        if r > 0:
            rbz = ph - int(floor((r + 1) / 2))
        else:
            rbz = ph
        if r > 0:
            numer = ub - ua
            alfs = zeros(p - 1, dtype=float64)
            for k in range(p, mul, -1):
                alfs[k - mul - 1] = numer / (uk[a + k] - ua)
            for j in range(1, r + 1):
                sav = r - j
                s = mul + j
                for k in range(p, s - 1, -1):
                    bpts[k] = (alfs[k - s] * bpts[k] +
                               (1.0 - alfs[k - s]) * bpts[k - 1])
                nextbpts[sav] = bpts[p]
        for i in range(lbz, ph + 1):
            ebpts[i, :] = 0.0
            mpi = min(p, i)
            for j in range(max(0, i - t), mpi + 1):
                ebpts[i] += bezalfs[i, j] * bpts[j]
        if oldr > 1:
            first = kind - 2
            last = kind
            den = ub - ua
            bet = (ub - uq[kind - 1]) / den
            for tr in range(1, oldr):
                i = first
                j = last
                kj = j - kind + 1
                while j - i > tr:
                    if i < cind:
                        alf = (ub - uq[i]) / (ua - uq[i])
                        qw[i] = alf * qw[i] + (1.0 - alf) * qw[i - 1]
                    if j >= lbz:
                        if j - tr <= kind - ph + oldr:
                            gam = (ub - uq[j - tr]) / den
                            ebpts[kj] = (gam * ebpts[kj] +
                                         (1.0 - gam) * ebpts[kj + 1])
                        else:
                            ebpts[kj] = (bet * ebpts[kj] +
                                         (1.0 - bet) * ebpts[kj + 1])
                        i += 1
                        j -= 1
                        kj -= 1
                    first -= 1
                    last += 1
        if a != p:
            for i in range(0, ph - oldr):
                uq[kind] = ua
                kind += 1
        for j in range(lbz, rbz + 1):
            qw[cind] = ebpts[j]
            cind += 1
        if b < m:
            for j in range(0, r):
                bpts[j] = nextbpts[j]
            for j in range(r, p + 1):
                bpts[j] = cpw[b - p + j]
            a = b
            b += 1
            ua = ub
        else:
            for i in range(0, ph + 1):
                uq[kind + i] = ub
    nq = mh - ph - 1
    return nq, uq, qw