-
-
Save PM2Ring/924b71c2c40728e7e1183de62b53a882 to your computer and use it in GitHub Desktop.
Crocheted sphere pattern generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
''' Crocheted sphere pattern generator. | |
Calculate the number of stitches per row in a crocheted sphere | |
of a given number of rows, and thence print a crochet pattern. | |
Original patterns from http://www.craftster.org/forum/index.php?topic=341241.0 | |
Written by PM 2Ring 2011.10.20 | |
Updated to Python 3.6 2018.10.03 | |
Key: | |
Ch = chain | |
Sc = single crochet | |
inc = 2 single crochet in next stitch. | |
dec = single crochet decrease. | |
These are worked in spiral rounds. | |
''' | |
import sys | |
from math import sin, pi | |
from itertools import chain | |
intro = """ | |
An ideal Crocheted Sphere pattern. | |
All stitches are single crochet, apart from the initial chain. | |
Ch = chain | |
Sc = single crochet | |
inc = 2 single crochet in next stitch. | |
dec = single crochet decrease. | |
These are worked in spiral rounds. | |
""" | |
def main(n): | |
""" Print an ideal crocheted sphere pattern """ | |
print(intro) | |
#Account for null "rows" at the poles. | |
nn = n + 1 | |
#Polar angle between each row | |
ang = pi / nn | |
#1st row is always == 6 | |
equator = 6.0 / sin(ang) | |
head = 'Ch 2. 6 Sc in second Ch from hook.' | |
foot = ( | |
'[dec] * 4. Fasten off. (4)\n' | |
'Weave loose end through each stitch ' | |
'in the opening. Pull tightly to close.' | |
) | |
rowlengths = [int(0.55 + equator * sin(i * ang)) for i in range(nn)] | |
deltas = [0] + [j - k for j, k in zip(rowlengths[1:], rowlengths)] | |
print("Total number of rows =", n) | |
print("Total number of stitches =", sum(rowlengths[1:]) - 2) | |
print(f"Equator = {equator:.3f}\n") | |
for i in range(1, nn): | |
rowlen = rowlengths[i] | |
#First and last rows | |
if i == 1: | |
print(f"Row {i:2}: {head} ({rowlen})") | |
continue | |
elif i == n: | |
print(f"Row {i:2}: {foot}") | |
return | |
delta = deltas[i] | |
if delta > 0: | |
# Northern hemisphere, increasing | |
ch = 'inc' | |
k = rowlen - 2 * delta | |
elif delta < 0: | |
# Southern hemisphere, decreasing | |
ch = 'dec' | |
k = rowlen + delta | |
else: | |
# Equatorial band | |
print(f"Row {i:2}: even ({rowlen})") | |
continue | |
delta = abs(delta) | |
f = k / delta | |
# Fill the stitches buffer with the delta pattern | |
buff = [int(f * u) for u in range(delta + 1)] | |
buff = [u - v for u, v in zip(buff[1:], buff)] | |
# Rotate the end section to the front | |
buff = [buff[-1]] + buff[:-1] | |
# Halve the front section, and save the other | |
# half so it can be rotated back to the end | |
u = buff[0] | |
buff[0] = u // 2 | |
sa = u - buff[0] | |
# Insert the 'inc' or 'dec' tokens. A token replaces a zero delta, | |
# and a token is inserted after a non-zero delta. | |
buff = list(chain.from_iterable((u, ch) if u else (ch,) for u in buff)) | |
if sa: | |
# Append the the rotated half from the front section | |
buff.append(sa) | |
#Condense the pattern, if it repeats exactly | |
u = len(buff) | |
for k in range(1, u // 2): | |
if u % k == 0: | |
start = buff[:k] | |
m = u // k | |
if buff == start * m: | |
buff = start | |
break | |
else: | |
m = 1 | |
buff = ', '.join([f"{u:2}" for u in buff]) | |
if m > 1: | |
buff = f"[{buff}] * {m}" | |
print(f"Row {i:2}: {buff} ({rowlen})") | |
if __name__ == '__main__': | |
n = int(sys.argv[1]) if len(sys.argv) > 1 else 20 | |
main(n) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment