def test_from_nurbs_python_curve_to_ezdxf_bspline():
    from geomdl.fitting import interpolate_curve
    curve = interpolate_curve([(0, 0), (0, 10), (10, 10), (10, 0)], degree=3)
    bspline = BSpline.from_nurbs_python_curve(curve)
    assert bspline.degree == 3
    assert len(bspline.control_points) == 4
    assert len(bspline.knots()) == 8  # count + order
예제 #2
0
        def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

            vertices_s = self.inputs['Vertices'].sv_get()
            degree_s = self.inputs['Degree'].sv_get()

            curves_out = []
            points_out = []
            knots_out = []
            for vertices, degree in zip_long_repeat(vertices_s, degree_s):
                if isinstance(degree, (tuple, list)):
                    degree = degree[0]

                curve = fitting.interpolate_curve(vertices,
                                                  degree,
                                                  centripetal=self.centripetal)

                points_out.append(curve.ctrlpts)
                knots_out.append(curve.knotvector)

                curve = SvGeomdlCurve(curve)
                curves_out.append(curve)

            self.outputs['Curve'].sv_set(curves_out)
            self.outputs['ControlPoints'].sv_set(points_out)
            self.outputs['Knots'].sv_set(knots_out)
예제 #3
0
def set_npoints(r, n):
	'''
	Set the number of contour points.
	
	Notes: 
	
	* The new contour points are calculated using NURBS interpolation.
	* The new contour points will be spaced equally from parametric position 0 to 1 around the contour.
	
	
	Inputs:
	
	* r : a single source contour as an (n,2) array or multiple source contours as an (m,) or (m,n,2) array
	* n : int, desired number of contour points
	
	Outputs:
	
	* r_new : contour shape(s) with n points, as an (n,2) or (m,n,2) array
	
	References:
	
	https://nurbs-python.readthedocs.io/en/latest/module_fitting.html
	'''
	pcurve    = fitting.interpolate_curve(list(r), 3)
	pcurve.sample_size = n
	return np.asarray( pcurve.evalpts )
예제 #4
0
파일: nurbs.py 프로젝트: Moult/sverchok
 def interpolate(cls, degree, points, metric='DISTANCE'):
     if metric not in {'DISTANCE', 'CENTRIPETAL'}:
         raise Exception("Unsupported metric")
     centripetal = metric == 'CENTRIPETAL'
     curve = fitting.interpolate_curve(points.tolist(),
                                       degree,
                                       centripetal=centripetal)
     return SvGeomdlCurve(curve)
예제 #5
0
 def _recalculate(self) -> None:
     if len(self.points) >= 3:
         self.t = np.linspace(0, 1, num=self.samples, endpoint=True)
         print(self.t.shape)
         self.curve = fitting.interpolate_curve(
             [point.to_tuple() for point in self.points], 2
         )
         self.curve_points = np.array(
             self.curve.evaluate_list(self.t)
         ).astype(np.int32).reshape((-1, 2))
         self.kd = spatial.KDTree(self.curve_points)
예제 #6
0
파일: nurbs.py 프로젝트: Moult/sverchok
 def interpolate_list(cls, degree, points, metric='DISTANCE'):
     if metric not in {'DISTANCE', 'CENTRIPETAL'}:
         raise Exception("Unsupported metric")
     centripetal = metric == 'CENTRIPETAL'
     curves = []
     for curve_points in points:
         curve = fitting.interpolate_curve(curve_points.tolist(),
                                           degree,
                                           centripetal=centripetal)
         curve = SvGeomdlCurve(curve)
         curves.append(curve)
     return curves
예제 #7
0
def manual_init(points, radius, pn=20, qn=8):
    trace = interpolate_curve(points, 3)
    rad_curve = interp1d([p[0] for p in points], radius)

    params = np.linspace(0, 1, pn).tolist()
    trace_binormal = np.array(trace.binormal(params))
    trace_tangent = np.array(trace.tangent(params))

    trace_points = []

    for tbi, tt in zip(trace_binormal, trace_tangent):
        for angle in np.linspace(0, 2 * np.pi, pn).tolist():
            r = R.from_rotvec(angle * tt[1])
            p = tbi[0] + rad_curve(tbi[0][0]) * r.apply(tbi[1])
            trace_points.append(p.tolist())

    return approximate_surface(trace_points,
                               pn,
                               pn,
                               3,
                               3,
                               ctrlpts_size_u=qn,
                               ctrlpts_size_v=qn)
