Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
def reflect(shape, position, _angle, keep_original):
    """Mirrors and copies the geometry across an invisible axis."""
    if shape is None: return None
    
    new_shape = shape.cloneAndClear()
    for contour in shape.contours:
        c = Contour()
        for point in contour.points:  
            d = distance(point.x, point.y, position.x, position.y)
            a = angle(point.x, point.y, position.x, position.y)
            x, y = coordinates(position.x, position.y, d * cos(radians(a - _angle)), 180 + _angle)
            d = distance(point.x, point.y, x, y)
            a = angle(point.x, point.y, x, y)
            px, py = coordinates(point.x, point.y, d * 2, a)
            c.addPoint(Point(px, py, point.type))
        if contour.closed:
            c.close()
        new_shape.add(c)
        
    if keep_original:
        g = Geometry()
        g.add(shape)
        g.add(new_shape)
        return g
        
    return new_shape
Пример #5
0
 def _function(shape, *args, **kwargs):
     if isinstance(shape, list):
         return fn(shape, *args, **kwargs)
     elif isinstance(shape, Path):
         return fn([shape], *args, **kwargs)[0]
     elif isinstance(shape, Geometry):
         g = Geometry()
         for path in fn(shape.paths, *args, **kwargs):
             g.add(path)
         return g
Пример #6
0
 def _function(shape, *args, **kwargs):
     if isinstance(shape, list):
         return fn(shape, *args, **kwargs)
     elif isinstance(shape, Path):
         return fn([shape], *args, **kwargs)[0]
     elif isinstance(shape, Geometry):
         g = Geometry()
         for path in fn(shape.paths, *args, **kwargs):
             g.add(path)
         return g
Пример #7
0
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
Пример #8
0
 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
Пример #9
0
def delete_paths(geo, bounding, delete_selected=True):
    if geo is None or bounding is None: return None
    new_geo = Geometry()
    for old_path in geo.paths:
        selected = False
        # Paths are eagerly selected: 
        # Even if only one point is inside of the bounding volume 
        # the path is selected.
        for point in old_path.points:
            if bounding.contains(point):
                selected = True
        if selected is delete_selected:
            new_geo.add(old_path.clone())
    return new_geo
Пример #10
0
def delete_paths(geo, bounding, delete_selected=True):
    if geo is None or bounding is None: return None
    new_geo = Geometry()
    for old_path in geo.paths:
        selected = False
        # Paths are eagerly selected:
        # Even if only one point is inside of the bounding volume
        # the path is selected.
        for point in old_path.points:
            if bounding.contains(point):
                selected = True
                break
        if selected is not delete_selected:
            new_geo.add(old_path.clone())
    return new_geo
Пример #11
0
def pack(shapes, iterations, padding, seed):
    _seed(seed)
    packed_objects = []
    for path in shapes:
        packed_objects.append(PackObject(path))
    for i in xrange(1, iterations):
        _pack(packed_objects, damping=0.1/i, padding=padding)


    geo = Geometry()
    for po in packed_objects:
        print po.x, po.y
        p = Transform.translated(po.x, po.y).map(po.path)
        geo.add(p)
    return geo
Пример #12
0
 def _function(shape, *args, **kwargs):
     from java.util import List
     if isinstance(shape, (list, tuple, List)):
         return fn(shape, *args, **kwargs)
     elif isinstance(shape, Path):
         new_path = Path(shape, False)
         for c in shape.contours:
             new_path.add(Contour(fn(c.points, *args, **kwargs), c.closed))
         return new_path
     elif isinstance(shape, Geometry):
         new_geo = Geometry()
         for path in shape.paths:
             new_geo.add(_map_geo_to_points(fn)(path, *args, **kwargs))
         return new_geo
     return None
