pyroll-core 3.2.0b1__tar.gz → 3.2.0b2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/PKG-INFO +1 -1
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/__init__.py +1 -15
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/__init__.py +0 -14
- pyroll_core-3.2.0b2/pyroll/core/grooves/angles/__init__.py +8 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/angles/_geometry.py +8 -20
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/angles/_path.py +0 -30
- pyroll_core-3.2.0b2/pyroll/core/grooves/angles/butterfly_groove.py +544 -0
- pyroll_core-3.2.0b2/pyroll/core/grooves/angles/factories.py +67 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/asymmetric_two_roll_pass.py +28 -3
- pyroll_core-3.2.0b1/pyroll/core/grooves/angles/__init__.py +0 -19
- pyroll_core-3.2.0b1/pyroll/core/grooves/angles/_contours.py +0 -73
- pyroll_core-3.2.0b1/pyroll/core/grooves/angles/butterfly_groove.py +0 -312
- pyroll_core-3.2.0b1/pyroll/core/grooves/angles/closed_groove.py +0 -213
- pyroll_core-3.2.0b1/pyroll/core/grooves/angles/edger_groove.py +0 -120
- pyroll_core-3.2.0b1/pyroll/core/grooves/angles/factories.py +0 -242
- pyroll_core-3.2.0b1/pyroll/core/grooves/angles/finisher_groove.py +0 -74
- pyroll_core-3.2.0b1/pyroll/core/grooves/angles/preforming_groove.py +0 -94
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/.gitignore +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/LICENSE +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/README.md +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/hatch.toml +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyproject.toml +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/config.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/disk_elements/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/disk_elements/disk_element_unit.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/disk_elements/hookimpls.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/engine/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/engine/engine.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/engine/hookimpls.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/base.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/boxes/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/boxes/box.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/boxes/constricted_box.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/boxes/upset_box.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/diamonds/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/diamonds/diamond.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/diamonds/gothic.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/diamonds/square.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/equivalent_ripped_groove.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/flat.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/generic_angle.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/generic_elongation.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/generic_elongation_solvers.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/hexagonal.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/circular_oval.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/constricted_circular_oval.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/constricted_swedish_oval.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/flat_oval.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/oval_3radii.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/oval_3radii_flanked.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/swedish_oval.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/ovals/upset_oval.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/rounds/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/rounds/false_round.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/rounds/round.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/grooves/spline.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/hooks.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/log.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/profile/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/profile/hookimpls.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/profile/profile.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/repr.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll/hookimpls.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll/roll.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/asymmetric_two_roll_pass.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/base.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/deformation_unit.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/base_roll_pass.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/deformation_unit.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/disk_element.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/engine.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/helpers.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/profile.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/roll.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/symmetric_roll_pass.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/three_roll_pass.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/hookimpls/two_roll_pass.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/symmetric_roll_pass.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/three_roll_pass.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/roll_pass/two_roll_pass.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/rotator/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/rotator/hookimpls.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/rotator/rotator.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/sequence/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/sequence/hookimpls.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/sequence/sequence.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/shapes.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/transport/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/transport/cooling_pipe.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/transport/hookimpls/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/transport/hookimpls/cooling_pipe.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/transport/hookimpls/spooler.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/transport/hookimpls/transport.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/transport/spooler.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/transport/transport.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/unit/__init__.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/unit/hookimpls.py +0 -0
- {pyroll_core-3.2.0b1 → pyroll_core-3.2.0b2}/pyroll/core/unit/unit.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyroll-core
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.0b2
|
|
4
4
|
Summary: PyRoll rolling simulation framework - core library.
|
|
5
5
|
Project-URL: Homepage, https://pyroll-project.github.io
|
|
6
6
|
Project-URL: Repository, https://github.com/pyroll-project/pyroll-core
|
|
@@ -24,15 +24,8 @@ from .grooves import (
|
|
|
24
24
|
FlatGroove,
|
|
25
25
|
HexagonalGroove,
|
|
26
26
|
EquivalentRibbedGroove,
|
|
27
|
-
PreformingGroove,
|
|
28
|
-
EdgerGroove,
|
|
29
|
-
FinisherGroove,
|
|
30
|
-
ClosedGroove,
|
|
31
27
|
ButterflyGroove,
|
|
32
28
|
GroovePair,
|
|
33
|
-
precontour_grooves,
|
|
34
|
-
finisher_grooves,
|
|
35
|
-
closed_grooves,
|
|
36
29
|
butterfly_grooves,
|
|
37
30
|
create_groove_by_type_name,
|
|
38
31
|
)
|
|
@@ -62,7 +55,7 @@ from .hooks import Hook, HookHost, HookFunction, root_hooks
|
|
|
62
55
|
from .disk_elements import DiskElementUnit
|
|
63
56
|
from .config import Config, config, PlottingBackend, ConfigValue, ConfigMeta
|
|
64
57
|
|
|
65
|
-
VERSION = "3.2.
|
|
58
|
+
VERSION = "3.2.0b2"
|
|
66
59
|
|
|
67
60
|
__all__ = [
|
|
68
61
|
# grooves
|
|
@@ -89,15 +82,8 @@ __all__ = [
|
|
|
89
82
|
"FlatGroove",
|
|
90
83
|
"HexagonalGroove",
|
|
91
84
|
"EquivalentRibbedGroove",
|
|
92
|
-
"PreformingGroove",
|
|
93
|
-
"EdgerGroove",
|
|
94
|
-
"FinisherGroove",
|
|
95
|
-
"ClosedGroove",
|
|
96
85
|
"ButterflyGroove",
|
|
97
86
|
"GroovePair",
|
|
98
|
-
"precontour_grooves",
|
|
99
|
-
"finisher_grooves",
|
|
100
|
-
"closed_grooves",
|
|
101
87
|
"butterfly_grooves",
|
|
102
88
|
"create_groove_by_type_name",
|
|
103
89
|
# profile
|
|
@@ -8,15 +8,8 @@ from .boxes import BoxGroove, ConstrictedBoxGroove, UpsetBoxGroove, ConstrictedU
|
|
|
8
8
|
|
|
9
9
|
from .diamonds import DiamondGroove, SquareGroove, GothicGroove
|
|
10
10
|
from .angles import (
|
|
11
|
-
PreformingGroove,
|
|
12
|
-
EdgerGroove,
|
|
13
|
-
FinisherGroove,
|
|
14
|
-
ClosedGroove,
|
|
15
11
|
ButterflyGroove,
|
|
16
12
|
GroovePair,
|
|
17
|
-
precontour_grooves,
|
|
18
|
-
finisher_grooves,
|
|
19
|
-
closed_grooves,
|
|
20
13
|
butterfly_grooves,
|
|
21
14
|
)
|
|
22
15
|
from .ovals import (
|
|
@@ -62,15 +55,8 @@ __all__ = [
|
|
|
62
55
|
"FlatGroove",
|
|
63
56
|
"HexagonalGroove",
|
|
64
57
|
"EquivalentRibbedGroove",
|
|
65
|
-
"PreformingGroove",
|
|
66
|
-
"EdgerGroove",
|
|
67
|
-
"FinisherGroove",
|
|
68
|
-
"ClosedGroove",
|
|
69
58
|
"ButterflyGroove",
|
|
70
59
|
"GroovePair",
|
|
71
|
-
"precontour_grooves",
|
|
72
|
-
"finisher_grooves",
|
|
73
|
-
"closed_grooves",
|
|
74
60
|
"butterfly_grooves",
|
|
75
61
|
"GenericAngleGroove",
|
|
76
62
|
"create_groove_by_type_name",
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Constructive geometry toolkit for building groove contours from lines, fillets and arcs.
|
|
3
|
-
|
|
4
|
-
Port of the Matlab angle roll pass design suite by Christian Overhagen (UDE),
|
|
5
|
-
see ``winkelkaliber_matlab/``. Lines are represented in homogeneous coordinates
|
|
6
|
-
``(a, b, c)`` with ``a * z + b * y + c = 0``. Points are ``numpy`` arrays ``(z, y)``.
|
|
7
|
-
|
|
8
|
-
Instead of the Matlab origin-relative offset flags (``'i'``/``'a'``/``tausch``),
|
|
9
|
-
all constructions take explicit hint points (``toward``) selecting the side on
|
|
10
|
-
which an offset, fillet or intersection lies.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
1
|
from typing import Tuple
|
|
14
2
|
|
|
15
3
|
import numpy as np
|
|
@@ -48,7 +36,7 @@ def line_through(p1, p2) -> Line:
|
|
|
48
36
|
|
|
49
37
|
|
|
50
38
|
def line_point_angle(p, angle: float) -> Line:
|
|
51
|
-
"""Line through a point with given angle measured from the vertical axis
|
|
39
|
+
"""Line through a point with given angle measured from the vertical axis.
|
|
52
40
|
|
|
53
41
|
:param angle: angle to the y-axis in radians
|
|
54
42
|
"""
|
|
@@ -68,7 +56,7 @@ def vertical_line(z: float) -> Line:
|
|
|
68
56
|
|
|
69
57
|
|
|
70
58
|
def intersect(g1: Line, g2: Line) -> Point:
|
|
71
|
-
"""Intersection point of two lines
|
|
59
|
+
"""Intersection point of two lines."""
|
|
72
60
|
d = g1[0] * g2[1] - g2[0] * g1[1]
|
|
73
61
|
if np.isclose(d, 0):
|
|
74
62
|
raise ValueError("Lines are parallel, no intersection exists.")
|
|
@@ -90,7 +78,7 @@ def signed_distance(g: Line, p) -> float:
|
|
|
90
78
|
|
|
91
79
|
|
|
92
80
|
def offset_toward(g: Line, dist: float, toward) -> Line:
|
|
93
|
-
"""Parallel line at given distance, shifted towards the hint point
|
|
81
|
+
"""Parallel line at given distance, shifted towards the hint point."""
|
|
94
82
|
g = _normalized(g)
|
|
95
83
|
side = np.sign(signed_distance(g, toward))
|
|
96
84
|
if side == 0:
|
|
@@ -107,7 +95,7 @@ def perpendicular_foot(g: Line, p) -> Point:
|
|
|
107
95
|
|
|
108
96
|
def fillet_line_line(g1: Line, g2: Line, radius: float, toward, toward2=None) -> Tuple[Point, Point, Point]:
|
|
109
97
|
"""
|
|
110
|
-
Fillet circle of given radius tangent to two lines
|
|
98
|
+
Fillet circle of given radius tangent to two lines.
|
|
111
99
|
|
|
112
100
|
:param toward: hint point on the side of ``g1`` where the fillet center lies
|
|
113
101
|
:param toward2: hint point on the side of ``g2`` where the fillet center lies, defaults to ``toward``
|
|
@@ -146,7 +134,7 @@ def fillet_corner(g1: Line, g2: Line, radius: float, along1, along2) -> Tuple[Po
|
|
|
146
134
|
|
|
147
135
|
|
|
148
136
|
def line_circle_intersection(g: Line, k: Circle, toward) -> Point:
|
|
149
|
-
"""Intersection of a line and a circle nearest to the hint point
|
|
137
|
+
"""Intersection of a line and a circle nearest to the hint point."""
|
|
150
138
|
g = _normalized(g)
|
|
151
139
|
m = np.array([k[0], k[1]])
|
|
152
140
|
r = k[2]
|
|
@@ -157,7 +145,7 @@ def line_circle_intersection(g: Line, k: Circle, toward) -> Point:
|
|
|
157
145
|
|
|
158
146
|
foot_point = m - d * g[:2]
|
|
159
147
|
half_chord = np.sqrt(max(r**2 - d**2, 0))
|
|
160
|
-
direction = np.array([-g[1], g[0]])
|
|
148
|
+
direction = np.array([-g[1], g[0]])
|
|
161
149
|
|
|
162
150
|
candidates = [foot_point + half_chord * direction, foot_point - half_chord * direction]
|
|
163
151
|
toward = np.asarray(toward, dtype=float)
|
|
@@ -191,7 +179,7 @@ def fillet_line_circle(
|
|
|
191
179
|
g: Line, k: Circle, radius: float, toward, externally: bool = True
|
|
192
180
|
) -> Tuple[Point, Point, Point]:
|
|
193
181
|
"""
|
|
194
|
-
Fillet circle of given radius tangent to a line and a circle
|
|
182
|
+
Fillet circle of given radius tangent to a line and a circle.
|
|
195
183
|
|
|
196
184
|
:param toward: hint point selecting the offset side of the line and the solution branch
|
|
197
185
|
:param externally: whether the fillet touches the circle from outside (default) or inside
|
|
@@ -214,7 +202,7 @@ def fillet_line_circle(
|
|
|
214
202
|
def arc_points(center, start, end, count: int) -> np.ndarray:
|
|
215
203
|
"""
|
|
216
204
|
Discretize the circular arc from start to end point around center,
|
|
217
|
-
always sweeping the smaller angle
|
|
205
|
+
always sweeping the smaller angle.
|
|
218
206
|
|
|
219
207
|
:return: array of shape (count, 2) including start and end point
|
|
220
208
|
"""
|
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Common contour construction method for the angle groove family.
|
|
3
|
-
|
|
4
|
-
All groove designs of the Matlab suite (``winkelkaliber_matlab``) and of the Startschenko
|
|
5
|
-
angle profile method (``Winkelprofile_CR/calculations.py``) construct their contours the
|
|
6
|
-
same way: as a chain of straight segments and circular arcs, where the arcs are either
|
|
7
|
-
|
|
8
|
-
- *fillets* tangent to their two neighboring carriers (Matlab ``spgkg``/``spgkk``), or
|
|
9
|
-
- *carrier arcs* on explicitly placed circles (ground arcs, Startschenko ``Rf``/``Rt``/``Ri``).
|
|
10
|
-
|
|
11
|
-
This module provides that method as two layers:
|
|
12
|
-
|
|
13
|
-
- :py:func:`chain_contour` — low level: assemble a point array from explicit
|
|
14
|
-
line/arc steps (mirrors the Matlab ``gerade_kon``/``kreis_kon`` assembly and the
|
|
15
|
-
piecewise contour functions of the Startschenko method), and
|
|
16
|
-
- :py:func:`build_filleted_contour` — high level: declare carriers (lines and circles)
|
|
17
|
-
with a transition radius at each junction; tangent points are resolved automatically.
|
|
18
|
-
|
|
19
|
-
Carriers are the primitives of :py:mod:`._geometry`: lines as homogeneous coordinate
|
|
20
|
-
``numpy`` arrays, circles as ``(center_z, center_y, radius)`` tuples. The distinction is
|
|
21
|
-
made by type: ``numpy.ndarray`` → line, ``tuple`` → circle.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
1
|
from typing import Sequence, Union
|
|
25
2
|
|
|
26
3
|
import numpy as np
|
|
@@ -77,14 +54,12 @@ def _nominal_vertex(c1: Carrier, c2: Carrier, toward) -> np.ndarray:
|
|
|
77
54
|
try:
|
|
78
55
|
return geo.line_circle_intersection(line, circle, toward)
|
|
79
56
|
except ValueError:
|
|
80
|
-
# separated: nominal junction between the closest points
|
|
81
57
|
center = np.array([circle[0], circle[1]])
|
|
82
58
|
foot = geo.perpendicular_foot(line, center)
|
|
83
59
|
direction = foot - center
|
|
84
60
|
direction = direction / np.hypot(*direction)
|
|
85
61
|
return (foot + center + circle[2] * direction) / 2
|
|
86
62
|
|
|
87
|
-
# circle-circle: tangency point on the center line
|
|
88
63
|
m1 = np.array([c1[0], c1[1]])
|
|
89
64
|
m2 = np.array([c2[0], c2[1]])
|
|
90
65
|
direction = m2 - m1
|
|
@@ -178,20 +153,16 @@ def build_filleted_contour(start, path: Sequence, end, hints: dict = None) -> np
|
|
|
178
153
|
start = np.asarray(start, dtype=float)
|
|
179
154
|
end = np.asarray(end, dtype=float)
|
|
180
155
|
|
|
181
|
-
# nominal junction vertices, resolved sequentially from the start
|
|
182
156
|
vertices = []
|
|
183
157
|
ref = start
|
|
184
158
|
for c1, c2 in zip(carriers[:-1], carriers[1:]):
|
|
185
159
|
if not _is_line(c1):
|
|
186
|
-
# the contour left the circle carrier on the far side of where it entered:
|
|
187
|
-
# take the entry's antipode as the proximity hint
|
|
188
160
|
ref = 2 * np.array([c1[0], c1[1]]) - ref
|
|
189
161
|
ref = _nominal_vertex(c1, c2, ref)
|
|
190
162
|
vertices.append(ref)
|
|
191
163
|
|
|
192
164
|
ref_points = [start, *vertices, end]
|
|
193
165
|
|
|
194
|
-
# resolve each junction to (entry point, arc steps, exit point)
|
|
195
166
|
steps = []
|
|
196
167
|
for i, radius in enumerate(radii):
|
|
197
168
|
c1, c2 = carriers[i], carriers[i + 1]
|
|
@@ -225,7 +196,6 @@ def build_filleted_contour(start, path: Sequence, end, hints: dict = None) -> np
|
|
|
225
196
|
approach = [("line", t1)] if _is_line(c1) else [("arc", (c1[0], c1[1]), t1)]
|
|
226
197
|
steps.append((approach + [("arc", center, t2)], t2))
|
|
227
198
|
|
|
228
|
-
# final leg on the last carrier
|
|
229
199
|
last = carriers[-1]
|
|
230
200
|
final_step = ("line", end) if _is_line(last) else ("arc", (last[0], last[1]), end)
|
|
231
201
|
|