coil-geom 0.1.0__py3-none-any.whl
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.
coil_geom/__init__.py
ADDED
|
File without changes
|
coil_geom/coil_geom.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Drawing Coil
|
|
3
|
+
02/04/2026
|
|
4
|
+
Uisang hwang
|
|
5
|
+
'''
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
_norm_vec = lambda v: np.sqrt(v[0]**2+v[1]**2)
|
|
10
|
+
_norm_pnt = lambda v1,v2: np.sqrt(v1**2+v2**2)
|
|
11
|
+
|
|
12
|
+
class CoilGeom():
|
|
13
|
+
def __init__(self, cx=1, cy=1, r=1,
|
|
14
|
+
r_dist = 1.3,
|
|
15
|
+
p_dist = 0.7,
|
|
16
|
+
ncoil = 5,
|
|
17
|
+
):
|
|
18
|
+
|
|
19
|
+
self.r = r
|
|
20
|
+
self.cx = cx
|
|
21
|
+
self.cy = cy
|
|
22
|
+
self.c1x = cx
|
|
23
|
+
self.c1y = cy
|
|
24
|
+
self.c2x = r+r*r_dist
|
|
25
|
+
self.c2y = cy
|
|
26
|
+
self.r_dist = r_dist
|
|
27
|
+
self.p_dist = p_dist
|
|
28
|
+
self.ncoil = ncoil
|
|
29
|
+
|
|
30
|
+
self._create()
|
|
31
|
+
|
|
32
|
+
def _create(self):
|
|
33
|
+
self._v1 = np.array([self.c1x, self.c1y], dtype='float32')
|
|
34
|
+
self._v2 = np.array([self.c2x, self.c2y], dtype='float32')
|
|
35
|
+
self._v3 = self._v2-self._v1
|
|
36
|
+
|
|
37
|
+
self._v4 = self._v3*0.5
|
|
38
|
+
h = np.sqrt(self.r**2-self._v4[0]**2)
|
|
39
|
+
|
|
40
|
+
_c = np.cos(np.deg2rad(-90))
|
|
41
|
+
_s = np.sin(np.deg2rad(-90))
|
|
42
|
+
_r = np.array([[_c, -_s], [_s, _c]])
|
|
43
|
+
|
|
44
|
+
self._v5 = np.dot(_r, self._v4)
|
|
45
|
+
self._v5 = self._v5/np.linalg.norm(self._v5)*h
|
|
46
|
+
|
|
47
|
+
self.v1 = self._v1
|
|
48
|
+
self.v2 = self._v2
|
|
49
|
+
self.v3 = np.array([self.v1[0],
|
|
50
|
+
self.v1[1],
|
|
51
|
+
self.v1[0]+self._v3[0],
|
|
52
|
+
self.v1[1]+self._v3[1]])
|
|
53
|
+
self.v4 = np.array([self.v1[0],
|
|
54
|
+
self.v1[1],
|
|
55
|
+
self.v1[0]+self._v4[0],
|
|
56
|
+
self.v1[1]+self._v4[1]])
|
|
57
|
+
self.v5 = np.array([self.v1[0]+self._v4[0],
|
|
58
|
+
self.v1[1]+self._v4[1],
|
|
59
|
+
self.v1[0]+self._v4[0]+self._v5[0],
|
|
60
|
+
self.v1[1]+self._v4[1]+self._v5[1]])
|
|
61
|
+
self.vt = self.v4+self.v5
|
|
62
|
+
self.theta = np.atan2(self.vt[3]-self.vt[1], self.vt[2]-self.vt[0])
|
|
63
|
+
|
|
64
|
+
# Find fillet circle
|
|
65
|
+
self._P = self._v5*self.p_dist
|
|
66
|
+
L = _norm_pnt(_norm_vec(self._P),_norm_vec(self._v4))
|
|
67
|
+
R = self.r
|
|
68
|
+
self.r_fillet = np.abs(R-L)
|
|
69
|
+
self.P = np.array([self.v4[2],
|
|
70
|
+
self.v4[3],
|
|
71
|
+
self.v4[2]+self._P[0],
|
|
72
|
+
self.v4[3]+self._P[1]])
|
|
73
|
+
V = self.P[2:]-self._v1
|
|
74
|
+
uv=V/_norm_vec(V)
|
|
75
|
+
f1 = self.r_fillet*uv
|
|
76
|
+
|
|
77
|
+
V = self.P[2:]-self._v2
|
|
78
|
+
uv=V/_norm_vec(V)
|
|
79
|
+
f2 = self.r_fillet*uv
|
|
80
|
+
|
|
81
|
+
self.P1 = np.array([self.P[2],
|
|
82
|
+
self.P[3],
|
|
83
|
+
self.P[2]+f1[0],
|
|
84
|
+
self.P[3]+f1[1]])
|
|
85
|
+
self.P2 = np.array([self.P[2],
|
|
86
|
+
self.P[3],
|
|
87
|
+
self.P[2]+f2[0],
|
|
88
|
+
self.P[3]+f2[1]])
|
|
89
|
+
|
|
90
|
+
def create_pnt(self, ncoil = 5, npnt=50, cx=1, cy=1, r=1, r_dist=1.3, p_dist=0.7, trace=False):
|
|
91
|
+
|
|
92
|
+
check_ncoil = [ncoil < 2, self.ncoil < 2]
|
|
93
|
+
if any(check_ncoil):
|
|
94
|
+
print(f"=> Invalid number of coil: ncoil{ncoil} or self.ncoil{self.ncoil}")
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
ncoil = ncoil if ncoil != self.ncoil else self.ncoil
|
|
98
|
+
|
|
99
|
+
updates = [
|
|
100
|
+
("cx", cx, cx != self.cx),
|
|
101
|
+
("cy", cy, cy != self.cy),
|
|
102
|
+
("r", r, r != self.r),
|
|
103
|
+
("r_dist", r_dist, r_dist != self.r_dist),
|
|
104
|
+
("p_dist", p_dist, p_dist != self.p_dist)
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
to_update = [item for item in updates if item[2]]
|
|
108
|
+
|
|
109
|
+
if to_update:
|
|
110
|
+
for name, value, _ in to_update:
|
|
111
|
+
setattr(self, name, value)
|
|
112
|
+
self._create()
|
|
113
|
+
|
|
114
|
+
if trace:
|
|
115
|
+
coil_segment = list()
|
|
116
|
+
|
|
117
|
+
sub_npnt = int(npnt/2)
|
|
118
|
+
|
|
119
|
+
p1 = self.P1[2:]-self.P1[0:2]
|
|
120
|
+
p2 = self.P2[2:]-self.P2[0:2]
|
|
121
|
+
deg_fillet1 = np.atan2(p1[1],p1[0])
|
|
122
|
+
deg_fillet2 = np.atan2(p2[1],p2[0])
|
|
123
|
+
|
|
124
|
+
deg_fillet = deg_fillet2 - deg_fillet1
|
|
125
|
+
dist_coil = _norm_vec(self._v3)
|
|
126
|
+
dist_sub_coil = _norm_vec(self._v4)*2
|
|
127
|
+
|
|
128
|
+
ncoil_sub = ncoil-1
|
|
129
|
+
total_pnt = npnt*ncoil+sub_npnt*ncoil_sub
|
|
130
|
+
xx = np.zeros(total_pnt)
|
|
131
|
+
yy = np.zeros(total_pnt)
|
|
132
|
+
|
|
133
|
+
def circle_pnt(cx,cy,r,deg1, deg2, npnt, index):
|
|
134
|
+
ddeg = (deg2-deg1)/(npnt-1)
|
|
135
|
+
for i in range(npnt):
|
|
136
|
+
deg = deg1+ddeg*i
|
|
137
|
+
x = cx+r*np.cos(deg)
|
|
138
|
+
y = cy+r*np.sin(deg)
|
|
139
|
+
xx[i+index], yy[i+index] = x, y
|
|
140
|
+
|
|
141
|
+
return i+index+1
|
|
142
|
+
|
|
143
|
+
# First coil
|
|
144
|
+
sx, sy = self.v1[0], self.v1[1]
|
|
145
|
+
sx_sub, sy_sub = self.P[2], self.P[3]
|
|
146
|
+
r, r_sub = self.r, self.r_fillet
|
|
147
|
+
cx_sub = sx_sub
|
|
148
|
+
start_angle = np.pi if self.p_dist > 0 else -np.pi
|
|
149
|
+
end_angle = deg_fillet1
|
|
150
|
+
prv_index = 0
|
|
151
|
+
cur_index = circle_pnt(sx, sy, r, start_angle, end_angle, npnt, prv_index)
|
|
152
|
+
|
|
153
|
+
if trace:
|
|
154
|
+
coil_segment.append((xx[prv_index:cur_index],
|
|
155
|
+
yy[prv_index:cur_index]))
|
|
156
|
+
prv_index = cur_index
|
|
157
|
+
|
|
158
|
+
for i in range(1, ncoil-1):
|
|
159
|
+
# Next sub coil
|
|
160
|
+
cx_sub = sx_sub+dist_sub_coil*(i-1)
|
|
161
|
+
cur_index = circle_pnt(cx_sub, sy_sub, r_sub,
|
|
162
|
+
deg_fillet1, deg_fillet2,
|
|
163
|
+
sub_npnt, prv_index)
|
|
164
|
+
if trace:
|
|
165
|
+
coil_segment.append((xx[prv_index:cur_index],
|
|
166
|
+
yy[prv_index:cur_index]))
|
|
167
|
+
prv_index = cur_index
|
|
168
|
+
|
|
169
|
+
# Next Coil
|
|
170
|
+
sx += dist_coil
|
|
171
|
+
start_angle = np.pi*2+deg_fillet2 if self.p_dist > 0 else deg_fillet2
|
|
172
|
+
end_angle = deg_fillet1 if self.p_dist > 0 else np.pi*2+deg_fillet1
|
|
173
|
+
cur_index = circle_pnt(sx, sy, r,
|
|
174
|
+
start_angle,
|
|
175
|
+
end_angle,
|
|
176
|
+
npnt,
|
|
177
|
+
prv_index)
|
|
178
|
+
|
|
179
|
+
if trace:
|
|
180
|
+
coil_segment.append((xx[prv_index:cur_index],
|
|
181
|
+
yy[prv_index:cur_index]))
|
|
182
|
+
prv_index = cur_index
|
|
183
|
+
|
|
184
|
+
if ncoil_sub > 1:
|
|
185
|
+
# Next sub coil
|
|
186
|
+
cx_sub += dist_sub_coil
|
|
187
|
+
|
|
188
|
+
if ncoil > 1:
|
|
189
|
+
cur_index = circle_pnt(cx_sub, sy_sub, r_sub,
|
|
190
|
+
deg_fillet1,
|
|
191
|
+
deg_fillet2,
|
|
192
|
+
sub_npnt,
|
|
193
|
+
prv_index)
|
|
194
|
+
if trace:
|
|
195
|
+
coil_segment.append((xx[prv_index:cur_index],
|
|
196
|
+
yy[prv_index:cur_index]))
|
|
197
|
+
prv_index = cur_index
|
|
198
|
+
|
|
199
|
+
sx += dist_coil
|
|
200
|
+
start_angle = np.pi*2+deg_fillet2 if self.p_dist > 0 else \
|
|
201
|
+
deg_fillet2
|
|
202
|
+
end_angle = 0 if self.p_dist > 0 else np.pi*2
|
|
203
|
+
cur_index = circle_pnt(sx, sy, r,
|
|
204
|
+
start_angle,
|
|
205
|
+
end_angle,
|
|
206
|
+
npnt,
|
|
207
|
+
prv_index)
|
|
208
|
+
if trace:
|
|
209
|
+
coil_segment.append((xx[prv_index:cur_index],
|
|
210
|
+
yy[prv_index:cur_index]))
|
|
211
|
+
|
|
212
|
+
return (xx, yy, coil_segment) if trace else (xx, yy)
|
|
213
|
+
|
|
214
|
+
def circle_coil(self, ncoil = 5, npnt=50, cx=1, cy=1, r=1,
|
|
215
|
+
r_dist = 1.3, p_dist = 0.7, trace = False):
|
|
216
|
+
return self.create_pnt(ncoil, npnt, cx, cy, r, r_dist, p_dist, trace)
|
|
217
|
+
|
|
218
|
+
def ellipse_coil(self, ncoil = 5, npnt=50, cx=1, cy=1, r=1,
|
|
219
|
+
r_dist = 1.3, p_dist = 0.7, compress=0.5, trace = False):
|
|
220
|
+
if trace:
|
|
221
|
+
xx, yy, seg = self.create_pnt(ncoil, npnt, cx, cy, r, r_dist, p_dist, trace)
|
|
222
|
+
for s in seg:
|
|
223
|
+
s[0] *= compress
|
|
224
|
+
else:
|
|
225
|
+
xx, yy = self.create_pnt(ncoil, npnt, cx, cy, r, r_dist, p_dist, trace)
|
|
226
|
+
|
|
227
|
+
return (xx*compress, yy, seg) if trace else (xx*compress, yy)
|
|
228
|
+
|
|
229
|
+
def __str__(self):
|
|
230
|
+
return f"c1x: {self.c1x}\n" \
|
|
231
|
+
f"c1y: {self.c1y}\n" \
|
|
232
|
+
f"c2x: {self.c2x}\n" \
|
|
233
|
+
f"c2y: {self.c2y}\n" \
|
|
234
|
+
f"v1 : {self._v1[0]:2.3f}, {self._v1[1]:2.3f}\n" \
|
|
235
|
+
f"v2 : {self._v2[0]:2.3f}, {self._v2[1]:2.3f}\n" \
|
|
236
|
+
f"v3 : {self._v3[0]:2.3f}, {self._v3[1]:2.3f}\n" \
|
|
237
|
+
f"v4 : {self._v4[0]:2.3f}, {self._v4[1]:2.3f}\n" \
|
|
238
|
+
f"v5 : {self._v5[0]:2.3f}, {self._v5[1]:2.3f}\n" \
|
|
239
|
+
f"V5 : {self.v5[0]:2.3f}, {self.v5[1]:2.3f}\n" \
|
|
240
|
+
f"Th : {self.theta/np.pi*180:2.3f}\n" \
|
|
241
|
+
f"_P : {self._P[0]:2.3f}, {self._P[1]:2.3f}\n" \
|
|
242
|
+
f" P : {self.P[0]:2.3f}, {self.P[1]:2.3f}, {self.P[2]:2.3f}, {self.P[3]:2.3f}\n" \
|
|
243
|
+
f"P1 : {self.P1[0]:2.3f}, {self.P1[1]:2.3f}, {self.P1[2]:2.3f}, {self.P1[3]:2.3f}\n" \
|
|
244
|
+
f"P2 : {self.P2[0]:2.3f}, {self.P2[1]:2.3f}, {self.P2[2]:2.3f}, {self.P2[3]:2.3f}\n" \
|
|
245
|
+
f"R : {self.r_fillet:2.3f}\n"
|
|
246
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: coil-geom
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Parametric coil and inductor geometry generator
|
|
5
|
+
Author: Uisang Hwang
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
|
|
12
|
+
# coil-geom
|
|
13
|
+
|
|
14
|
+
**coil-geom** is a Python package for generating and visualizing **coil and inductor geometries** using clean, parametric definitions.
|
|
15
|
+
It is designed for engineering, scientific visualization, and symbolic / schematic-style plotting.
|
|
16
|
+
|
|
17
|
+
- Pure geometry first (NumPy-friendly)
|
|
18
|
+
- Easy plotting with Matplotlib
|
|
19
|
+
- Suitable for electronics, physics, and CAD-style workflows
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install coil-geom
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
coil_geom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
coil_geom/coil_geom.py,sha256=qZFx0M80h9dSZrIEN36acsZ2LfAAhEjjKsSRCf_uAvM,9528
|
|
3
|
+
coil_geom-0.1.0.dist-info/METADATA,sha256=PL8_wBr1j6UxVO_xM9xDdLbau1ZIMwXSifbBbPYeDEY,776
|
|
4
|
+
coil_geom-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
5
|
+
coil_geom-0.1.0.dist-info/top_level.txt,sha256=S3NPYNi2-wPro1HVphAFO_pSgnf_gh4t6DiGoLlHMKc,10
|
|
6
|
+
coil_geom-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
coil_geom
|