コード例 #1
0
 def test_complex_ellipse_with_spline_intersection(self):
     ellipse = ConstructionEllipse(center=(0, 0), major_axis=(3, 0), ratio=0.5)
     bspline = BSpline([(-4, -4), (-2, -1), (2, 1), (4, 4)])
     p1 = ellipse.flattening(distance=0.01)
     p2 = bspline.flattening(distance=0.01)
     res = intersect_polylines_2d(Vec2.list(p1), Vec2.list(p2))
     assert len(res) == 2
コード例 #2
0
    def from_arc(cls, entity: 'DXFGraphic') -> 'Spline':
        """ Create a new SPLINE entity from a CIRCLE, ARC or ELLIPSE entity.

        The new SPLINE entity has no owner, no handle, is not stored in
        the entity database nor assigned to any layout!

        """
        dxftype = entity.dxftype()
        if dxftype == 'ELLIPSE':
            ellipse = cast('Ellipse', entity).construction_tool()
        elif dxftype == 'CIRCLE':
            ellipse = ConstructionEllipse.from_arc(
                center=entity.dxf.get('center', NULLVEC),
                radius=abs(entity.dxf.get('radius', 1.0)),
                extrusion=entity.dxf.get('extrusion', Z_AXIS),
            )
        elif dxftype == 'ARC':
            ellipse = ConstructionEllipse.from_arc(
                center=entity.dxf.get('center', NULLVEC),
                radius=abs(entity.dxf.get('radius', 1.0)),
                extrusion=entity.dxf.get('extrusion', Z_AXIS),
                start_angle=entity.dxf.get('start_angle', 0),
                end_angle=entity.dxf.get('end_angle', 360))
        else:
            raise TypeError('CIRCLE, ARC or ELLIPSE entity required.')

        spline = Spline.new(dxfattribs=entity.graphic_properties(),
                            doc=entity.doc)
        s = BSpline.from_ellipse(ellipse)
        spline.dxf.degree = s.degree
        spline.dxf.flags = Spline.RATIONAL
        spline.control_points = s.control_points
        spline.knots = s.knots()
        spline.weights = s.weights()
        return spline
コード例 #3
0
def test_dxfattribs():
    e = ConstructionEllipse()
    attribs = e.dxfattribs()
    assert attribs['center'] == (0, 0, 0)
    assert attribs['major_axis'] == (1, 0, 0)
    assert 'minor_axis' not in attribs
    assert attribs['extrusion'] == (0, 0, 1)
    assert attribs['ratio'] == 1.0
    assert attribs['start_param'] == 0
    assert attribs['end_param'] == math.tau
コード例 #4
0
def test_dxfattribs():
    e = ConstructionEllipse()
    attribs = e.dxfattribs()
    assert attribs["center"] == (0, 0, 0)
    assert attribs["major_axis"] == (1, 0, 0)
    assert "minor_axis" not in attribs
    assert attribs["extrusion"] == (0, 0, 1)
    assert attribs["ratio"] == 1.0
    assert attribs["start_param"] == 0
    assert attribs["end_param"] == math.tau
コード例 #5
0
def test_swap_axis_full_ellipse():
    ellipse = ConstructionEllipse(
        major_axis=(5, 0, 0),
        ratio=2,
    )
    assert ellipse.minor_axis.isclose((0, 10, 0))

    ellipse.swap_axis()
    assert ellipse.ratio == 0.5
    assert ellipse.major_axis == (0, 10, 0)
    assert ellipse.minor_axis == (-5, 0, 0)
    assert ellipse.start_param == 0
    assert ellipse.end_param == math.pi * 2
コード例 #6
0
def test_tangents():
    e = ConstructionEllipse(center=(3, 3),
                            major_axis=(2, 0),
                            ratio=0.5,
                            start_param=0,
                            end_param=math.pi * 1.5)
    params = list(e.params(7))
    result = [(0.0, 1.0, 0.0), (-0.894427190999916, 0.447213595499958, 0.0),
              (-1.0, 3.061616997868383e-17, 0.0),
              (-0.894427190999916, -0.4472135954999579, 0.0),
              (-2.4492935982947064e-16, -1.0, 0.0),
              (0.8944271909999159, -0.44721359549995804, 0.0), (1.0, 0.0, 0.0)]
    for v, r in zip(e.tangents(params), result):
        assert v.isclose(r)
