コード例 #1
0
def test_transformlock_transforms_rotate_02():
    '''Locks work within groups.'''
    t = rotation_locked_rectangle_pair()
    g = Group([Group([t])])
    transforms.offset(g, (200, 0))
    assert_rotation_preserves_diff(g)
    assert_rotation_changes_coords(g)
コード例 #2
0
ファイル: transformlock.py プロジェクト: willprice/chiplotle
    def scale_example():
        s1 = shapes.star_outline(100, 100, 4)
        transforms.offset(s1, (300, 0))
        transforms.rotate(s1, -math.pi / 4)
        s2 = shapes.star_outline(100, 100, 6)
        transforms.offset(s2, (300, 0))
        transforms.rotate(s2, -math.pi / 2)
        s3 = shapes.star_outline(100, 100, 9)
        transforms.offset(s3, (300, 0))
        transforms.rotate(s3, -math.pi * 3 / 4)

        tl = TransformLock([s1, s2], ["scale"])
        start = Group([tl, s3])

        mid = copy.deepcopy(start)
        end = copy.deepcopy(start)

        formatters.Pen(3)(start)
        formatters.Pen(2)(mid)
        formatters.Pen(1)(end)
        transforms.scale(mid, 2)
        transforms.scale(end, 3)

        o = shapes.circle(100)
        return Group([start, mid, end, o])
コード例 #3
0
def test_transformlock_transforms_scale_02():
    '''Locks work within groups.'''
    t = scale_locked_rectangle_pair()
    g = Group([Group([t])])
    transforms.scale(g, 2)
    assert_scaling_preserves_diff(g)
    assert_scaling_changes_coords(g)
コード例 #4
0
ファイル: ruler.py プロジェクト: willprice/chiplotle
def ruler(start_coord, end_coord, units, min_tick_height, symmetric=False):
    """
    A measuring ruler.

    - `units` is a list of units on which to put marks, from smaller
        to larger. e.g., (10, 20, 40).
    - `min_tick_height` is the height of the marks for the smallest units.
        The hight of the other units are multiples of this.
    - `symmetric` set to True to draw the tick lines symmetrically around
        the invisible center-line.
    """
    start_coord = Coordinate(*start_coord)
    end_coord = Coordinate(*end_coord)

    length = (end_coord - start_coord).magnitude
    angle = (end_coord - start_coord).angle

    result = []
    for i, unit in enumerate(units):
        ticks = int(math.ceil(length / unit))
        for t in range(ticks):
            tick_height = min_tick_height * (i + 1)
            if symmetric:
                x1, y1 = unit * t, tick_height / 2
                x2, y2 = unit * t, -tick_height / 2
            else:
                x1, y1 = unit * t, 0
                x2, y2 = unit * t, -tick_height
            tick = line((x1, y1), (x2, y2))
            result.append(tick)
    g = Group(result)
    rotate(g, angle, (0, 0))
    offset(g, start_coord)
    return g
コード例 #5
0
def radial_ruler(radius,
                 start_angle,
                 end_angle,
                 units,
                 min_tick_height,
                 symmetric=True):

    length = end_angle - start_angle

    result = []
    for i, unit in enumerate(units):
        ticks = int(math.ceil(length / unit))
        for t in range(ticks):
            tick_height = min_tick_height * (i + 1)
            if symmetric:
                r1, a1 = tick_height / 2, unit * t + start_angle
                r2, a2 = -tick_height / 2, unit * t + start_angle
            else:
                r1, a1 = 0, unit * t + start_angle
                r2, a2 = -tick_height, unit * t + start_angle
            xy1 = p2c(Coordinate(r1, a1) + Coordinate(radius, 0))
            xy2 = p2c(Coordinate(r2, a2) + Coordinate(radius, 0))
            tick = line(xy1, xy2)
            result.append(tick)
    return Group(result)