Пример #13
0
 def _function(shape, *args, **kwargs):
     if isinstance(shape, list):
         return fn(shape, *args, **kwargs)
     elif isinstance(shape, Contour):
         return fn([shape], *args, **kwargs)[0]
     elif isinstance(shape, Path):
         path = shape.cloneAndClear()
         for contour in fn(shape.contours, *args, **kwargs):
             path.add(contour)
         return path
     elif isinstance(shape, Geometry):
         g = Geometry()
         for p in shape.paths:
             g.add(_function(p, *args, **kwargs))
         return g
Пример #14
0
 def _function(shape, *args, **kwargs):
     if isinstance(shape, list):
         return fn(shape, *args, **kwargs)
     elif isinstance(shape, Contour):
         return fn([shape], *args, **kwargs)[0]
     elif isinstance(shape, Path):
         path = shape.cloneAndClear()
         for contour in fn(shape.contours, *args, **kwargs):
             path.add(contour)
         return path
     elif isinstance(shape, Geometry):
         g = Geometry()
         for p in shape.paths:
             g.add(_function(p, *args, **kwargs))
         return g
Пример #15
0
 def _function(shape, *args, **kwargs):
     from java.util import List
     if isinstance(shape, (list, tuple, List)):
         return fn(shape, *args, **kwargs)
     elif isinstance(shape, Path):
         new_path = Path(shape, False)
         for c in shape.contours:
             new_path.add(Contour(fn(c.points, *args, **kwargs), c.closed))
         return new_path
     elif isinstance(shape, Geometry):
         new_geo = Geometry()
         for path in shape.paths:
             new_geo.add(_map_geo_to_points(fn)(path, *args, **kwargs))
         return new_geo
     return None
Пример #16
0
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
Пример #17
0
 def _function(_list, *args, **kwargs):
     if isinstance(_list, (Path, Geometry, Contour)):
         return fn(_list.points, *args, **kwargs)
     elif isinstance(_list, (list, tuple, Iterable)):
         if len(_list) == 0: return None
         first = _list[0]
         if isinstance(first, Point):
             return fn(_list, *args, **kwargs)
         elif isinstance(first, (Path, Geometry, Contour)):
             if len(_list) == 1:
                 return fn(first.points, *args, **kwargs)
             else:
                 g = Geometry()
                 for el in _list:
                     g.add(fn(el.points, *args, **kwargs))
                 return g
     return None
Пример #18
0
 def _function(_list, *args, **kwargs):
     if isinstance(_list, (Path, Geometry, Contour)):
         return fn(_list.points, *args, **kwargs)
     elif isinstance(_list, (list, tuple, Iterable)):
         if len(_list) == 0: return None
         first = _list[0]
         if isinstance(first, Point):
             return fn(_list, *args, **kwargs)
         elif isinstance(first, (Path, Geometry, Contour)):
             if len(_list) == 1:
                 return fn(first.points, *args, **kwargs)
             else:
                 g = Geometry()
                 for el in _list:
                     g.add(fn(el.points, *args, **kwargs))
                 return g
     return None
Пример #19
0
 def _function(shape, *args, **kwargs):
     from java.util import List
     if isinstance(shape, (list, tuple, List)):
         return fn(shape, *args, **kwargs)
     elif isinstance(shape, Point):
         return fn([shape], *args, **kwargs)[0]
     elif isinstance(shape, Contour):
         new_points = fn(shape.points, *args, **kwargs)
         return Contour(new_points, shape.closed)
     elif isinstance(shape, Path):
         path = shape.cloneAndClear()
         for contour in shape.contours:
             path.add(_function(contour, *args, **kwargs))
         return path
     elif isinstance(shape, Geometry):
         g = Geometry()
         for p in shape.paths:
             g.add(_function(p, *args, **kwargs))
         return g
Пример #20
0
 def _function(shape, *args, **kwargs):
     from java.util import List
     if isinstance(shape, (list, tuple, List)):
         return fn(shape, *args, **kwargs)
     elif isinstance(shape, Point):
         return fn([shape], *args, **kwargs)[0]
     elif isinstance(shape, Contour):
         new_points = fn(shape.points, *args, **kwargs)
         return Contour(new_points, shape.closed)
     elif isinstance(shape, Path):
         path = shape.cloneAndClear()
         for contour in shape.contours:
             path.add(_function(contour, *args, **kwargs))
         return path
     elif isinstance(shape, Geometry):
         g = Geometry()
         for p in shape.paths:
             g.add(_function(p, *args, **kwargs))
         return g
