Пример #1
0
    def from_spline(
        cls,
        spline: BSpline,
        start_width: float,
        end_width: float,
        segments: int,
    ) -> "CurvedTrace":
        """
        Create curved trace from a B-spline.

        Args:
            spline: :class:`~ezdxf.math.BSpline` object
            start_width: start width
            end_width: end width
            segments: count of segments for approximation

        """
        curve_trace = cls()
        count = segments + 1
        t = linspace(0, spline.max_t, count)
        for ((point, derivative),
             width) in zip(spline.derivatives(t, n=1),
                           linspace(start_width, end_width, count)):
            normal = Vec2(derivative).orthogonal(True)
            curve_trace._append(Vec2(point), normal, width)
        return curve_trace
Пример #2
0
    def from_arc(cls,
                 arc: ConstructionArc,
                 start_width: float,
                 end_width: float,
                 segments: int = 64) -> 'CurvedTrace':
        """
        Create curved trace from an arc.

        Args:
            arc: :class:`~ezdxf.math.ConstructionArc` object
            start_width: start width
            end_width: end width
            segments: count of segments for full circle (360 degree) approximation, partial arcs have proportional
                      less segments, but at least 3

        Raises:
            ValueError: if arc.radius <= 0

        """
        if arc.radius <= 0:
            raise ValueError(f'Invalid radius: {arc.radius}.')
        curve_trace = cls()
        count = max(math.ceil(arc.angle_span / 360.0 * segments), 3) + 1
        center = Vec2(arc.center)
        for point, width in zip(arc.vertices(arc.angles(count)),
                                linspace(start_width, end_width, count)):
            curve_trace._append(point, point - center, width)
        return curve_trace
Пример #3
0
    def draw_elliptic_arc_entity_3d(self, entity: DXFGraphic) -> None:
        dxf, dxftype = entity.dxf, entity.dxftype()
        properties = self._resolve_properties(entity)

        if dxftype in {'CIRCLE', 'ARC'}:
            center = dxf.center  # ocs transformation in .from_arc()
            radius = dxf.radius
            if dxftype == 'CIRCLE':
                start_angle = 0
                end_angle = 360
            else:
                start_angle = dxf.start_angle
                end_angle = dxf.end_angle
            e = ConstructionEllipse.from_arc(center, radius, dxf.extrusion,
                                             start_angle, end_angle)
        elif dxftype == 'ELLIPSE':
            e = cast(Ellipse, entity).construction_tool()
        else:
            raise TypeError(dxftype)

        # Approximate as 3D polyline
        segments = int((e.end_param - e.start_param) / math.tau *
                       self.circle_approximation_count)
        points = list(
            e.vertices(
                linspace(e.start_param, e.end_param, max(4, segments + 1))))
        self.out.start_path()
        for a, b in zip(points, points[1:]):
            self.out.draw_line(a, b, properties)
        self.out.end_path()
Пример #4
0
 def build():
     circle = Circle()
     vertices = list(circle.vertices(linspace(0, 360, vertex_count, endpoint=False)))
     m = Matrix44.chain(
         Matrix44.axis_rotate(axis=Vec3.random(), angle=random.uniform(0, math.tau)),
         Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)),
     )
     return synced_transformation(circle, vertices, m)
Пример #5
0
def circle(radius=1, count=16):
    circle_ = Circle.new(dxfattribs={
        'center': (0, 0, 0),
        'radius': radius
    },
                         doc=doc)
    control_vertices = list(circle_.vertices(linspace(0, 360, count)))
    return circle_, control_vertices
Пример #6
0
def test_rational_spline_curve_points_by_nurbs_python():
    arc = ConstructionArc(end_angle=90)
    spline = rational_bspline_from_arc(end_angle=arc.end_angle)
    curve = spline.to_nurbs_python_curve()

    t = list(linspace(0, 1, 10))
    points = list(spline.points(t))
    expected = list(curve.evaluate_list(t))
    for p, e in zip(points, expected):
        assert p.isclose(e)
Пример #7
0
def test_rational_spline_derivatives_by_nurbs_python():
    arc = ConstructionArc(end_angle=90)
    spline = rational_bspline_from_arc(end_angle=arc.end_angle)
    curve = spline.to_nurbs_python_curve()

    t = list(linspace(0, 1, 10))
    derivatives = list(spline.derivatives(t, n=1))
    expected = [curve.derivatives(u, 1) for u in t]
    for (p, d1), (e, ed1) in zip(derivatives, expected):
        assert p.isclose(e)
        assert d1.isclose(ed1)
Пример #8
0
    def divide(self, count: int) -> Iterator[Vec3]:
        """Returns `count` interpolated vertices along the polyline.
        Argument `count` has to be greater than 2 and the start- and end
        vertices are always included.

        """
        if count < 2:
            raise ValueError(f"invalid count: {count}")
        vertex_at = self._vertex_at
        for distance in linspace(0.0, self.length, count):
            yield vertex_at(distance)
Пример #9
0
 def __init__(
     self,
     curve: SupportsPointMethod,
     *,
     max_t: float = 1.0,
     segments: int = 100,
 ):
     assert hasattr(curve, "point")
     assert segments > 0
     self._polyline = ConstructionPolyline(
         curve.point(t) for t in linspace(0.0, max_t, segments + 1))
     self._max_t = max_t
     self._step = max_t / segments