コード例 #6
0
def cross(width, height):
    '''Draws a cross shape.

    - `width` is the length of the horizontal line.
    - `height` is the length of the vertical line..
    '''

    l1 = Path([Coordinate(-width / 2.0, 0), Coordinate(width / 2.0, 0)])
    l2 = Path([Coordinate(0, -height / 2.0), Coordinate(0, height / 2.0)])
    return Group([l1, l2])
コード例 #7
0
ファイル: frame.py プロジェクト: yratof/chiplotle
def frame(width, height, inset):
    '''A frame (rectangle within a rectangle) with a width, height, and inset.

    - `width` is the width of the frame.
    - `height` is the height of the frame.
    - `inset` is the distance to inset the inner rectangle from the outer.
    '''

    r1 = rectangle(width, height)
    r2 = rectangle(width - (inset * 2), height - (inset * 2))
    return Group([r1, r2])
コード例 #8
0
ファイル: transformlock.py プロジェクト: willprice/chiplotle
    def rotation_example():
        r1 = shapes.rectangle(100, 100)
        r2 = shapes.rectangle(200, 200)
        transforms.offset(r2, (400, 0))
        r3 = shapes.rectangle(300, 300)
        transforms.offset(r3, (800, 0))

        tl = TransformLock([r1, r2], ["rotate"])
        start = Group([tl, r3])
        transforms.offset(start, (500, 0))

        mid = copy.deepcopy(start)
        end = copy.deepcopy(start)

        formatters.Pen(3)(start)
        formatters.Pen(2)(mid)
        formatters.Pen(1)(end)
        transforms.rotate(mid, math.pi / 6, (0, 0))
        transforms.rotate(end, math.pi / 3, (0, 0))

        o = shapes.circle(100)
        return Group([start, mid, end, o])
コード例 #9
0
    def _annotate_centroid(self):
        coord = self.shape.centroid
        label = Label('\n\rcentroid: ' + str(coord),
            self.charwidth, self.charheight,
            origin = 'top-center')
        r = rectangle(20, 20)
        cr = cross(50, 50)
        mark = Group([r, cr, label])

        offset(label, coord)
        offset(r, coord)
        offset(cr, coord)

        return mark
コード例 #10
0
    def _annotate_center(self):
        coord = self.shape.center
        label = Label('\n\rcenter: ' + str(coord),
            self.charwidth, self.charheight,
            origin = 'top-center')
        c = circle(20)
        cr = cross(50, 50)
        mark = Group([c, cr, label])

        offset(label, coord)
        offset(c, coord)
        offset(cr, coord)

        return mark
コード例 #11
0
def arrow(path, headwidth, headheight, filled=False):
    '''Returns an arrow shape.

    - `path` is a Path object.
    - `headwidth` is the width of the arrow head.
    - `headheight` is the height of the arrow head.
    '''

    ## make arow head...
    r, a = xy_to_polar((path.points[-1] - path.points[-2]))
    head = isosceles(headwidth, headheight, filled)
    offset(head, (0, -headheight))
    rotate(head, a - math.pi / 2, (0, 0))
    offset(head, path.points[-1])

    return Group([head, path])
コード例 #12
0
def donut(width, height, inset, segments=100):
    """
        A donut (ellipse within ellipse) with a width, height, inset, segments.

        segments is how many lines should be used to draw ellipse. More
        segments create a smoother ellipse, but will take longer to draw.

        inset is the distance to inset the inner ellipse from the outer.

        The donut is drawn with the current pen location as the center.
        offset may be used to shift this around, for example, to draw from
        the lower, left corner.
    """

    e1 = ellipse(width, height, segments)
    e2 = ellipse(width - (inset * 2), height - (inset * 2), segments)
    return Group([e1, e2])