예제 #8
0
    Examples for the NURBS-Python Package
    Released under MIT License
    Developed by Onur Rauf Bingol (c) 2018

    2-dimensional curve fitting by global interpolation
"""

from geomdl import fitting
from geomdl.visualization import VisMPL as vis

# The NURBS Book Ex9.1
points = ((0, 0), (3, 4), (-1, 4), (-4, 0), (-4, -3))
degree = 3  # cubic curve

# Do global curve interpolation
curve = fitting.interpolate_curve(points, degree)

# Plot the interpolated curve
curve.delta = 0.01
curve.vis = vis.VisCurve2D()
curve.render()

# # Visualize data and evaluated points together
# import numpy as np
# import matplotlib.pyplot as plt
# evalpts = np.array(curve.evalpts)
# pts = np.array(points)
# plt.plot(evalpts[:, 0], evalpts[:, 1])
# plt.scatter(pts[:, 0], pts[:, 1], color="red")
# plt.show()
예제 #9
0
    def interpolate_tow_points(self, target=None):
        """Takes in array of points, and interpolates in between them using geomdl package
        Interpoaltes to a level such that the distance between points is roughly equal to 
        $target_length (by default is t.w/2). Interpolates in batches, as large arrays can cause errors
        
        Parameters
        ----------
        target : float, optional
            target distance for point spacing, by default None
        
        """

        self.prev_pts = self.new_pts

        if target:
            target_length = target  #w/4
        else:
            target_length = self.interp_dist
        n_pts = len(self.new_pts[2])
        points = np.copy(self.new_pts)

        # Batch up sections for large tows
        batch = []
        batch_combine = [[], [], [], [], []]

        i = 0
        batch_sz = 200
        while (i + batch_sz < n_pts):
            tmp = points[:, i:i + batch_sz]
            batch.append(points[:, i:i + batch_sz])
            i += batch_sz - 1
        batch.append(points[:, i:])

        for b in batch:
            if len(b[2]) <= 2:  # If only two points - linear interpolation
                order = 1
            elif len(b[2]) == 3:  # If 3 poits - quadratic interpolation
                order = 2
            else:  # if > 3 pts - cubic interpolation
                order = 3

            # Get length of batch curve. Use middle line as basis
            v1s = np.array(b[2][1:])
            v2s = np.array(b[2][:-1])
            diff = v2s - v1s
            lengths = [np.linalg.norm(x) for x in diff]
            length = sum([np.linalg.norm(x) for x in diff
                          ])  #Get total length of distances between each point

            # Delta dictates how many 'evenly' spaced points the interpolation funciton will output.
            # Roughly equal to 1/n_points-1 - (e.g. delta = 0.01 --> 1/100 --> 101 points).
            # Delta must be < 1, so min() statement is too ensure this (bit hacky atm)
            delta = min(target_length / length, 0.99)

            # call the interpolate curve function
            for j in range(len(b)):
                curve = fit.interpolate_curve(b[j].tolist(), order)
                curve.delta = delta
                evalpts = curve.evalpts  #evalpts is the new list of interpolated points
                batch_combine[
                    j] += evalpts  #stich batches back together as created

        # Recheck new lengths for debugging
        v1s = np.array(batch_combine[2][1:])
        v2s = np.array(batch_combine[2][:-1])
        diff = v2s - v1s
        lengths = [np.linalg.norm(x) for x in diff]

        # Evalpts is of type list, need to return as numpy array
        self.new_pts = np.array(batch_combine)
예제 #10
0
 def make(vertices):
     curve = fitting.interpolate_curve(vertices,
                                       degree,
                                       centripetal=self.centripetal)
     return SvGeomdlCurve(curve)