def copy(shape, copies, transform_order='tsr', translate=Point.ZERO, rotate=0, scale=Point.ZERO): """Create multiple copies of a shape.""" if shape is None: return None if isinstance(shape, Path): shape = shape.asGeometry() g = Geometry() tx = ty = r = 0.0 sx = sy = 1.0 for i in xrange(copies): t = Transform() # Each letter of the order describes an operation. for op in transform_order: if op == 't': t.translate(tx, ty) elif op == 'r': t.rotate(r) elif op == 's': t.scale(sx, sy) g.extend(t.map(shape)) tx += translate.x ty += translate.y r += rotate sx += scale.x / 100.0 sy += scale.y / 100.0 return g
def shape_on_path(shape, template, amount, dist, start, keep_geometry): if shape is None: return None if template is None: return None if isinstance(shape, Path): shape = shape.asGeometry() if isinstance(template, Path): template = template.asGeometry() g = Geometry() if keep_geometry: g.extend(template.clone()) first = True for i in range(amount): if first: t = start / 100 first = False else: t += dist / 500.0 pt1 = template.pointAt(t) pt2 = template.pointAt(t + 0.00001) a = angle(pt2.x, pt2.y, pt1.x, pt1.y) tp = Transform() tp.translate(pt1.x, pt1.y) tp.rotate(a - 180) new_shape = tp.map(shape) g.extend(new_shape) return g
def group(shapes): if shapes is None: return None g = Geometry() for shape in shapes: if isinstance(shape, Geometry): g.extend(shape) elif isinstance(shape, Path): g.add(shape) else: raise "Unable to group %ss. I can only group paths or geometry objects." % shape return g
def _function(shape, *args, **kwargs): if isinstance(shape, Path): return fn(shape, *args, **kwargs) elif isinstance(shape, Geometry): g = Geometry() for path in shape.paths: result = fn(path, *args, **kwargs) if isinstance(result, Path): g.add(result) elif isinstance(result, Geometry): g.extend(result) return g return None
def text_on_path(shape, text, font_name="Verdana", font_size=20, position=0, offset=2.0, keep_geometry=True): if shape is None or shape.length <= 0: return None if text is None: return None text = unicode(text) if isinstance(shape, Path): shape = shape.asGeometry() g = Geometry() if keep_geometry: g.extend(shape.clone()) fm = get_font_metrics(font_name, font_size) string_width = textwidth(text, fm) dw = string_width / shape.length first = True for i, char in enumerate(text): char_width = textwidth(char, fm) if first: t = position / 100.0 first = False else: t += char_width / string_width * dw # Always loop (the other behavior is weird) t = t % 1.0 pt1 = shape.pointAt(t) pt2 = shape.pointAt(t + 0.001) a = angle(pt2.x, pt2.y, pt1.x, pt1.y) tp = Text(char, -char_width, -offset) tp.align = Text.Align.LEFT tp.fontName = font_name tp.fontSize = font_size tp.translate(pt1.x, pt1.y) tp.rotate(a - 180) g.add(tp.path) return g
def lpath(x, y, angle, angleScale, length, thicknessScale, lengthScale, full_rule): p = Path() p.rect(0, -length / 2, 2, length) segment = p.asGeometry() # Now run the simulation g = Geometry() stack = [] angleStack = [] t = Transform() t.translate(x, y) for letter in full_rule: if re.search('[a-zA-Z]', letter): # Move forward and draw newShape = t.map(segment) g.extend(newShape) t.translate(0, -length) elif letter == '+': # Rotate right t.rotate(angle) elif letter == '-': # Rotate left t.rotate(-angle) elif letter == '[': # Push state (start branch) stack.append(Transform(t)) angleStack.append(angle) elif letter == ']': # Pop state (end branch) t = stack.pop() angle = angleStack.pop() elif letter == '"': # Multiply length t.scale(1.0, lengthScale / 100.0) elif letter == '!': # Multiply thickness t.scale(thicknessScale / 100.0, 1.0) elif letter == ';': # Multiply angle angle *= angleScale / 100.0 elif letter == '_': # Divide length t.scale(1.0, 1.0 / (lengthScale / 100.0)) elif letter == '?': # Divide thickness t.scale(1.0 / (thicknessScale / 100.0), 1.0) elif letter == '@': # Divide angle angle /= angleScale / 100.0 return g
def cook(generations,x,y,angle,angleScale,length,thicknessScale,lengthScale,premise,rule1,rule2,rule3): #segment = self.segment #if segment is None: p = Path() p.rect(0, -length/2, 2, length) segment = p.asGeometry() # Parse all rules ruleArgs = [rule1,rule2,rule3] rules = {} #rulenum = 1 #while hasattr(cook,"rule%i" % rulenum): for full_rule in ruleArgs: #full_rule = getattr("rule%i" % rulenum) if len(full_rule) > 0: if len(full_rule) < 3 or full_rule[1] != '=': raise ValueError("Rule %s should be in the format A=FFF" % full_rule) rule_key = full_rule[0] rule_value = full_rule[2:] rules[rule_key] = rule_value #rulenum += 1 # Expand the rules up to the number of generations full_rule = premise for gen in xrange(int(round(generations))): tmp_rule = "" for letter in full_rule: if letter in rules: tmp_rule += rules[letter] else: tmp_rule += letter full_rule = tmp_rule # Now run the simulation g = Geometry() stack = [] angleStack = [] t = Transform() t.translate(x, y) angle = angle for letter in full_rule: if re.search('[a-zA-Z]',letter): # Move forward and draw newShape = t.map(segment) g.extend(newShape) t.translate(0, -length) elif letter == '+': # Rotate right t.rotate(angle) elif letter == '-': # Rotate left t.rotate(-angle) elif letter == '[': # Push state (start branch) stack.append(Transform(t)) angleStack.append(angle) elif letter == ']': # Pop state (end branch) t = stack.pop() angle = angleStack.pop() elif letter == '"': # Multiply length t.scale(1.0, lengthScale/100.0) elif letter == '!': # Multiply thickness t.scale(thicknessScale/100.0, 1.0) elif letter == ';': # Multiply angle angle *= angleScale/100.0 elif letter == '_': # Divide length t.scale(1.0, 1.0/(lengthScale/100.0)) elif letter == '?': # Divide thickness t.scale(1.0/(thicknessScale/100.0), 1.0) elif letter == '@': # Divide angle angle /= angleScale/100.0 return g
def l_system(shape, position, generations, length, length_scale, angle, angle_scale, thickness_scale, premise, *rules): if shape is None: p = Path() p.rect(0, -length/2, 2, length) shape = p.asGeometry() # Parse all rules rule_map = {} for rule_index, full_rule in enumerate(rules): if len(full_rule) > 0: if len(full_rule) < 3 or full_rule[1] != '=': raise ValueError("Rule %s should be in the format A=FFF" % (rule_index + 1)) rule_key = full_rule[0] rule_value = full_rule[2:] rule_map[rule_key] = rule_value # Expand the rules up to the number of generations full_rule = premise for gen in xrange(int(round(generations))): tmp_rule = "" for letter in full_rule: if letter in rule_map: tmp_rule += rule_map[letter] else: tmp_rule += letter full_rule = tmp_rule # Now run the simulation g = Geometry() stack = [] angleStack = [] t = Transform() t.translate(position.x, position.y) angle = angle for letter in full_rule: if letter == 'F': # Move forward and draw transformed_shape = t.map(shape) if isinstance(transformed_shape, Geometry): g.extend(transformed_shape) elif isinstance(transformed_shape, Path): g.add(transformed_shape) t.translate(0, -length) elif letter == '+': # Rotate right t.rotate(angle) elif letter == '-': # Rotate left t.rotate(-angle) elif letter == '[': # Push state (start branch) stack.append(Transform(t)) angleStack.append(angle) elif letter == ']': # Pop state (end branch) t = stack.pop() angle = angleStack.pop() elif letter == '"': # Multiply length t.scale(1.0, length_scale / 100.0) elif letter == '!': # Multiply thickness t.scale(thickness_scale / 100.0, 1.0) elif letter == ';': # Multiply angle angle *= angle_scale / 100.0 elif letter == '_': # Divide length t.scale(1.0, 1.0/(length_scale / 100.0)) elif letter == '?': # Divide thickness t.scale(1.0/(thickness_scale / 100.0), 1.0) elif letter == '@': # Divide angle angle /= angle_scale / 100.0 return g