def insert_knot(self, u_bar, count=1): # "The NURBS book", 2nd edition, p.5.2, eq. 5.11 s = sv_knotvector.find_multiplicity(self.knotvector, u_bar) #print(f"I: kv {len(self.knotvector)}{self.knotvector}, u_bar {u_bar} => s {s}") k = np.searchsorted(self.knotvector, u_bar, side='right') - 1 p = self.degree u = self.knotvector new_knotvector = sv_knotvector.insert(self.knotvector, u_bar, count) N = len(self.control_points) control_points = self.get_homogenous_control_points() for r in range(1, count + 1): prev_control_points = control_points control_points = [] for i in range(N + 1): #print(f"I: i {i}, k {k}, p {p}, r {r}, s {s}, k-p+r-1 {k-p+r-1}, k-s {k-s}") if i <= k - p + r - 1: point = prev_control_points[i] #print(f"P[{r},{i}] := {i}{prev_control_points[i]}") elif k - p + r <= i <= k - s: denominator = u[i + p - r + 1] - u[i] alpha = (u_bar - u[i]) / denominator point = alpha * prev_control_points[i] + ( 1.0 - alpha) * prev_control_points[i - 1] #print(f"P[{r},{i}]: alpha {alpha}, pts {i}{prev_control_points[i]}, {i-1}{prev_control_points[i-1]} => {point}") else: point = prev_control_points[i - 1] #print(f"P[{r},{i}] := {i-1}{prev_control_points[i-1]}") control_points.append(point) N += 1 control_points, weights = from_homogenous(np.array(control_points)) curve = SvNativeNurbsCurve(self.degree, new_knotvector, control_points, weights) return curve
def insert_knot(self, u_bar, count=1, if_possible=False): # "The NURBS book", 2nd edition, p.5.2, eq. 5.11 N = len(self.control_points) u = self.get_knotvector() s = sv_knotvector.find_multiplicity(u, u_bar) #print(f"I: kv {len(u)}{u}, u_bar {u_bar} => s {s}") #k = np.searchsorted(u, u_bar, side='right')-1 k = sv_knotvector.find_span(u, N, u_bar) p = self.get_degree() new_knotvector = sv_knotvector.insert(u, u_bar, count) control_points = self.get_homogenous_control_points() if (u_bar == u[0] or u_bar == u[-1]): if s + count > p + 1: if if_possible: count = (p + 1) - s else: raise CantInsertKnotException( f"Can't insert first/last knot t={u_bar} for {count} times" ) else: if s + count > p: if if_possible: count = p - s else: raise CantInsertKnotException( f"Can't insert knot t={u_bar} for {count} times") for r in range(1, count + 1): prev_control_points = control_points control_points = [] for i in range(N + 1): #print(f"I: i {i}, k {k}, p {p}, r {r}, s {s}, k-p+r-1 {k-p+r-1}, k-s {k-s}") if i <= k - p + r - 1: point = prev_control_points[i] #print(f"P[{r},{i}] := {i}{prev_control_points[i]}") elif k - p + r <= i <= k - s: denominator = u[i + p - r + 1] - u[i] if abs(denominator) < 1e-6: raise Exception( f"Can't insert the knot t={u_bar} for {i}th time: u[i+p-r+1]={u[i+p-r+1]}, u[i]={u[i]}, denom={denominator}" ) alpha = (u_bar - u[i]) / denominator point = alpha * prev_control_points[i] + ( 1.0 - alpha) * prev_control_points[i - 1] #print(f"P[{r},{i}]: alpha {alpha}, pts {i}{prev_control_points[i]}, {i-1}{prev_control_points[i-1]} => {point}") else: point = prev_control_points[i - 1] #print(f"P[{r},{i}] := {i-1}{prev_control_points[i-1]}") control_points.append(point) N += 1 control_points, weights = from_homogenous(np.array(control_points)) curve = SvNativeNurbsCurve(self.degree, new_knotvector, control_points, weights) return curve