Exemplo n.º 1
0
    def bspline(self,
                length: float,
                segments: int = 10,
                degree: int = 3,
                method: str = 'uniform') -> BSpline:
        """
        Approximate euler spiral as B-spline.

        Args:
            length: length of euler spiral
            segments: count of fit points for B-spline calculation
            degree: degree of BSpline
            method: calculation method for parameter vector t

        Returns:
            :class:`BSpline`

        """
        fit_points = list(self.approximate(length, segments=segments))
        spline = global_bspline_interpolation(fit_points,
                                              degree,
                                              method=method)
        knots = [v * length
                 for v in spline.knot_values()]  # scale knot values to length
        spline.basis.knots = knots
        return spline
Exemplo n.º 2
0
    def render_as_fit_points(self,
                             layout: 'BaseLayout',
                             degree: int = 3,
                             method: str = 'chord',
                             dxfattribs: dict = None) -> None:
        """
        Render a B-spline as 2D/3D :class:`~ezdxf.entities.Polyline`, where the definition points are fit points.

           - 2D spline vertices uses: :meth:`~ezdxf.layouts.BaseLayout.add_polyline2d`
           - 3D spline vertices uses: :meth:`~ezdxf.layouts.BaseLayout.add_polyline3d`

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            degree: degree of B-spline (order = `degree` + 1)
            method: "uniform", "distance"/"chord", "centripetal"/"sqrt_chord" or "arc"
                    calculation method for parameter t
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        """
        spline = global_bspline_interpolation(self.points,
                                              degree=degree,
                                              method=method)
        vertices = list(spline.approximate(self.segments))
        if any(vertex.z != 0. for vertex in vertices):
            layout.add_polyline3d(vertices, dxfattribs=dxfattribs)
        else:
            layout.add_polyline2d(vertices, dxfattribs=dxfattribs)
def test_check_values():
    test_points = [(0., 0.), (1., 2.), (3., 1.), (5., 3.)]
    spline = global_bspline_interpolation(test_points,
                                          degree=3,
                                          method='distance')
    result = list(spline.approximate(49))
    assert len(result) == 50
    for p1, p2 in zip(result, expected):
        assert isclose(p1[0], p2[0], abs_tol=1e-6)
        assert isclose(p1[1], p2[1], abs_tol=1e-6)
def test_bspline_interpolation(fit_points):
    spline = global_bspline_interpolation(fit_points, degree=3)
    assert len(spline.control_points) == len(fit_points)
    assert spline.t_array[0] == 0.
    assert spline.t_array[-1] == 1.
    assert len(spline.t_array) == len(fit_points)

    t_points = [spline.point(t) for t in spline.t_array]
    for p1, p2 in zip(t_points, fit_points):
        assert p1 == p2
Exemplo n.º 5
0
 def add_spline(degree=2, color=3):
     spline = global_bspline_interpolation(fit_points,
                                           degree=degree,
                                           method="distance")
     msp.add_polyline2d(
         spline.control_points,
         dxfattribs={
             "color": color,
             "linetype": "DASHED"
         },
     )
     msp.add_open_spline(
         spline.control_points,
         degree=spline.degree,
         dxfattribs={"color": color},
     )
Exemplo n.º 6
0
def spline_interpolation(vertices: Iterable['Vertex'], degree: int = 3, method: str = 'chord',
                         subdivide: int = 4) -> List[Vector]:
    """
    B-spline interpolation, vertices are fit points for the spline definition.

    Only method 'uniform', yields vertices at fit points.

    Args:
        vertices: fit points
        degree: degree of B-spline
        method: "uniform", "chord"/"distance", "centripetal"/"sqrt_chord" or "arc" calculation method for parameter t
        subdivide: count of sub vertices + 1, e.g. 4 creates 3 sub-vertices

    Returns: list of vertices

    """
    vertices = list(vertices)
    spline = global_bspline_interpolation(vertices, degree=degree, method=method)
    return list(spline.approximate(segments=(len(vertices) - 1) * subdivide))
Exemplo n.º 7
0
    def bspline(
        self,
        length: float,
        segments: int = 10,
        degree: int = 3,
        method: str = "uniform",
    ) -> BSpline:
        """Approximate euler spiral as B-spline.

        Args:
            length: length of euler spiral
            segments: count of fit points for B-spline calculation
            degree: degree of BSpline
            method: calculation method for parameter vector t

        Returns:
            :class:`BSpline`

        """
        length = float(length)
        fit_points = list(self.approximate(length, segments=segments))
        derivatives = [
            # Scaling derivatives by chord length (< real length) is suggested
            # by Piegl & Tiller.
            self.tangent(t).normalize(length)
            for t in _params(length, segments)
        ]
        spline = global_bspline_interpolation(
            fit_points, degree, method=method, tangents=derivatives
        )
        return BSpline(
            spline.control_points,
            spline.order,
            # Scale knot values to length:
            [v * length for v in spline.knots()],
        )
def test_bspline_interpolation_first_derivatives(fit_points):
    tangents = estimate_tangents(fit_points)
    spline = global_bspline_interpolation(fit_points,
                                          degree=3,
                                          tangents=tangents)
    assert len(spline.control_points) == 2 * len(fit_points)
Exemplo n.º 9
0
 def add_spline(degree=2, color=3):
     spline = global_bspline_interpolation(fit_points, degree=degree, method='distance')
     msp.add_polyline2d(spline.control_points, dxfattribs={'color': color, 'linetype': 'DASHED'})
     msp.add_open_spline(spline.control_points, degree=spline.degree, dxfattribs={'color': color})