Пример #21
0
def import_svg(file_name, centered=False, position=Point.ZERO):
    """Import geometry from a SVG file."""
    # We defer loading the SVG library until we need it.
    # This makes creating a node faster.
    import svg
    if not file_name: return None
    f = file(file_name, 'r')
    s = f.read()
    f.close()
    g = Geometry()
    paths = svg.parse(s, True)
    for path in paths:
        g.add(path)
    t = Transform()
    if centered:
        x, y, w, h = list(g.bounds)
        t.translate(-x - w / 2, -y - h / 2)
    t.translate(position)
    g = t.map(g)
    return g
Пример #22
0
def import_svg(file_name, centered=False, position=Point.ZERO):
    """Import geometry from a SVG file."""
    # We defer loading the SVG library until we need it.
    # This makes creating a node faster.
    import svg
    if not file_name: return None
    f = file(file_name, 'r')
    s = f.read()
    f.close()
    g = Geometry()
    paths = svg.parse(s, True)
    for path in paths:
        g.add(path)
    t = Transform()
    if centered:
        x, y, w, h = list(g.bounds)
        t.translate(-x-w/2, -y-h/2)
    t.translate(position)
    g = t.map(g)
    return g
Пример #23
0
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
Пример #24
0
def reflect(shape, position, _angle, keep_original):
    """Mirrors and copies the geometry across an invisible axis."""
    if shape is None: return None

    new_shape = shape.cloneAndClear()
    for contour in shape.contours:
        c = Contour()
        for point in contour.points:
            d = distance(point.x, point.y, position.x, position.y)
            a = angle(point.x, point.y, position.x, position.y)
            x, y = coordinates(position.x, position.y,
                               d * cos(radians(a - _angle)), 180 + _angle)
            d = distance(point.x, point.y, x, y)
            a = angle(point.x, point.y, x, y)
            px, py = coordinates(point.x, point.y, d * 2, a)
            c.addPoint(Point(px, py, point.type))
        if contour.closed:
            c.close()
        new_shape.add(c)

    if keep_original:
        g = Geometry()
        g.add(shape)
        g.add(new_shape)
        return g

    return new_shape
Пример #25
0
def angle_pack(shapes, seed, limit, maximum_radius, angle_tries=1, use_bounding_box=False):
    if shapes is None: return None
    _seed(seed)

    def center_and_translate(shape, tx=0, ty=0):
        bx, by, bw, bh = list(shape.bounds)
        t = Transform()
        t.translate(-bw / 2 - bx, -bh / 2 - by)
        return t.map(shape)

    geo = Geometry()
    bounding_path = Path()

    # Center first shape
    first_shape = center_and_translate(shapes[0])
    geo.add(first_shape)
    bounding_path.cornerRect(first_shape.bounds)

    for shape in shapes[1:]:
        centered_shape = center_and_translate(shape)

        angles = []
        for i in range(angle_tries):
            a = uniform(0, 360)
            if use_bounding_box:
                d = try_angle(bounding_path, centered_shape, a, limit, maximum_radius, use_bounding_box)
            else:
                d = try_angle(geo, centered_shape, a, limit, maximum_radius, use_bounding_box)
            angles.append([d, a])
        chosen_distance, chosen_angle = sorted(angles)[0]

        tx, ty = coordinates(0, 0, chosen_distance, chosen_angle)
        t = Transform()
        t.translate(tx, ty)
        translated_shape = t.map(centered_shape)
        bounding_path.cornerRect(translated_shape.bounds)
        geo.add(translated_shape)

    return geo
Пример #26
0
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
Пример #27
0
 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
Пример #28
0
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
Пример #29
0
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