1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
"""
This is a script for Drawbot (http://drawbot.com)
It draws a graph of the factors of a 2-axis, 4 master designspace.
"""
from mutatorMath.objects.mutator import buildMutator
from mutatorMath.objects.location import Location
import random as rann
import os, time, math
import itertools
class MathDot(object):
def __init__(self, pt=(0,0), s=0.5, alpha=1, name=None):
self.pt = pt
self.size = s
self.alpha = alpha
self.name = name
def draw(self):
save()
s = self.size * .5
fill(1,0,0, self.alpha)
oval(self.pt[0]-.5*s, self.pt[1]-0.5*s, s, s)
fill(1,0.5,0)
stroke(None)
fontSize(9 * 0.1)
text("%s\n%3.2f"%(self.name, self.size), (self.pt[0], self.pt[1]-3))
restore()
def __repr__(self):
return "<MathDot %3.1f, %3.1f %s>"%(self.pt[0],self.pt[1], self.name)
def copy(self):
return self.__class__(self.pt, self.size, self.alpha, self.name)
def __add__(self, other):
new = self.copy()
new.pt = new.pt[0]+other.pt[0], new.pt[1]+other.pt[1]
new.size += other.size
new.alpha += other.alpha
return new
def __sub__(self, other):
new = self.copy()
new.pt = new.pt[0]-other.pt[0], new.pt[1]-other.pt[1]
new.size -= other.size
new.alpha -= other.alpha
return new
def __div__(self, factor):
if not isinstance(factor, tuple):
factor = (factor, factor)
new = self.copy()
new.pt = self.pt[0]/factor[0], self.pt[1]/factor[1]
new.size = self.size/factor[0]
new.alpha = self.alpha/factor[0]
return new
def __mul__(self, factor):
if not isinstance(factor, tuple):
factor = (factor, factor)
new = self.copy()
new.pt = self.pt[0]*factor[0], self.pt[1]*factor[1]
new.size *= factor[0]
new.alpha = self.alpha*factor[0]
return new
__rmul__ = __mul__
items = [
(Location(pop=0, snap=0), MathDot((0,0), name="neutral")),
(Location(pop=0, snap=1), MathDot((0, 100), name="on-axis-one-A")),
(Location(pop=1, snap=0), MathDot((100, 0), name="on-axis-two-A")),
(Location(pop=1, snap=1), MathDot((100, 100), name="off-axis-A")),
]
bias, mb = buildMutator(items)
grid = {}
for loc, (master, xx) in mb.items():
for axis, value in loc:
if not axis in grid:
grid[axis] = []
if not (axis,value) in grid[axis]:
grid[axis].append((axis,value))
nodes = list(itertools.product(*grid.values()))
nodes.sort()
corners = {}
for n in nodes:
l = Location()
l.fromTuple(n)
for factor, obj, name in mb.getFactors(l, allFactors=True):
if not obj.name in corners:
corners[obj.name] = []
corners[obj.name].append((factor, l))
def dot((x,y), s=10):
save()
fill(1,0,0 ,.5)
oval(x-.5*s, y-.5*s, s, s)
restore()
def nameToStroke(name, alpha=1):
# simple conversion of a name to some sort of unique-ish color.
rann.seed(name)
fill(None)
stroke(rann.random(), 0, rann.random(), alpha)
def nameToFill(name, alpha=1):
# simple conversion of a name to some sort of unique-ish color.
rann.seed(name)
stroke(None)
fill(rann.random(), 0, rann.random(), alpha)
# make the drawings
for name in corners:
newPage(500,500)
designSpaceScale = 250
save()
margin = 102
translate(margin, margin)
projectionAngle = math.radians(20)
strokeWidth(10)
stroke(.5)
fill(None)
a = b = 1 # scale these to the number of masters on an axis
line((0,0), (0,designSpaceScale*a))
line((0,0), (designSpaceScale*b, 0))
polyPts = []
for factor, loc in corners[name]:
save()
dy = math.cos(projectionAngle) * factor * designSpaceScale *.5
dx = math.sin(projectionAngle) * factor * designSpaceScale *.5
pos1 = (loc['pop']*designSpaceScale+dx, loc['snap']*designSpaceScale+dy)
pos2 = (loc['pop']*designSpaceScale, loc['snap']*designSpaceScale)
polyPts.append(pos1)
nameToStroke(name, 1)
strokeWidth(10)
line(pos1, pos2)
dot(pos1)
dot(pos2)
w, h = textSize(name)
pos3 = pos1[0] - w -10, pos1[1]
strokeWidth(20)
nameToStroke(name, 0.4)
line(pos1, pos3)
fill(1)
stroke(None)
text(name, pos3)
restore()
# draw the plane
# note: these polygons are hardwired to the number of masters.
# While you can easily add more masters to see what the factors do,
# these surfaces won't do the right thing.
if len(polyPts)==4:
stroke(None)
nameToFill(name, 0.25)
polygon(polyPts[0], polyPts[1], polyPts[3])
if "off" in name:
nameToFill(name, 0.15)
polygon(polyPts[0], polyPts[2], polyPts[3])
restore()
path = os.path.join(os.getcwd(), "mutatorMath_pyramids_wedges_%s.png"%(name))
saveImage(path)
|