コード例 #13
0
def target(outer_radius, inner_radius, circles_count, segments=36):
    """
    Creates `circles_count` concentric circles.
    Can be used to create radially filled circles.
    """

    if not outer_radius > inner_radius:
        raise ValueError("outer_radius must be > inner_radius.")
    if not circles_count > 1:
        raise ValueError("circles_count must be >= 2.")

    result = []
    radius_delta = (outer_radius - inner_radius) / float(circles_count)
    for i in range(circles_count):
        result.append(circle(inner_radius + radius_delta * i, segments))

    return Group(result)
コード例 #14
0
ファイル: grid.py プロジェクト: yratof/chiplotle
def grid(width, height, width_divisions, height_divisions):
    '''Rectangular grid.

    - `width` : ``int`` or ``float``, width of the rectangle.
    - `height` : ``int`` or ``float``, height of the rectangle.
    - `width_divisions` : ``int``, number of horizontal equidistant partitions.
    - `height_divisions` : ``int``, number of vertical equidistant partitions.

    '''

    ul_x = width
    bl_x = ul_x
    ur_x = ul_x + width

    ul_y = height
    ur_y = ul_y
    bl_y = ul_y - height

    x_step_size = width / width_divisions
    y_step_size = height / height_divisions

    g = Group()

    ## add horizontal lines
    for i in range(height_divisions + 1):
        step_y = y_step_size * i
        l = line((ul_x, ul_y - step_y), (ur_x, ur_y - step_y))
        g.append(l)
    ## add vertical lines

    for i in range(width_divisions + 1):
        step_x = x_step_size * i
        l = line((ul_x + step_x, ul_y), (bl_x + step_x, bl_y))
        g.append(l)

    return g
コード例 #15
0
def test_shapes_group__init__03():
    '''A Group can be initialized with a list of Paths.'''
    t = Group([Path([(1, 2), (3, 4)])])
    assert len(t) == 1
    assert t[0] == Path([(1, 2), (3, 4)])
コード例 #16
0
def test_shapes_group__init__02():
    '''A Group can take no parameters.'''
    t = Group()
    assert len(t) == 0
コード例 #17
0
    else:
        #No collision
        return None



## DEMO
if __name__ == '__main__':
    from chiplotle.geometry.shapes.line import line
    from chiplotle.geometry.core.group import Group
    from chiplotle.tools import io
    from random import randrange

    #draw a bunch of lines that do not intersect

    no_intersections = Group()

    line_1 = line([randrange(0, 4000), randrange(0, 4000)],
        [randrange(0, 4000), randrange(0, 4000)])
    no_intersections.append(line_1)

    while len(no_intersections) < 300:
        new_line = line([randrange(0, 4000), randrange(0, 4000)],
            [randrange(0, 4000), randrange(0, 4000)])

        intersection = False

        for l in no_intersections:
            if get_line_intersection(new_line, l) != None:
                intersection = True
                break
コード例 #18
0
def test_shapes_group__init__01():
    """A Group can be empty."""
    t = Group([])
    assert len(t) == 0
コード例 #19
0
    rads_incr = segmentation_map[segmentation_mode.lower()]()
    rads = start_angle
    arc = []
    while rads < end_angle:
        coord = Coordinate(math.cos(rads), math.sin(rads))
        coord = coord * Coordinate(width / 2.0, height / 2.0)
        rads += rads_incr
        arc.append(coord)
    ## NOTE: this is better than using rads <= end_angle since
    ## the equality does not always work as expected with floats
    ## due to rounding.
    last = Coordinate(math.cos(end_angle), math.sin(end_angle))
    last *= Coordinate(width / 2.0, height / 2.0)
    arc.append(last)
    return Path(arc)


## RUN DEMO CODE

if __name__ == '__main__':
    from chiplotle.tools import io
    from chiplotle.geometry.core.group import Group

    gr = Group()
    for radius in range(100, 1000, 10):
        ae = arc_ellipse(radius, radius * 2, 0, math.pi / 2, 5, 'arc')
        gr.append(ae)

    io.view(gr)
