コード例 #1
0
ファイル: forms.py プロジェクト: Yonniee/ezdxf
def spline_interpolation(vertices: Iterable['Vertex'],
                         degree: int = 3,
                         method: str = 'uniform',
                         power: float = .5,
                         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', 'distance' or 'centripetal', calculation method for parameter t
        power: power for 'centripetal', default is distance ^ .5
        subdivide: count of sub vertices + 1, e.g. 4 creates 3 sub-vertices

    Returns: list of vertices

    """
    vertices = list(vertices)
    spline = bspline_control_frame(vertices,
                                   degree=degree,
                                   method=method,
                                   power=power)
    return list(spline.approximate(segments=(len(vertices) - 1) * subdivide))
コード例 #2
0
    def render_as_fit_points(self,
                             layout: 'BaseLayout',
                             degree: int = 3,
                             method: str = 'distance',
                             power: float = .5,
                             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'`` or ``'centripetal'``, calculation method for parameter t
            power: power for ``'centripetal'``, default = ``0.5``
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        """
        spline = bspline_control_frame(self.points,
                                       degree=degree,
                                       method=method,
                                       power=power)
        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)
コード例 #3
0
    def render_as_fit_points(self, layout: 'GenericLayoutType', degree: int = 3, method: str = 'distance',
                             power: float = .5, dxfattribs: dict = None) -> None:
        """
        Render a B-spline as 2d/3d polyline, where the definition points are fit points.

           - 2d points in -> add_polyline2d()
           - 3d points in -> add_polyline3d()

        To get vertices at fit points, use method='uniform' and use Spline.subdivide(count), where
        count is the sub-segment count, count=4, means 4 line segments between two definition points.

        Args:
            layout: ezdxf layout
            degree: degree of B-spline
            method: 'uniform', 'distance' or 'centripetal', calculation method for parameter t
            power: power for 'centripetal', default is distance ^ .5
            dxfattribs: DXF attributes for POLYLINE

        """
        spline = bspline_control_frame(self.points, degree=degree, method=method, power=power)
        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)
コード例 #4
0
def test_check_values():
    test_points = [(0., 0.), (1., 2.), (3., 1.), (5., 3.)]
    spline = bspline_control_frame(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)
コード例 #5
0
def test_control_frame(fit_points):
    spline = bspline_control_frame(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
コード例 #6
0
ファイル: hatch.py プロジェクト: ptmcg/ezdxf
 def add_spline_control_frame(self, fit_points: Iterable[Tuple[float, float]],
                              degree: int = 3,
                              method: str = 'distance',
                              power: float = .5) -> 'SplineEdge':
     bspline = bspline_control_frame(fit_points=fit_points, degree=degree, method=method, power=power)
     return self.add_spline(
         fit_points=fit_points,
         control_points=bspline.control_points,
         knot_values=bspline.knot_values(),
     )
コード例 #7
0
 def add_spline(degree=2, color=3):
     spline = bspline_control_frame(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})
コード例 #8
0
    def bspline(self, length: float, segments: int = 10, degree: int = 3, method: str = 'uniform') -> BSpline:
        """
        Approximate euler spiral by 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

        """
        fit_points = list(self.approximate(length, segments=segments))
        spline = bspline_control_frame(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