コード例 #7
0
def test_rational_spline_from_elliptic_arc_has_expected_parameters():
    ellipse = ConstructionEllipse(
        center=(1, 1),
        major_axis=(2, 0),
        ratio=0.5,
        start_param=0,
        end_param=math.pi / 2,
    )
    spline = rational_bspline_from_ellipse(ellipse)
    assert spline.degree == 2

    cpoints = spline.control_points
    assert len(cpoints) == 3
    assert cpoints[0].isclose((3, 1, 0))
    assert cpoints[1].isclose((3, 2, 0))
    assert cpoints[2].isclose((1, 2, 0))

    weights = spline.weights()
    assert len(weights) == 3
    assert weights[0] == 1.0
    assert weights[1] == math.cos(math.pi / 4)
    assert weights[2] == 1.0

    # as BSpline constructor()
    s2 = BSpline.from_ellipse(ellipse)
    assert spline.control_points == s2.control_points
コード例 #8
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()
コード例 #9
0
    def apply_construction_tool(self, e: ConstructionEllipse) -> 'Ellipse':
        """ Set ELLIPSE data from construction tool
        :class:`ezdxf.math.ConstructionEllipse`.

        """
        self.update_dxf_attribs(e.dxfattribs())
        return self  # floating interface
コード例 #10
0
ファイル: test_708a_path.py プロジェクト: Sean-Spark/ezdxf
def test_add_ellipse():
    from ezdxf.math import ConstructionEllipse
    ellipse = ConstructionEllipse(center=(3, 0),
                                  major_axis=(1, 0),
                                  ratio=0.5,
                                  start_param=0,
                                  end_param=math.pi)
    path = Path()
    tools.add_ellipse(path, ellipse)
    assert path.start == (4, 0)
    assert path.end == (2, 0)

    # set start point to end of ellipse
    path = Path(start=(2, 0))
    # add reversed ellipse, by default the start of
    # an empty path is set to the ellipse start
    tools.add_ellipse(path, ellipse, reset=False)
    assert path.start == (2, 0)
    assert path.end == (4, 0)

    path = Path()
    # add a line segment from (0, 0) to start of ellipse
    tools.add_ellipse(path, ellipse, reset=False)
    assert path.start == (0, 0)
    assert path.end == (2, 0)
コード例 #11
0
def test_from_arc():
    ellipse = ConstructionEllipse.from_arc(center=(2, 2, 2), radius=3)
    assert ellipse.center == (2, 2, 2)
    assert ellipse.major_axis == (3, 0, 0)
    assert ellipse.ratio == 1
    assert ellipse.start_param == 0
    assert math.isclose(ellipse.end_param, math.tau)
コード例 #12
0
    def apply_construction_tool(self, e: ConstructionEllipse) -> None:
        """
        Set ELLIPSE data from construction tool :class:`ezdxf.math.ConstructionEllipse`.

        .. versionadded:: 0.13

        """
        self.update_dxf_attribs(e.dxfattribs())
コード例 #13
0
def test_vertices():
    e = ConstructionEllipse(center=(3, 3), major_axis=(2, 0), ratio=0.5, start_param=0, end_param=math.pi * 1.5)
    params = list(e.params(7))
    result = [
        (5.0, 3.0, 0.0),
        (4.414213562373095, 3.7071067811865475, 0.0),
        (3.0, 4.0, 0.0),
        (1.585786437626905, 3.7071067811865475, 0.0),
        (1.0, 3.0, 0.0),
        (1.5857864376269046, 2.2928932188134525, 0.0),
        (3.0, 2.0, 0.0),
    ]
    for v, r in zip(e.vertices(params), result):
        assert v.isclose(r)

    v1, v2 = e.vertices([0, math.tau])
    assert v1 == v2
コード例 #14
0
def test_default_init():
    e = ConstructionEllipse()
    assert e.center == (0, 0, 0)
    assert e.major_axis == (1, 0, 0)
    assert e.minor_axis == (0, 1, 0)
    assert e.extrusion == (0, 0, 1)
    assert e.ratio == 1.0
    assert e.start_param == 0
    assert e.end_param == math.tau
コード例 #15
0
 def from_circle(cls, circle: 'Circle', segments: int = 1) -> 'Path':
     """ Returns a :class:`Path` from a :class:`~ezdxf.entities.Circle`. """
     path = cls()
     ellipse = ConstructionEllipse.from_arc(
         center=circle.dxf.center,
         radius=circle.dxf.radius,
         extrusion=circle.dxf.extrusion,
     )
     path.add_ellipse(ellipse, segments=segments, reset=True)
     return path