コード例 #20
0
ファイル: noise.py プロジェクト: yratof/chiplotle
    '''
    def noisify(coords, value):
        try:
            x, y = value
        except TypeError:
            x = y = value
        result = [ ]
        for point in coords:
            x_wiggle = random.randrange(-x, x)
            y_wiggle = random.randrange(-y, y)
            xy = point + Coordinate(x_wiggle, y_wiggle)
            result.append(xy)
        return CoordinateArray(result)

    t = TransformVisitor(noisify)
    t.visit(shape, value)



## RUN DEMO CODE
if __name__ == "__main__":
    from chiplotle.geometry.shapes.circle import circle
    from chiplotle.tools import io
    c1 = circle(1000, 100)
    c2 = circle(800, 100)
    noise(c1, 90)
    c1 += Coordinate(1000, 1000)
    g = Group([c1, c2])
    noise(g, 60)
    io.view(g)
コード例 #21
0
def catmull_path(points, interpolation_count=50):
    '''Path with Catmull-Rom spline interpolation.'''

    path_points = catmull_interpolation(points, interpolation_count)
    return Path(path_points)


## DEMO
if __name__ == '__main__':
    from chiplotle.tools import io
    from chiplotle.geometry.shapes.cross import cross
    from chiplotle.geometry.core.group import Group
    from chiplotle.geometry.transforms.offset import offset
    import random

    points = []
    for i in range(10):
        x, y = random.randint(-100, 100), random.randint(-100, 100)
        points.append((x, y))

    crosses = []
    for point in points:
        c = cross(15, 15)
        offset(c, point)
        crosses.append(c)

    path = catmull_path(points)

    g = Group([path] + crosses)
    io.view(g)
コード例 #22
0
ファイル: offset.py プロジェクト: yratof/chiplotle
from chiplotle.geometry.core.coordinate import Coordinate
from chiplotle.geometry.transforms.transformvisitor import TransformVisitor


def offset(shape, value):
    '''In place offsetting.

    - `shape` is the shape to be rotated.
    - `value` is the offset value. Can be a scalar or an (x, y) coordinate.
    '''
    if isinstance(value, (list, tuple)):
        value = Coordinate(*value)

    def offset(coords, value):
        return coords + value

    t = TransformVisitor(offset)
    t.visit(shape, value)


## RUN DEMO CODE
if __name__ == "__main__":
    from chiplotle.geometry.shapes.rectangle import rectangle
    from chiplotle.tools import io
    r0 = rectangle(1000, 400)
    r1 = rectangle(1000, 400)
    r2 = rectangle(1000, 400)
    offset(r1, (0, 1500))
    offset(r2, (100, 200))
    io.view(Group([r0, r1, r2]))
コード例 #23
0
    return result


## RUN DEMO CODE

if __name__ == '__main__':
    from chiplotle.geometry.core.group import Group
    from chiplotle.geometry.transforms.offset import offset
    from chiplotle.geometry.transforms.rotate import rotate
    from chiplotle.tools import io

    #one of each main spiral type
    s1 = spiral_archimedean(500, wrapping_constant=1)

    s2 = spiral_archimedean(500, wrapping_constant=2, direction="ccw")
    offset(s2, (0, -1000))

    #these two are long, so we'll rotate them and move them to the side
    #of the others
    s3 = spiral_archimedean(1800, wrapping_constant=-1, direction="ccw")
    rotate(s3, math.pi * 1.5)
    offset(s3, (650, 400))
    s4 = spiral_archimedean(1500, wrapping_constant=-2, direction="ccw")
    rotate(s4, math.pi * .6)
    offset(s4, (1000, -1100))

    g = Group([s1, s2, s3, s4])

    io.view(g)
コード例 #24
0
        x = math.cos(theta) * math.pow(math.e, (expansion_rate * theta))
        y = math.sin(theta) * math.pow(math.e, (expansion_rate * theta))

        if direction == "ccw":
            y *= -1.0

        spiral_points.append((x, y))
        theta += theta_incr

    return Path(spiral_points)


## RUN DEMO CODE

if __name__ == "__main__":
    from chiplotle.geometry.core.group import Group
    from chiplotle.geometry.shapes.line import line
    from chiplotle.tools import io

    s = spiral_logarithmic()

    # add some lines for scale
    line_right = line((0, 0), (500, 0))
    line_left = line((0, 0), (-500, 0))
    line_up = line((0, 0), (0, 500))
    line_down = line((0, 0), (0, -500))

    g = Group([s, line_right, line_left, line_up, line_down])

    io.view(g)
コード例 #25
0
from chiplotle.geometry.core.coordinate import Coordinate
from chiplotle.geometry.transforms.transformvisitor import TransformVisitor


def scale(shape, value, pivot=Coordinate(0, 0)):
    """In place scaling.

    - `shape` is the shape to be rotated.
    - `value` is the scaling value. Can be a scalar or an (x, y) coordinate.
    - `pivot` is the Coordinate around which the shape will be scaled.
    """
    from chiplotle.tools.geometrytools.scale import scale

    t = TransformVisitor(scale)
    t.visit(shape, value, pivot)


## RUN DEMO CODE
if __name__ == "__main__":
    from chiplotle.geometry.shapes.rectangle import rectangle
    from chiplotle.tools import io

    r0 = rectangle(1000, 500)
    r1 = rectangle(1000, 500)
    r2 = rectangle(1000, 500)
    scale(r1, 5, (500, 250))
    scale(r2, (10, 20))
    g = Group([r0, r1, r2])
    print(g.format)
    io.view(g)
コード例 #26
0
def group(lst):
    return Group(lst)
コード例 #27
0
ファイル: transformlock.py プロジェクト: willprice/chiplotle
        s1 = shapes.star_outline(100, 100, 4)
        transforms.offset(s1, (300, 0))
        transforms.rotate(s1, -math.pi / 4)
        s2 = shapes.star_outline(100, 100, 6)
        transforms.offset(s2, (300, 0))
        transforms.rotate(s2, -math.pi / 2)
        s3 = shapes.star_outline(100, 100, 9)
        transforms.offset(s3, (300, 0))
        transforms.rotate(s3, -math.pi * 3 / 4)

        tl = TransformLock([s1, s2], ["scale"])
        start = Group([tl, s3])

        mid = copy.deepcopy(start)
        end = copy.deepcopy(start)

        formatters.Pen(3)(start)
        formatters.Pen(2)(mid)
        formatters.Pen(1)(end)
        transforms.scale(mid, 2)
        transforms.scale(end, 3)

        o = shapes.circle(100)
        return Group([start, mid, end, o])

    ## go...
    r = rotation_example()
    s = scale_example()

    io.view(Group([s, r]))
コード例 #28
0
def test_shapes_group__init__04():
    '''A Group can be initialized with another Group.'''
    t = Group([Group([]), Path([(1, 2), (3, 4)])])
    assert len(t) == 2
    assert t[0] == Group([])
    assert t[1] == Path([(1, 2), (3, 4)])
コード例 #29
0
def test_shapes_group__init__01():
    '''A Group can be empty.'''
    t = Group([])
    assert len(t) == 0
コード例 #30
0
            points[i] + dxy[i],
            points[i + 1] - dxy[i + 1],
            points[i + 1],
        ]
        plot_points += bezier_interpolation(control_points,
                                            interpolation_count, 1)[:-1]

    return Path(plot_points)


## RUN DEMO CODE

if __name__ == "__main__":
    from chiplotle.geometry.core.group import Group
    from chiplotle.tools import io

    points = [
        (0, 0),
        (1000, 1000),
        (-1000, 1000),
        (-1000, -1000),
        (1000, -1000),
        (0, 0),
    ]
    e1 = path_interpolated(points, 1)
    e2 = path_interpolated(points, 0.5)
    e3 = path_interpolated(points, 0)
    assert isinstance(e1, Path)

    io.view(Group([e1, e2, e3]))