def curve_from_grid(points, **kwargs): """ Make a Curve (of degree 3) as an approximation of a sequence of points. :param points - N x D array, D is dimension :param nt Prescribed number of poles of the resulting spline. :return: Curve object. TODO: - Measure efficiency. Estimate how good we can be. Do it our self if we can do at leas 10 times better. - Find out which method is used. Hoschek (4.4.1) refers to several methods how to determine parametrization of the curve, i.e. Find parameters t_i to the given approximation points P_i. - Further on it is not clear what is the mening of the 's' parameter and how one cna influence tolerance and smoothness. - Some sort of adaptivity is used. """ deg = kwargs.get('degree', 3) tol = kwargs.get('tol', 0.01) weights = np.ones(points.shape[0]) weights[0] = weights[-1] = 1000.0 tck = scipy.interpolate.splprep(points.T, k=deg, s=tol, w=weights)[0] knots, poles, degree = tck curve_poles = np.array(poles).T curve_poles[0] = points[0] curve_poles[-1] = points[-1] basis = bs.SplineBasis(degree, knots) curve = bs.Curve(basis, curve_poles) return curve
def plot_4p(self): degree = 2 poles = [[0., 0.], [1.0, 0.5], [2., -2.], [3., 1.]] basis = bs.SplineBasis.make_equidistant(degree, 2) curve = bs.Curve(basis, poles) plotting.plot_curve_2d(curve, poles=True) b00, b11 = curve.aabb() b01 = [b00[0], b11[1]] b10 = [b11[0], b00[1]] bb = np.array([b00, b10, b11, b01, b00]) plotting.plot_2d(bb[:, 0], bb[:, 1]) plotting.show()
def plotting_2d(self, plotting): # simple 2d graphs n_points = 201 eq_basis = bs.SplineBasis.make_equidistant(2, 4) x_coord = np.linspace(eq_basis.domain[0], eq_basis.domain[1], n_points) for i_base in range(eq_basis.size): y_coord = [ eq_basis.eval(i_base, x) for x in x_coord ] plotting.plot_2d(x_coord, y_coord) plotting.show() # 2d curves degree = 2 poles = [ [0., 0.], [1.0, 0.5], [2., -2.], [3., 1.] ] basis = bs.SplineBasis.make_equidistant(degree, 2) curve = bs.Curve(basis, poles) plotting.plot_curve_2d(curve, poles=True) poles = [[0., 0.], [-1.0, 0.5], [-2., -2.], [3., 1.]] basis = bs.SplineBasis.make_equidistant(degree, 2) curve = bs.Curve(basis, poles) plotting.plot_curve_2d(curve, poles=True) plotting.show()
def line(vtxs, overhang=0.0): ''' Return B-spline approximation of a line from two points :param vtxs: [ X0, X1 ], Xn are point coordinates in arbitrary dimension D :return: Curve2D ''' assert len(vtxs) == 2 vtxs = np.array(vtxs) if overhang > 0.0: dv = overhang * (vtxs[1] - vtxs[0]) vtxs[0] -= dv vtxs[1] += dv mid = np.mean(vtxs, axis=0) poles = [vtxs[0], mid, vtxs[1]] knots = 3 * [0.0 - overhang] + 3 * [1.0 + overhang] basis = bs.SplineBasis(2, knots) return bs.Curve(basis, poles)
def get_curves(v0, v1): n_points = 100 u_points = np.linspace(v0[0], v1[0], n_points) v_points = np.linspace(v0[1], v1[1], n_points) uv_points = np.stack((u_points, v_points), axis=1) xyz_points = bw_surface._bs_surface.eval_array(uv_points) curve_xyz = bs_approx.curve_from_grid(xyz_points) poles_z = curve_xyz.poles[:, 2].copy() x_diff, y_diff, z_diff = np.abs(xyz_points[-1] - xyz_points[0]) if x_diff > y_diff: axis = 0 else: axis = 1 poles_t = curve_xyz.poles[:, axis].copy() poles_t -= xyz_points[0][axis] poles_t /= (xyz_points[-1][axis] - xyz_points[0][axis]) poles_z -= base_point[2] poles_tz = np.stack((poles_t, poles_z), axis=1) curve_tz = bs.Curve(curve_xyz.basis, poles_tz) return bw.curve_from_bs(curve_tz), bw.curve_from_bs(curve_xyz)
def test_aabb(self): poles = [[0., 0.], [1.0, 0.5], [2., -2.], [3., 1.]] basis = bs.SplineBasis.make_equidistant(2, 2) curve = bs.Curve(basis, poles) box = curve.aabb() assert np.allclose(box, np.array([[0, -2], [3, 1]]))