コード例 #16
0
ファイル: test_708_path.py プロジェクト: kloppen/ezdxf
def test_from_ellipse():
    from ezdxf.entities import Ellipse
    from ezdxf.math import ConstructionEllipse
    e = ConstructionEllipse(center=(3, 0), major_axis=(1, 0), ratio=0.5,
                            start_param=0, end_param=math.pi)
    ellipse = Ellipse.new()
    ellipse.apply_construction_tool(e)
    path = Path.from_ellipse(ellipse)
    assert path.start == (4, 0)
    assert path.end == (2, 0)
コード例 #17
0
def bezier4p_from_ellipse(func, count):
    ellipse = ConstructionEllipse(
        center=(1, 2),
        major_axis=(2, 0),
        ratio=0.5,
        start_param=0,
        end_param=math.tau,
    )
    for _ in range(count):
        list(func(ellipse))
コード例 #18
0
 def construction_tool(self) -> ConstructionEllipse:
     """Returns construction tool :class:`ezdxf.math.ConstructionEllipse`."""
     dxf = self.dxf
     return ConstructionEllipse(
         dxf.center,
         dxf.major_axis,
         dxf.extrusion,
         dxf.ratio,
         dxf.start_param,
         dxf.end_param,
     )
コード例 #19
0
 def add_arc_edge(edge):
     x, y, *_ = edge.center
     # from_arc() requires OCS data:
     ellipse = ConstructionEllipse.from_arc(
         center=(x, y, elevation),
         radius=edge.radius,
         extrusion=extrusion,
         start_angle=edge.start_angle,
         end_angle=edge.end_angle,
     )
     tools.add_ellipse(path, ellipse, reset=not bool(path))
コード例 #20
0
def _from_circle(circle: Circle, **kwargs) -> "Path":
    segments = kwargs.get("segments", 1)
    path = Path()
    radius = abs(circle.dxf.radius)
    if radius > 1e-12:
        ellipse = ConstructionEllipse.from_arc(
            center=circle.dxf.center,
            radius=radius,
            extrusion=circle.dxf.extrusion,
        )
        tools.add_ellipse(path, ellipse, segments=segments, reset=True)
    return path
コード例 #21
0
def test_rational_spline_from_complex_elliptic_arc():
    ellipse = ConstructionEllipse(
        center=(49.64089977339618, 36.43095770602131, 0.0),
        major_axis=(16.69099826506408, 6.96203799241026, 0.0),
        ratio=0.173450304570581,
        start_param=5.427509144462117,
        end_param=7.927025930557775,
    )
    curves = list(cubic_bezier_from_ellipse(ellipse))

    assert curves[0].control_points[0].isclose(ellipse.start_point)
    assert curves[1].control_points[-1].isclose(ellipse.end_point)
コード例 #22
0
 def add_ellipse_edge(edge):
     ocs_ellipse = edge.construction_tool()
     # ConstructionEllipse has WCS representation:
     ellipse = ConstructionEllipse(
         center=wcs(ocs_ellipse.center.replace(z=elevation)),
         major_axis=wcs(ocs_ellipse.major_axis),
         ratio=ocs_ellipse.ratio,
         extrusion=extrusion,
         start_param=ocs_ellipse.start_param,
         end_param=ocs_ellipse.end_param,
     )
     tools.add_ellipse(path, ellipse, reset=not bool(path))
コード例 #23
0
def _from_circle(circle: Circle, **kwargs) -> 'Path':
    segments = kwargs.get('segments', 1)
    path = Path()
    radius = abs(circle.dxf.radius)
    if not math.isclose(radius, 0):
        ellipse = ConstructionEllipse.from_arc(
            center=circle.dxf.center,
            radius=radius,
            extrusion=circle.dxf.extrusion,
        )
        tools.add_ellipse(path, ellipse, segments=segments, reset=True)
    return path
コード例 #24
0
def test_get_start_and_end_vertex():
    ellipse = ConstructionEllipse(
        center=(1, 2, 3),
        major_axis=(4, 3, 0),
        extrusion=(0, 0, -1),
        ratio=.7,
        start_param=math.pi / 2,
        end_param=math.pi,
    )

    start, end = list(ellipse.vertices([
        ellipse.start_param,
        ellipse.end_param,
    ]))
    # test values from BricsCAD
    assert start.isclose(Vec3(3.1, -0.8, 3), abs_tol=1e-6)
    assert end.isclose(Vec3(-3, -1, 3), abs_tol=1e-6)

    # for convenience, but vertices() is much more efficient:
    assert ellipse.start_point.isclose(Vec3(3.1, -0.8, 3), abs_tol=1e-6)
    assert ellipse.end_point.isclose(Vec3(-3, -1, 3), abs_tol=1e-6)
