File: arc_from_spline.py

package info (click to toggle)
ezdxf 1.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 104,528 kB
  • sloc: python: 182,341; makefile: 116; lisp: 20; ansic: 4
file content (96 lines) | stat: -rw-r--r-- 2,764 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# Copyright (c) 2021-2022, Manfred Moitzi
# License: MIT License
import pathlib
import ezdxf
from ezdxf import zoom
from ezdxf.math import ConstructionArc, BSpline

CWD = pathlib.Path("~/Desktop/Outbox").expanduser()
if not CWD.exists():
    CWD = pathlib.Path(".")

# ------------------------------------------------------------------------------
# This is a more theoretical example which shows how to recreate an ARC entity
# from a SPLINE entity, assuming the SPLINE represents an ARC.
# ------------------------------------------------------------------------------

doc = ezdxf.new()
msp = doc.modelspace()

# create the source ARC:
arc = msp.add_arc(
    (0, 0),
    radius=5,
    start_angle=15,
    end_angle=165,
    dxfattribs={
        "layer": "source arc",
        "color": ezdxf.const.RED,
    },
)

# create a SPLINE entity from ARC, in your scenario these are the source
# entities of your DXF document!
spline = msp.add_spline(
    dxfattribs={
        "layer": "B-Spline",
        "color": ezdxf.const.YELLOW,
    }
)
# create a B-spline construction tool from ARC
arc_tool = arc.construction_tool()
bspline = BSpline.from_arc(arc_tool)
spline.apply_construction_tool(bspline)

# ------------------------------------------------------------------------------
# Recreate ARC from SPLINE, if you ASSUME or KNOW it represents an ARC:
# for spline in msp.query("SPLINE):
#     ...
# ------------------------------------------------------------------------------

# 1. get the B-spline construction tool from the SPLINE entity
bspline = spline.construction_tool()
max_t = bspline.max_t

# calculate 3 significant points and 2 check points of the SPLINE:
start, chk1, middle, chk2, end = bspline.points(
    [0, max_t * 0.25, max_t * 0.5, max_t * 0.75, max_t]
)

# create an arc from 3 points:
arc_tool = ConstructionArc.from_3p(start, end, middle)
arc_tool.add_to_layout(
    msp,
    dxfattribs={
        "layer": "recreated arc",
        "color": ezdxf.const.MAGENTA,
    },
)

# This only works for flat B-splines in the xy-plane, a.k.a. 2D splines!

# Verify the assumption:
center = arc_tool.center
radius = arc_tool.radius
err = max(abs(radius - p.distance(center)) for p in (chk1, chk2))
print(f"max error: {err:.6f}")

# Warning: this does not proof that the assumption was correct, it's always
# possible to create a diverging B-spline which matches the check points:

foul = (4.5, 1)
fit_points = [start, foul, chk1, middle, chk2, end]
msp.add_spline(
    fit_points,
    dxfattribs={
        "layer": "foul B-spline",
        "color": ezdxf.const.RED,
    },
)

# add checkmarks
for p in fit_points:
    msp.add_circle(p, radius=0.03, dxfattribs={"color": ezdxf.const.RED})

zoom.objects(msp, [arc])
doc.saveas(CWD / "arc_recreation.dxf")