Download raw (12.5 KB)
# -*- coding: utf-8 -*-
from chiplotle import *
import random
import math
import re
from shapes.chlorella import chlorella_cell
from shapes.dunaliella_salina import duna_cell
from shapes.nannochloropsis import nanno_cell
from shapes.p_cruentum import p_cell
from shapes.spirulina import spirulina_cell
from shapes.haematococcus import haema_cell
#################################
## VIRTUAL OR HARDWARE PLOTTER ##
#################################
VIRTUAL = True
if VIRTUAL:
from chiplotle.tools.plottertools import instantiate_virtual_plotter
plotter = instantiate_virtual_plotter(left_bottom = Coordinate(-17300,-11880), right_top = Coordinate(16340,11880), type="DPX-3300")
plotter.margins.hard.draw_outline()
plotter.select_pen(1)
else:
plotter = instantiate_plotters( )[0]
plotter.select_pen(1)
#################################
## WRAPPING THE CELL FUNCTIONS ##
#################################
def wrapped_chlorella():
plotter.select_pen(2)
return chlorella_cell(random.randint(int(4.5 * y_unit), int(7 * y_unit)), random.randint(3,4))
def wrapped_duna():
plotter.select_pen(3)
return duna_cell(random.randint(int(4.5 * y_unit), int(7 * y_unit)), random.randint(3,6))
def wrapped_haema():
plotter.select_pen(4)
return haema_cell(random.randint(int(4.5 * y_unit), int(7 * y_unit)))
def wrapped_nanno():
plotter.select_pen(5)
return nanno_cell(random.randint(int(4.5 * y_unit), int(7 * y_unit)), 5)
def wrapped_p():
plotter.select_pen(6)
return p_cell(int(4.5 * y_unit), int(7 * y_unit))
def wrapped_spirulina():
plotter.select_pen(7)
return spirulina_cell(random.randint(3,12), random.uniform(0.1,0.3), random.randint(int(4.5 * y_unit), int(7 * y_unit)))
#######################################
## VARIOUS FUNCTIONS TO PROCESS TEXT ##
#######################################
def mm(amount):
return amount * 40
def cm(amount):
return amount * 400
def units_to_cm(amount):
return amount / 400.0
def title(input_text, char_widht, char_height):
input_text = input_text.upper()
if " " in input_text:
formatted_text = input_text.replace(" ", "\r\n")
input_text = formatted_text
title = shapes.group([])
movement = 0
for i in range(8):
title_text = shapes.label(input_text, units_to_cm(char_widht), units_to_cm(char_height),0,0)
transforms.center_at(title_text, (movement,0))
title.append(title_text)
movement += (y_unit)/7
return title
def title_splitter(text): # Makes the title have the same spacing as the pattern.
gapped_title = shapes.group([])
pos_y = 0 * y_unit
change = 8 * y_unit
for letter in text:
l = title(letter, 5 * y_unit, 6 * x_unit)
transforms.rotate(l, math.radians(90))
transforms.offset(l, (0, pos_y))
gapped_title.append(l)
pos_y += change
return gapped_title
# Returns a tuple with the word, and a boolean whether it's bold
# if it's bold also return tokens before and after bold sign
# *word*, → ('word,', True)
def add_style_annotation (word):
m = re.match(r'^(\W?)\*(.+)\*(\W?)$', word)
if m:
return ('{}{}{}'.format(m.group(1), m.group(2), m.group(3)), True)
else:
return (word, False)
# Changes boldness across multiple word to bold per word.
# *one two three* *one* *two* *three*
def bold_per_word (m):
return re.sub(r'(\s+)', '*\\1*', m.group(0))
def tokenize_text (text):
text = re.sub(r'\*[^\*]+\*', bold_per_word, text.replace('\r\n', '\n').replace('\n', ' __newline__ '))
return [add_style_annotation(w) for w in re.split(r'\s+', text)]
def line_length(txt, char_width):
return len(txt) * char_width * 1.3
def make_label (text, char_width, char_height, offset):
line = shapes.label(text, units_to_cm(char_width), units_to_cm(char_height), -.1, 1)
transforms.offset(line, (0, -offset))
return line
# Transform text lines into plotter labels
def make_labels (lines, charwidth, charheight, charspace=None, linespace=None, offset=None):
text = '{}{}'.format(chr(10), chr(13)).join(lines)
label = shapes.label(text, charwidth=units_to_cm(charwidth), charheight=units_to_cm(charheight), charspace=charspace, linespace=linespace)
if offset:
transforms.offset(label, offset)
return label
def bufferLength (annotated_words, separator=" ", prefix="", char_width=1):
if annotated_words:
separator_length = line_length(separator, char_width)
length = line_length(prefix, char_width)
# Loop through words, if they're bold count an extra char
for word, bold in annotated_words:
length += line_length(word, char_width)
if bold:
length += line_length(word[-1], char_width)
# add spaces
length += (len(annotated_words) - 1) * separator_length
return length
else:
return 0
def makeLines (text, width, char_width, prefix = ""):
lines = []
buff = []
separator = " "
# print(text, tokenize_text(text))
for token in tokenize_text(text):
# print(token)
length = bufferLength(buff, separator, prefix, char_width)
word_length = bufferLength([token], separator, separator, char_width)
if (width and length + word_length > width) or token[0] == '__newline__':
lines.append(buff)
buff = [token] if token[0] <> '__newline__' else []
else:
if '°' in token[0]:
buff.append((token[0].replace("°", chr(14) + chr(122) + chr(15)), token[1]))
else:
buff.append(token)
if buff:
lines.append(buff)
normal = [prefix + separator.join([word for word, _ in line]) for line in lines]
bold = [prefix + separator.join([word if bold else len(word) * ' ' for word, bold in line]) for line in lines]
return (normal, bold)
def body(input_text, width, char_width, char_height, line_height, charspace=-.1, linespace=None):
linesRegular, _ = makeLines(input_text, width, char_width)
return make_labels(linesRegular, charwidth=char_width, charheight=char_height, charspace=charspace, linespace=linespace)
#######################
## VARIOUS FUNCTIONS ##
#######################
def kask(): #Draws the KASK logo
logo = shapes.group([])
half = shapes.group([])
lower_half = shapes.group([])
height = 1 * x_unit
width = 0.8 * y_unit
vertical_indent = height / 2.0
k_1 = shapes.label("K", units_to_cm(width), units_to_cm(height),0,0)
a = shapes.label("A", units_to_cm(width), units_to_cm(height),0,0)
transforms.offset(a, (1 * y_unit, vertical_indent))
s = shapes.label("S", units_to_cm(width), units_to_cm(height),0,0)
transforms.offset(s, (2 * y_unit, vertical_indent))
k_2 = shapes.label("K", units_to_cm(width), units_to_cm(height),0,0)
transforms.offset(k_2, (3 * y_unit, 0))
half.append(k_1)
half.append(a)
half.append(s)
half.append(k_2)
k_3 = shapes.label("K", units_to_cm(width), units_to_cm(height),0,0)
a_1 = shapes.label("A", units_to_cm(width), units_to_cm(height),0,0)
transforms.offset(a_1, (1 * y_unit, vertical_indent))
s_1 = shapes.label("S", units_to_cm(width), units_to_cm(height),0,0)
transforms.offset(s_1, (2 * y_unit, vertical_indent))
k_4 = shapes.label("K", units_to_cm(width), units_to_cm(height),0,0)
transforms.offset(k_4, (3 * y_unit, 0))
lower_half.append(k_3)
lower_half.append(a_1)
lower_half.append(s_1)
lower_half.append(k_4)
logo.append(half)
transforms.rotate(lower_half, math.radians(180))
transforms.offset(lower_half, (3.8 * y_unit,- 0.2 * y_unit))
logo.append(lower_half)
border = shapes.ellipse(5.5 * y_unit, 4 * x_unit)
transforms.offset(border, ((3.8 * y_unit)/2, (-0.2 * y_unit)/2))
logo.append(border)
transforms.rotate(logo, math.radians(90))
transforms.center_at(logo, (0,0))
return logo
def conservatorium ():
charwidth = .2 * x_unit
charheight = 0.3 * y_unit
shift = 0.5 * charheight
parts = ['CON', 'SER', 'VA', 'TO', 'RIUM']
logo = Group()
lines = Group()
outline = shapes.rectangle(16 * 1.5 * charwidth, 6.5 * 2 * charheight)
transforms.offset(outline, (7 * 1.5 * charwidth, -2.1 * 2 * charheight))
logo.append(outline)
for r in range(6):
omit = len(parts) - r
line = Group()
x = 0
for p, text in enumerate(parts):
if p <> omit:
label = shapes.label(text, charwidth=units_to_cm(charwidth), charheight=units_to_cm(charheight), charspace=0, linespace=0)
if p % 2 == 1:
transforms.offset(label, (x, shift))
else:
transforms.offset(label, (x, 0))
line.append(label)
x += len(text) * charwidth * 1.55
transforms.offset(line, (0, -charheight * 2 * r))
lines.append(line)
# transforms.center_at(lines, (0,0))
logo.append(lines)
transforms.rotate(logo, math.radians(90))
return logo
def hogent():
charwidth = .5 * x_unit
charheight = .6 * y_unit
hogent = shapes.label('HO\r\nGENT', charwidth=units_to_cm(charwidth), charheight=units_to_cm(charheight), charspace=0, linespace=0)
howest = shapes.label('howest', charwidth=units_to_cm(charwidth) * .75, charheight=units_to_cm(charheight), charspace=-.1, linespace=0)
transforms.offset(hogent, (0, charheight * -1))
transforms.offset(howest, (0, charheight * -6))
logo = Group([hogent, howest])
transforms.rotate(logo, math.radians(90))
transforms.center_at(logo, (0,0))
return logo
def make_combinations(options=[], length=1): #Makes every possible combination of patterns
if length > 1:
combinations = []
for i in range(len(options) - 1):
for combination in make_combinations(options[i+1:], length - 1):
combinations.append([options[i]] + combination)
return combinations
else:
return [[option] for option in options]
def x(input):
return input * x_unit
def y(input):
return input * y_unit
#######################
## DEFINING THE GRID ##
#######################
plotter.set_origin_bottom_left()
width = plotter.margins.hard.width
height = plotter.margins.hard.height
x_unit = width / 80.0
y_unit = height / 64.0
#############################
### DRAWING THE PATTERNS ###
#############################
posx = x(4)
posy = y(4)
counter = 0
wraps = [wrapped_chlorella, wrapped_duna, wrapped_haema, wrapped_nanno, wrapped_p, wrapped_spirulina]
random.shuffle(wraps)
combinations = make_combinations(wraps, 1) + make_combinations(wraps, 2) + make_combinations(wraps, 3) + make_combinations(wraps, 4) + make_combinations(wraps, 5) + make_combinations(wraps, 6)
# random.shuffle(combinations) ### Uncomment this if you want the patterns to be drawn randomly and not from 1 - 6 combinations.
for pattern in combinations[:-2]:
for p in pattern:
shape = p()
transforms.center_at(shape,(posx,posy))
plotter.write(shape)
counter += 1
if counter%8 != 0:
posy += y(8)
else:
posy = y(4)
posx += x(8)
######################
## DRAWING THE TEXT ##
######################
plotter.select_pen(1)
header_title_text = "Colorlab research,"
header_text = "Colorlab research, initiated by Laboratorium with\nOSP (Einar Andersen, Gijs de Heij & Sarah Magnan)."
body_text = "This publication is published under the Free Art License and has been generated with a python script.\nAll files are available on osp.kitchen/work/colorlab.\n\nPlotted with living colors produced by Maria Boto Ordonez within Kask Laboratorium.\n\nwww.laboratorium.bio."
poster_title = shapes.group([])
living = title_splitter("Living")
transforms.offset(living, (x(71), y(1)))
colors = title_splitter("Colors")
transforms.offset(colors, (x(79), y(1)))
header_t = body(header_text, y(14), y(0.2), x(0.4), x(1))
transforms.rotate(header_t, math.radians(90))
transforms.offset(header_t, (x(70), y(48)))
body_t = body(body_text, y(14), y(0.2), x(0.4), x(1))
transforms.rotate(body_t, math.radians(90))
transforms.offset(body_t, (x(73), y(48)))
kask_logo = kask()
transforms.center_at(kask_logo, (x(60), y(44)))
conservatorium_logo = conservatorium()
transforms.center_at(conservatorium_logo, (x(60), y(50.5)))
hogent_logo = hogent()
transforms.center_at(hogent_logo, (x(60), y(54.5)))
transforms.offset(hogent_logo, (x(.25), 0))
poster_title.extend([living, colors, header_t, body_t, kask_logo, conservatorium_logo, hogent_logo])
plotter.write(poster_title)
############
## FINISH ##
############
plotter.select_pen(0)
if VIRTUAL:
io.view(plotter)