コード例 #25
0
ファイル: boundary_paths.py プロジェクト: Rahulghuge94/ezdxf
 def construction_tool(self) -> ConstructionEllipse:
     """Returns ConstructionEllipse() for the OCS representation."""
     return ConstructionEllipse(
         center=Vec3(self.center),
         major_axis=Vec3(self.major_axis),
         extrusion=Vec3(0, 0, 1),
         ratio=self.ratio,
         # 1. ConstructionEllipse() is always in ccw orientation
         # 2. Start- and end params are always stored in ccw orientation
         start_param=self.start_param,
         end_param=self.end_param,
     )
コード例 #26
0
 def from_arc(cls, arc: 'Arc', segments: int = 1) -> 'Path':
     """ Returns a :class:`Path` from an :class:`~ezdxf.entities.Arc`. """
     path = cls()
     ellipse = ConstructionEllipse.from_arc(
         center=arc.dxf.center,
         radius=arc.dxf.radius,
         extrusion=arc.dxf.extrusion,
         start_angle=arc.dxf.start_angle,
         end_angle=arc.dxf.end_angle,
     )
     path.add_ellipse(ellipse, segments=segments, reset=True)
     return path
コード例 #27
0
def test_params_from_vertices_random():
    center = Vector.random(5)
    major_axis = Vector.random(5)
    extrusion = Vector.random()
    ratio = 0.75
    e = ConstructionEllipse(center, major_axis, extrusion, ratio)

    params = [random.uniform(0.0001, math.tau - 0.0001) for _ in range(20)]
    vertices = e.vertices(params)
    new_params = e.params_from_vertices(vertices)
    for expected, param in zip(params, new_params):
        assert math.isclose(expected, param)

    # This creates the same vertex as v1 and v2
    v1, v2 = e.vertices([0, math.tau])
    assert v1.isclose(v2)

    # This should create the same param for v1 and v2, but
    # floating point inaccuracy produces unpredictable results:
    p1, p2 = e.params_from_vertices((v1, v2))

    assert math.isclose(p1, 0, abs_tol=1e-9) or math.isclose(
        p1, math.tau, abs_tol=1e-9)
    assert math.isclose(p2, 0, abs_tol=1e-9) or math.isclose(
        p2, math.tau, abs_tol=1e-9)
コード例 #28
0
def test_rational_spline_from_elliptic_arc_has_same_end_points():
    ellipse = ConstructionEllipse(
        center=(1, 1),
        major_axis=(2, 0),
        ratio=0.5,
        start_param=math.radians(30),
        end_param=math.radians(330),
    )
    start_point = ellipse.start_point
    end_point = ellipse.end_point
    spline = rational_bspline_from_ellipse(ellipse)
    assert start_point.isclose(spline.control_points[0])
    assert end_point.isclose(spline.control_points[-1])
コード例 #29
0
 def bulge_to(p1: Vec3, p2: Vec3, bulge: float):
     if p1.isclose(p2):
         return
     center, start_angle, end_angle, radius = bulge_to_arc(p1, p2, bulge)
     ellipse = ConstructionEllipse.from_arc(
         center, radius, Z_AXIS,
         math.degrees(start_angle),
         math.degrees(end_angle),
     )
     curves = list(cubic_bezier_from_ellipse(ellipse))
     if curves[0].control_points[0].isclose(p2):
         curves = _reverse_bezier_curves(curves)
     self.add_curves(curves)
コード例 #30
0
def test_swap_axis_arbitrary_params():
    random_tests_count = 100
    random.seed(0)

    for _ in range(random_tests_count):
        ellipse = ConstructionEllipse(
            # avoid (0, 0, 0) as major axis
            major_axis=(non_zero_random(), non_zero_random(), 0),
            ratio=2,
            start_param=random.uniform(0, math.tau),
            end_param=random.uniform(0, math.tau),
            extrusion=(0, 0, random.choice((1, -1))),
        )

        # Test if coordinates of start- and end point stay at the same location
        # before and after swapping axis.
        start_point = ellipse.start_point
        end_point = ellipse.end_point
        minor_axis = ellipse.minor_axis
        ellipse.swap_axis()
        assert ellipse.major_axis.isclose(minor_axis, abs_tol=1e-9)
        assert ellipse.start_point.isclose(start_point, abs_tol=1e-9)
        assert ellipse.end_point.isclose(end_point, abs_tol=1e-9)