kerykeion 4.0.6__py3-none-any.whl → 4.12.3__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.
Potentially problematic release.
This version of kerykeion might be problematic. Click here for more details.
- kerykeion/__init__.py +4 -96
- kerykeion/aspects/__init__.py +2 -2
- kerykeion/aspects/aspects_utils.py +174 -0
- kerykeion/aspects/natal_aspects.py +51 -222
- kerykeion/aspects/synastry_aspects.py +45 -23
- kerykeion/astrological_subject.py +453 -199
- kerykeion/charts/__init__.py +1 -1
- kerykeion/charts/charts_utils.py +339 -5
- kerykeion/charts/kerykeion_chart_svg.py +441 -500
- kerykeion/charts/templates/chart.xml +362 -330
- kerykeion/enums.py +50 -0
- kerykeion/fetch_geonames.py +16 -25
- kerykeion/kr_types/__init__.py +7 -0
- kerykeion/kr_types/chart_types.py +33 -32
- kerykeion/kr_types/kerykeion_exception.py +1 -1
- kerykeion/kr_types/kr_literals.py +87 -44
- kerykeion/kr_types/kr_models.py +42 -78
- kerykeion/kr_types/settings_models.py +163 -0
- kerykeion/relationship_score.py +7 -13
- kerykeion/report.py +3 -0
- kerykeion/settings/__init__.py +1 -1
- kerykeion/settings/kerykeion_settings.py +13 -183
- kerykeion/settings/kr.config.json +9 -9
- kerykeion/utilities.py +184 -22
- {kerykeion-4.0.6.dist-info → kerykeion-4.12.3.dist-info}/METADATA +142 -32
- kerykeion-4.12.3.dist-info/RECORD +32 -0
- {kerykeion-4.0.6.dist-info → kerykeion-4.12.3.dist-info}/WHEEL +1 -1
- kerykeion-4.0.6.dist-info/RECORD +0 -29
- {kerykeion-4.0.6.dist-info → kerykeion-4.12.3.dist-info}/LICENSE +0 -0
- {kerykeion-4.0.6.dist-info → kerykeion-4.12.3.dist-info}/entry_points.txt +0 -0
kerykeion/charts/__init__.py
CHANGED
kerykeion/charts/charts_utils.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import math
|
|
2
2
|
import datetime
|
|
3
|
-
from kerykeion.kr_types import KerykeionException
|
|
3
|
+
from kerykeion.kr_types import KerykeionException, ChartType
|
|
4
4
|
from typing import Union
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
def decHourJoin(inH: int, inM: int, inS: int) -> float:
|
|
7
8
|
"""Join hour, minutes, seconds, timezone integer to hour float.
|
|
8
9
|
|
|
@@ -20,6 +21,7 @@ def decHourJoin(inH: int, inM: int, inS: int) -> float:
|
|
|
20
21
|
output = dh + dm + ds
|
|
21
22
|
return output
|
|
22
23
|
|
|
24
|
+
|
|
23
25
|
def degreeDiff(a: Union[int, float], b: Union[int, float]) -> float:
|
|
24
26
|
"""Calculate the difference between two degrees.
|
|
25
27
|
|
|
@@ -40,6 +42,7 @@ def degreeDiff(a: Union[int, float], b: Union[int, float]) -> float:
|
|
|
40
42
|
out = 360.0 - out
|
|
41
43
|
return out
|
|
42
44
|
|
|
45
|
+
|
|
43
46
|
def offsetToTz(datetime_offset: Union[datetime.timedelta, None]) -> float:
|
|
44
47
|
"""Convert datetime offset to float in hours.
|
|
45
48
|
|
|
@@ -61,9 +64,9 @@ def offsetToTz(datetime_offset: Union[datetime.timedelta, None]) -> float:
|
|
|
61
64
|
output = dh + sh
|
|
62
65
|
return output
|
|
63
66
|
|
|
67
|
+
|
|
64
68
|
def sliceToX(slice: Union[int, float], radius: Union[int, float], offset: Union[int, float]) -> float:
|
|
65
|
-
"""
|
|
66
|
-
Calculates the x-coordinate of a point on a circle based on the slice, radius, and offset.
|
|
69
|
+
"""Calculates the x-coordinate of a point on a circle based on the slice, radius, and offset.
|
|
67
70
|
|
|
68
71
|
Args:
|
|
69
72
|
- slice (int | float): Represents the
|
|
@@ -86,9 +89,9 @@ def sliceToX(slice: Union[int, float], radius: Union[int, float], offset: Union[
|
|
|
86
89
|
radial = ((math.pi / 6) * slice) + plus
|
|
87
90
|
return radius * (math.cos(radial) + 1)
|
|
88
91
|
|
|
92
|
+
|
|
89
93
|
def sliceToY(slice: Union[int, float], r: Union[int, float], offset: Union[int, float]) -> float:
|
|
90
|
-
"""
|
|
91
|
-
Calculates the y-coordinate of a point on a circle based on the slice, radius, and offset.
|
|
94
|
+
"""Calculates the y-coordinate of a point on a circle based on the slice, radius, and offset.
|
|
92
95
|
|
|
93
96
|
Args:
|
|
94
97
|
- slice (int | float): Represents the slice of the circle to calculate
|
|
@@ -108,3 +111,334 @@ def sliceToY(slice: Union[int, float], r: Union[int, float], offset: Union[int,
|
|
|
108
111
|
plus = (math.pi * offset) / 180
|
|
109
112
|
radial = ((math.pi / 6) * slice) + plus
|
|
110
113
|
return r * ((math.sin(radial) / -1) + 1)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def draw_zodiac_slice(
|
|
117
|
+
c1: Union[int, float],
|
|
118
|
+
chart_type: ChartType,
|
|
119
|
+
seventh_house_degree_ut: Union[int, float],
|
|
120
|
+
num: int,
|
|
121
|
+
r: Union[int, float],
|
|
122
|
+
style: str,
|
|
123
|
+
type: str,
|
|
124
|
+
) -> str:
|
|
125
|
+
"""Draws a zodiac slice based on the given parameters.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
- c1 (Union[int, float]): The value of c1.
|
|
129
|
+
- chart_type (ChartType): The type of chart.
|
|
130
|
+
- seventh_house_degree_ut (Union[int, float]): The degree of the seventh house.
|
|
131
|
+
- num (int): The number of the sign. Note: In OpenAstro it did refer to self.zodiac,
|
|
132
|
+
which is a list of the signs in order, starting with Aries. Eg:
|
|
133
|
+
{"name": "aries", "element": "fire"}
|
|
134
|
+
- r (Union[int, float]): The value of r.
|
|
135
|
+
- style (str): The CSS inline style.
|
|
136
|
+
- type (str): The type ?. In OpenAstro, it was the symbol of the sign. Eg: "aries".
|
|
137
|
+
self.zodiac[i]["name"]
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
- str: The zodiac slice and symbol as an SVG path.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
# pie slices
|
|
144
|
+
offset = 360 - seventh_house_degree_ut
|
|
145
|
+
# check transit
|
|
146
|
+
if chart_type == "Transit" or chart_type == "Synastry":
|
|
147
|
+
dropin = 0
|
|
148
|
+
else:
|
|
149
|
+
dropin = c1
|
|
150
|
+
slice = f'<path d="M{str(r)},{str(r)} L{str(dropin + sliceToX(num, r - dropin, offset))},{str(dropin + sliceToY(num, r - dropin, offset))} A{str(r - dropin)},{str(r - dropin)} 0 0,0 {str(dropin + sliceToX(num + 1, r - dropin, offset))},{str(dropin + sliceToY(num + 1, r - dropin, offset))} z" style="{style}"/>'
|
|
151
|
+
|
|
152
|
+
# symbols
|
|
153
|
+
offset = offset + 15
|
|
154
|
+
# check transit
|
|
155
|
+
if chart_type == "Transit" or chart_type == "Synastry":
|
|
156
|
+
dropin = 54
|
|
157
|
+
else:
|
|
158
|
+
dropin = 18 + c1
|
|
159
|
+
sign = f'<g transform="translate(-16,-16)"><use x="{str(dropin + sliceToX(num, r - dropin, offset))}" y="{str(dropin + sliceToY(num, r - dropin, offset))}" xlink:href="#{type}" /></g>'
|
|
160
|
+
|
|
161
|
+
return slice + "" + sign
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def convert_latitude_coordinate_to_string(coord: Union[int, float], north_label: str, south_label: str) -> str:
|
|
165
|
+
"""Converts a floating point latitude to string with
|
|
166
|
+
degree, minutes and seconds and the appropriate sign
|
|
167
|
+
(north or south). Eg. 52.1234567 -> 52°7'25" N
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
- coord (float | int): latitude in floating or integer format
|
|
171
|
+
- north_label (str): String label for north
|
|
172
|
+
- south_label (str): String label for south
|
|
173
|
+
Returns:
|
|
174
|
+
- str: latitude in string format with degree, minutes,
|
|
175
|
+
seconds and sign (N/S)
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
sign = north_label
|
|
179
|
+
if coord < 0.0:
|
|
180
|
+
sign = south_label
|
|
181
|
+
coord = abs(coord)
|
|
182
|
+
deg = int(coord)
|
|
183
|
+
min = int((float(coord) - deg) * 60)
|
|
184
|
+
sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
|
|
185
|
+
return f"{deg}°{min}'{sec}\" {sign}"
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def convert_longitude_coordinate_to_string(coord: Union[int, float], east_label: str, west_label: str) -> str:
|
|
189
|
+
"""Converts a floating point longitude to string with
|
|
190
|
+
degree, minutes and seconds and the appropriate sign
|
|
191
|
+
(east or west). Eg. 52.1234567 -> 52°7'25" E
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
- coord (float|int): longitude in floating point format
|
|
195
|
+
- east_label (str): String label for east
|
|
196
|
+
- west_label (str): String label for west
|
|
197
|
+
Returns:
|
|
198
|
+
str: longitude in string format with degree, minutes,
|
|
199
|
+
seconds and sign (E/W)
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
sign = east_label
|
|
203
|
+
if coord < 0.0:
|
|
204
|
+
sign = west_label
|
|
205
|
+
coord = abs(coord)
|
|
206
|
+
deg = int(coord)
|
|
207
|
+
min = int((float(coord) - deg) * 60)
|
|
208
|
+
sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
|
|
209
|
+
return f"{deg}°{min}'{sec}\" {sign}"
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def draw_aspect_line(
|
|
213
|
+
r: Union[int, float],
|
|
214
|
+
ar: Union[int, float],
|
|
215
|
+
degA: Union[int, float],
|
|
216
|
+
degB: Union[int, float],
|
|
217
|
+
color: str,
|
|
218
|
+
seventh_house_degree_ut: Union[int, float],
|
|
219
|
+
) -> str:
|
|
220
|
+
"""Draws svg aspects: ring, aspect ring, degreeA degreeB
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
- r (Union[int, float]): The value of r.
|
|
224
|
+
- ar (Union[int, float]): The value of ar.
|
|
225
|
+
- degA (Union[int, float]): The degree of A.
|
|
226
|
+
- degB (Union[int, float]): The degree of B.
|
|
227
|
+
- color (str): The color of the aspect.
|
|
228
|
+
- seventh_house_degree_ut (Union[int, float]): The degree of the seventh house.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
str: The SVG line element as a string.
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
first_offset = (int(seventh_house_degree_ut) / -1) + int(degA)
|
|
235
|
+
x1 = sliceToX(0, ar, first_offset) + (r - ar)
|
|
236
|
+
y1 = sliceToY(0, ar, first_offset) + (r - ar)
|
|
237
|
+
|
|
238
|
+
second_offset = (int(seventh_house_degree_ut) / -1) + int(degB)
|
|
239
|
+
x2 = sliceToX(0, ar, second_offset) + (r - ar)
|
|
240
|
+
y2 = sliceToY(0, ar, second_offset) + (r - ar)
|
|
241
|
+
|
|
242
|
+
out = f'<line class="aspect" x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {color}; stroke-width: 1; stroke-opacity: .9;"/>'
|
|
243
|
+
|
|
244
|
+
return out
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def draw_elements_percentages(
|
|
248
|
+
fire_label: str,
|
|
249
|
+
fire_points: float,
|
|
250
|
+
earth_label: str,
|
|
251
|
+
earth_points: float,
|
|
252
|
+
air_label: str,
|
|
253
|
+
air_points: float,
|
|
254
|
+
water_label: str,
|
|
255
|
+
water_points: float,
|
|
256
|
+
) -> str:
|
|
257
|
+
"""Draw the elements grid.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
- fire_label (str): Label for fire
|
|
261
|
+
- fire_points (float): Points for fire
|
|
262
|
+
- earth_label (str): Label for earth
|
|
263
|
+
- earth_points (float): Points for earth
|
|
264
|
+
- air_label (str): Label for air
|
|
265
|
+
- air_points (float): Points for air
|
|
266
|
+
- water_label (str): Label for water
|
|
267
|
+
- water_points (float): Points for water
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
str: The SVG elements grid as a string.
|
|
271
|
+
"""
|
|
272
|
+
total = fire_points + earth_points + air_points + water_points
|
|
273
|
+
|
|
274
|
+
fire_percentage = int(round(100 * fire_points / total))
|
|
275
|
+
earth_percentage = int(round(100 * earth_points / total))
|
|
276
|
+
air_percentage = int(round(100 * air_points / total))
|
|
277
|
+
water_percentage = int(round(100 * water_points / total))
|
|
278
|
+
|
|
279
|
+
out = '<g transform="translate(-30,79)">'
|
|
280
|
+
out += f'<text y="0" style="fill:#ff6600; font-size: 10px;">{fire_label} {str(fire_percentage)}%</text>'
|
|
281
|
+
out += f'<text y="12" style="fill:#6a2d04; font-size: 10px;">{earth_label} {str(earth_percentage)}%</text>'
|
|
282
|
+
out += f'<text y="24" style="fill:#6f76d1; font-size: 10px;">{air_label} {str(air_percentage)}%</text>'
|
|
283
|
+
out += f'<text y="36" style="fill:#630e73; font-size: 10px;">{water_label} {str(water_percentage)}%</text>'
|
|
284
|
+
out += "</g>"
|
|
285
|
+
|
|
286
|
+
return out
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def convert_decimal_to_degree_string(dec: float, type="3") -> str:
|
|
290
|
+
"""
|
|
291
|
+
Coverts decimal float to degrees in format a°b'c".
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
- dec (float): decimal float
|
|
295
|
+
- type (str): type of format:
|
|
296
|
+
- 1: a°
|
|
297
|
+
- 2: a°b'
|
|
298
|
+
- 3: a°b'c"
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
str: degrees in format a°b'c"
|
|
302
|
+
"""
|
|
303
|
+
|
|
304
|
+
dec = float(dec)
|
|
305
|
+
a = int(dec)
|
|
306
|
+
a_new = (dec - float(a)) * 60.0
|
|
307
|
+
b_rounded = int(round(a_new))
|
|
308
|
+
b = int(a_new)
|
|
309
|
+
c = int(round((a_new - float(b)) * 60.0))
|
|
310
|
+
|
|
311
|
+
if type == "3":
|
|
312
|
+
out = f"{a:02d}°{b:02d}'{c:02d}""
|
|
313
|
+
elif type == "2":
|
|
314
|
+
out = f"{a:02d}°{b_rounded:02d}'"
|
|
315
|
+
elif type == "1":
|
|
316
|
+
out = f"{a:02d}°"
|
|
317
|
+
else:
|
|
318
|
+
raise KerykeionException(f"Wrong type: {type}, it must be 1, 2 or 3.")
|
|
319
|
+
|
|
320
|
+
return str(out)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def draw_transit_ring_degree_steps(r: Union[int, float], seventh_house_degree_ut: Union[int, float]) -> str:
|
|
324
|
+
"""Draws the transit ring degree steps.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
- r (Union[int, float]): The value of r.
|
|
328
|
+
- seventh_house_degree_ut (Union[int, float]): The degree of the seventh house.
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
str: The SVG path of the transit ring degree steps.
|
|
332
|
+
"""
|
|
333
|
+
|
|
334
|
+
out = '<g id="transitRingDegreeSteps">'
|
|
335
|
+
for i in range(72):
|
|
336
|
+
offset = float(i * 5) - seventh_house_degree_ut
|
|
337
|
+
if offset < 0:
|
|
338
|
+
offset = offset + 360.0
|
|
339
|
+
elif offset > 360:
|
|
340
|
+
offset = offset - 360.0
|
|
341
|
+
x1 = sliceToX(0, r, offset)
|
|
342
|
+
y1 = sliceToY(0, r, offset)
|
|
343
|
+
x2 = sliceToX(0, r + 2, offset) - 2
|
|
344
|
+
y2 = sliceToY(0, r + 2, offset) - 2
|
|
345
|
+
out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: #F00; stroke-width: 1px; stroke-opacity:.9;"/>'
|
|
346
|
+
out += "</g>"
|
|
347
|
+
|
|
348
|
+
return out
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def draw_degree_ring(r: Union[int, float], c1: Union[int, float], seventh_house_degree_ut: Union[int, float], stroke_color: str) -> str:
|
|
352
|
+
"""Draws the degree ring.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
- r (Union[int, float]): The value of r.
|
|
356
|
+
- c1 (Union[int, float]): The value of c1.
|
|
357
|
+
- seventh_house_degree_ut (Union[int, float]): The degree of the seventh house.
|
|
358
|
+
- stroke_color (str): The color of the stroke.
|
|
359
|
+
|
|
360
|
+
Returns:
|
|
361
|
+
str: The SVG path of the degree ring.
|
|
362
|
+
"""
|
|
363
|
+
out = '<g id="degreeRing">'
|
|
364
|
+
for i in range(72):
|
|
365
|
+
offset = float(i * 5) - seventh_house_degree_ut
|
|
366
|
+
if offset < 0:
|
|
367
|
+
offset = offset + 360.0
|
|
368
|
+
elif offset > 360:
|
|
369
|
+
offset = offset - 360.0
|
|
370
|
+
x1 = sliceToX(0, r - c1, offset) + c1
|
|
371
|
+
y1 = sliceToY(0, r - c1, offset) + c1
|
|
372
|
+
x2 = sliceToX(0, r + 2 - c1, offset) - 2 + c1
|
|
373
|
+
y2 = sliceToY(0, r + 2 - c1, offset) - 2 + c1
|
|
374
|
+
|
|
375
|
+
out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {stroke_color}; stroke-width: 1px; stroke-opacity:.9;"/>'
|
|
376
|
+
out += "</g>"
|
|
377
|
+
|
|
378
|
+
return out
|
|
379
|
+
|
|
380
|
+
def draw_transit_ring(r: Union[int, float], paper_1_color: str, zodiac_transit_ring_3_color: str) -> str:
|
|
381
|
+
"""
|
|
382
|
+
Draws the transit ring.
|
|
383
|
+
|
|
384
|
+
Args:
|
|
385
|
+
- r (Union[int, float]): The value of r.
|
|
386
|
+
- paper_1_color (str): The color of paper 1.
|
|
387
|
+
- zodiac_transit_ring_3_color (str): The color of the zodiac transit ring
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
str: The SVG path of the transit ring.
|
|
391
|
+
"""
|
|
392
|
+
radius_offset = 18
|
|
393
|
+
|
|
394
|
+
out = f'<circle cx="{r}" cy="{r}" r="{r - radius_offset}" style="fill: none; stroke: {paper_1_color}; stroke-width: 36px; stroke-opacity: .4;"/>'
|
|
395
|
+
out += f'<circle cx="{r}" cy="{r}" r="{r}" style="fill: none; stroke: {zodiac_transit_ring_3_color}; stroke-width: 1px; stroke-opacity: .6;"/>'
|
|
396
|
+
|
|
397
|
+
return out
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def draw_first_circle(r: Union[int, float], stroke_color: str, chart_type: ChartType, c1: Union[int, float, None] = None) -> str:
|
|
401
|
+
"""
|
|
402
|
+
Draws the first circle.
|
|
403
|
+
|
|
404
|
+
Args:
|
|
405
|
+
- r (Union[int, float]): The value of r.
|
|
406
|
+
- color (str): The color of the circle.
|
|
407
|
+
- chart_type (ChartType): The type of chart.
|
|
408
|
+
- c1 (Union[int, float]): The value of c1.
|
|
409
|
+
|
|
410
|
+
Returns:
|
|
411
|
+
str: The SVG path of the first circle.
|
|
412
|
+
"""
|
|
413
|
+
if chart_type == "Synastry" or chart_type == "Transit":
|
|
414
|
+
return f'<circle cx="{r}" cy="{r}" r="{r - 36}" style="fill: none; stroke: {stroke_color}; stroke-width: 1px; stroke-opacity:.4;" />'
|
|
415
|
+
else:
|
|
416
|
+
if c1 is None:
|
|
417
|
+
raise KerykeionException("c1 is None")
|
|
418
|
+
|
|
419
|
+
return f'<circle cx="{r}" cy="{r}" r="{r - c1}" style="fill: none; stroke: {stroke_color}; stroke-width: 1px; " />'
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def draw_second_circle(r: Union[int, float], stroke_color: str, fill_color: str, chart_type: ChartType, c2: Union[int, float, None] = None) -> str:
|
|
423
|
+
"""
|
|
424
|
+
Draws the second circle.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
- r (Union[int, float]): The value of r.
|
|
428
|
+
- stroke_color (str): The color of the stroke.
|
|
429
|
+
- fill_color (str): The color of the fill.
|
|
430
|
+
- chart_type (ChartType): The type of chart.
|
|
431
|
+
- c2 (Union[int, float]): The value of c2.
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
str: The SVG path of the second circle.
|
|
435
|
+
"""
|
|
436
|
+
|
|
437
|
+
if chart_type == "Synastry" or chart_type == "Transit":
|
|
438
|
+
return f'<circle cx="{r}" cy="{r}" r="{r - 72}" style="fill: {fill_color}; fill-opacity:.4; stroke: {stroke_color}; stroke-opacity:.4; stroke-width: 1px" />'
|
|
439
|
+
|
|
440
|
+
else:
|
|
441
|
+
if c2 is None:
|
|
442
|
+
raise KerykeionException("c2 is None")
|
|
443
|
+
|
|
444
|
+
return f'<circle cx="{r}" cy="{r}" r="{r - c2}" style="fill: {fill_color}; fill-opacity:.2; stroke: {stroke_color}; stroke-opacity:.4; stroke-width: 1px" />'
|