Пример #10
0
    def flattening(self, sagitta: float) -> Iterator[Vec2]:
        """Approximate the circle by vertices, argument `sagitta` is the
        max. distance from the center of an arc segment to the center of its
        chord. Returns a closed polygon where the start vertex is coincident
        with the end vertex!

        .. versionadded:: 0.17.1

        """
        from .arc import arc_segment_count

        count = arc_segment_count(self.radius, math.tau, sagitta)
        yield from self.vertices(linspace(0.0, math.tau, count + 1))
Пример #11
0
def get_params(start: float, end: float, num: int) -> Iterable[float]:
    """Returns `num` params from start- to end param in counter clockwise order.

    All params are normalized in the range from [0, 2π).

    """
    if num < 2:
        raise ValueError("num >= 2")
    if end <= start:
        end += math.tau

    for param in linspace(start, end, num):
        yield param % math.tau
Пример #12
0
    def angles(self, num: int) -> Iterable[float]:
        """ Returns `num` angles from start- to end angle in degrees in counter clockwise order.

        All angles are normalized in the range from [0, 360).

        """
        if num < 2:
            raise ValueError('num >= 2')
        start = self.dxf.start_angle % 360
        stop = self.dxf.end_angle % 360
        if stop <= start:
            stop += 360
        for angle in linspace(start, stop, num=num, endpoint=True):
            yield angle % 360
Пример #13
0
    def flattening(self, sagitta: float) -> Iterable[Vec3]:
        """Approximate the circle by vertices in WCS, argument `sagitta` is the
        max. distance from the center of an arc segment to the center of its
        chord. Returns a closed polygon: start vertex == end vertex!

        Yields always :class:`~ezdxf.math.Vec3` objects.

        .. versionadded:: 0.15

        """
        radius = abs(self.dxf.radius)
        if radius > 0.0:
            count = arc_segment_count(radius, math.tau, sagitta)
            yield from self.vertices(linspace(0.0, 360.0, count + 1))
Пример #14
0
def test_random_ellipse_transformations(sx, sy, sz, start, end):
    vertex_count = 8

    for angle in linspace(0, math.tau, 19):
        for dx, dy, dz in product([2, 0, -2], repeat=3):
            axis = Vec3.random()  # TODO: fixed rotation axis

            config = f"CONFIG sx={sx}, sy={sy}, sz={sz}; " \
                     f"start={start:.4f}, end={end:.4f}; angle={angle};" \
                     f"dx={dx}, dy={dy}, dz={dz}; axis={str(axis)}"
            ellipse0, vertices0 = build(angle, dx, dy, dz, axis, start, end,
                                        vertex_count)
            assert check(ellipse0, vertices0, vertex_count) is True, config
            ellipse1, vertices1 = synced_scaling(ellipse0, vertices0, sx, sy,
                                                 sz)
            assert check(ellipse1, vertices1, vertex_count) is True, config
Пример #15
0
def profile_bspline_point_new(count, spline):
    for _ in range(count):
        for t in linspace(0, 1.0, 100):
            spline.point(t)
Пример #16
0
def profile_vertex_calculation(count, spline, num):
    for _ in range(count):
        for t in linspace(0.0, spline.max_t, num):
            spline.point(t)
Пример #17
0
def test_params():
    count = 9
    e = ConstructionEllipse(start_param=math.pi / 2, end_param=-math.pi / 2)
    params = list(e.params(count))
    expected = list(linspace(math.pi / 2, math.pi / 2.0 * 3.0, count))
    assert params == expected
Пример #18
0
def profile_bspline_derivatives_new(count, spline):
    for _ in range(count):
        list(spline.derivatives(t=linspace(0, 1.0, 100)))
Пример #19
0
def sine_wave(count: int, scale: float = 1.0) -> Iterable[Vec3]:
    for t in linspace(0, math.tau, count):
        yield Vec3(t * scale, math.sin(t) * scale)
Пример #20
0
def t_vector():
    return list(linspace(0, max(KNOTS), 20))
Пример #21
0
def sine_wave(count: int, scale: float = 1.0):
    for t in linspace(0, math.tau, count):
        yield Vector(t * scale, math.sin(t) * scale)
Пример #22
0
def bspline_points_rational(cls, count):
    for curve in splines:
        weights = [1.0] * curve.count
        spline = cls(curve, weights)
        for u in linspace(0, spline.basis.max_t, count):
            spline.point(u)
Пример #23
0
def bspline_points(cls, count):
    for curve in splines:
        spline = cls(curve)
        for u in linspace(0, spline.basis.max_t, count):
            spline.point(u)
Пример #24
0
def bspline_multi_points(cls, count):
    for curve in splines:
        spline = cls(curve)
        list(spline.points(linspace(0, spline.basis.max_t, count)))
Пример #25
0
def bspline_multi_derivative(cls, count):
    for curve in splines:
        spline = cls(curve)
        list(spline.derivatives(linspace(0, spline.basis.max_t, count), 1))
Пример #26
0
def bspline_derivative(cls, count):
    for curve in splines:
        spline = cls(curve)
        for u in linspace(0, spline.basis.max_t, count):
            spline.derivative(u, 1)