def test_periodic_boundary_evaluation(self): # Issue #66: "From left evaluations crash on periodic basis" b = BSplineBasis(3, [0,0,0,1,2,3,4,4,4]) x = b.evaluate(t=0, from_right=False) self.assertAlmostEqual(x[0,0], 0.0) x = b.evaluate(t=0, from_right=True) self.assertAlmostEqual(x[0,0], 1.0) b = BSplineBasis(3, [-1,0,0,1,2,3,4,4,5], periodic=0) x = b.evaluate(t=0, d=1, from_right=False) self.assertAlmostEqual(x[0, 0], 2.0) self.assertAlmostEqual(x[0,-1], -2.0)
def test_periodic_boundary_evaluation(self): # Issue #66: "From left evaluations crash on periodic basis" b = BSplineBasis(3, [0,0,0,1,2,3,4,4,4]) x = b.evaluate(t=0, from_right=False) self.assertAlmostEqual(x[0,0], 0.0) x = b.evaluate(t=0, from_right=True) self.assertAlmostEqual(x[0,0], 1.0) b = BSplineBasis(3, [-1,0,0,1,2,3,4,4,5], periodic=0) x = b.evaluate(t=0, d=1, from_right=False) self.assertAlmostEqual(x[0, 0], 2.0) self.assertAlmostEqual(x[0,-1], -2.0)
def rebuild(self, p, n): """ Creates an approximation to this curve by resampling it using a uniform knot vector of order *p* with *n* control points. :param int p: Polynomial discretization order :param int n: Number of control points :return: A new approximate curve :rtype: Curve """ # establish uniform open knot vector knot = [0] * p + list(range(1, n - p + 1)) + [n - p + 1] * p basis = BSplineBasis(p, knot) # set parametric range of the new basis to be the same as the old one basis.normalize() t0 = self.bases[0].start() t1 = self.bases[0].end() basis *= (t1 - t0) basis += t0 # fetch evaluation points and solve interpolation problem t = basis.greville() N = basis.evaluate(t, sparse=True) controlpoints = splinalg.spsolve(N, self.evaluate(t)) # return new resampled curve return Curve(basis, controlpoints)
def rebuild(self, p, n): """Creates an approximation to this curve by resampling it using a uniform knot vector of order *p* with *n* control points. :param int p: Polynomial discretization order :param int n: Number of control points :return: A new approximate curve :rtype: Curve """ # establish uniform open knot vector knot = [0] * p + list(range(1, n - p + 1)) + [n - p + 1] * p basis = BSplineBasis(p, knot) # set parametric range of the new basis to be the same as the old one basis.normalize() t0 = self.bases[0].start() t1 = self.bases[0].end() basis *= t1 - t0 basis += t0 # fetch evaluation points and solve interpolation problem t = basis.greville() N = basis.evaluate(t) controlpoints = np.linalg.solve(N, self.evaluate(t)) # return new resampled curve return Curve(basis, controlpoints)
def camber(M, P, order=5): """ Create the NACA centerline used for wing profiles. This is given as an exact quadratic piecewise polynomial y(x), see http://airfoiltools.com/airfoil/naca4digit. The method will produce one of two representations: For order<5 it will create x(t)=t and for order>4 it will create x(t) as qudratic in t and stretched towards the endpointspoints creating a more optimized parametrization. :param M: Max camber height (y) given as percentage 0% to 9% of length :type M: Int 0<M<10 :param P: Max camber position (x) given as percentage 0% to 90% of length :type P: Int 0<P<10 :return : Exact centerline representation :rtype : Curve """ # parametrized by x=t or x="t^2" if order>4 M = M / 100.0 P = P / 10.0 basis = BSplineBasis(order) # basis.insert_knot([P]*(order-2)) # insert a C1-knot for i in range(order - 2): basis.insert_knot(P) t = basis.greville() n = len(t) x = np.zeros((n, 2)) for i in range(n): if t[i] <= P: if order > 4: x[i, 0] = t[i]**2 / P else: x[i, 0] = t[i] x[i, 1] = M / P / P * (2 * P * x[i, 0] - x[i, 0] * x[i, 0]) else: if order > 4: x[i, 0] = (t[i]**2 - 2 * t[i] + P) / (P - 1) else: x[i, 0] = t[i] x[i, 1] = M / (1 - P) / (1 - P) * (1 - 2 * P + 2 * P * x[i, 0] - x[i, 0] * x[i, 0]) N = basis.evaluate(t) controlpoints = np.linalg.solve(N, x) return Curve(basis, controlpoints)