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)
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)
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