Follow these guides below to learn how to use LineDream!
LineDream is a generative art library for Python. It is heavily influenced by P5 and Processing. However, it takes a more object-oriented pythonic approach. Each primitive has its own transformation methods and styling properties.
Currently, LineDream targets SVG outputs due to its extensive API for 2D vector graphic. The library was originally created to make art for a pen plotters, however the inner object structure could be applied to other rendering platforms and use cases.
Installation is done through the Python Package Index.
pip install LineDream
Package information can be found here: https://pypi.org/project/LineDream/
This is a simple example that shows a handful of functions that LineDream has to offer.
import random
from LineDream import Line, Canvas, Rectangle, Square, Ellipse, Point, Circle, CircleMath
Canvas.width=800
Canvas.height=400
Canvas.background_color='black'
for pp in range(100):
x = random.randint(0, Canvas.width)
y = random.randint(0, 400)
coords = (x,y)
p = Point(*coords)
p.stroke_color= 'white'
c_size = 180
circle_center = Canvas.width/2, Canvas.height+c_size/2
c = Circle(*circle_center, 180)
c.stroke_color='white'
c = Circle(*circle_center, 200)
c.stroke_color='white'
c = Circle(*circle_center, 220)
c.stroke_color='white'
long=True
for degrees in range(360,180,-10):
dist_from_circle = 250
line_len = 40
if long:
line_len = 100
long=False
else:
long=True
d_x_s, d_y_s = CircleMath.distance_to_coords(degrees, dist_from_circle)
x1 = circle_center[0] + d_x_s
y1 = circle_center[1] + d_y_s
d_x, d_y = CircleMath.distance_to_coords(degrees, dist_from_circle + line_len)
x2 = circle_center[0] + d_x
y2 = circle_center[1] + d_y
Line([(x1,y1), (x2,y2)], stroke_color='white')
Canvas.save("example1.svg")
The canvas contains all the attributes and smarts around rending the image.
When you create art, it will typically go something like this:
from LineDream import Canvas, Line
# create a canvas that is 300x200
Canvas.width = 300
Canvas.height = 200
# set the background color of the canvas
Canvas.background_color = 'green'
# lets create a triangle
# First, we will create a line object with one set of vertices
l = Line([(130, 50)], close_path=True, stroke_color='yellow')
# ... Whoops! to create a triangle, we need 3 vertices.
# It's ok! We can add these after the fact:
l.add_vertex(130, 150)
l.add_vertex(180, 100)
#rotate this awesome triangle 120 degrees
l.rotate(120)
# save the final result out.
Canvas.save("amazing_art.svg")
When specifying a coordinate on the canvas, viewable locations are positive numbers. The (0, 0) position is in the upper left.
from LineDream import Canvas, Circle
Canvas.width = 300
Canvas.height = 100
Canvas.background_color = 'black'
# create a circle at the (0,0) position of the canvas. The radius is 40
Circle(0, 0, 40, stroke_color='blue', stroke_width=10)
Canvas.save("show_0_position.svg")
This is the list of primitive object shapes and types that LineDream provides. These are the building blocks of all the art you will create.
All primitive objects have access to:
A line, simply put, is multiple sets of coordinates which when rendered create line segments. A Line can be two sets of coordinates (making one segment), or many sets of coordinates.
from LineDream import Line
# this a line object with no segments defined.
# This will not render anything.
l = Line()
# ... now lets add two vertex points.
l.add_vertex(10,60)
l.add_vertex(20,70)
# ... We've added two vertex's to our Line!
from LineDream import Circle
# Create a Circle at (30,20)
# It's radius is 10
Circle(30,20, 10)
from LineDream import Ellipse
# Create an Ellipse at (30,20)
# It's width is 10
# It's Height is 15
Ellipse(30,20, 10, 15)
from LineDream import Square
# Create a square with it's center at (40,50)
# It's width and height are 10
Square(40, 50, 10)
from LineDream import Rectangle
# Create a rectangle with it's center at (40,50)
# It's width is 5
# It's height is 20
Rectangle(40, 50, 5, 20)
This is an experimental feature. Currently, it (sloppily) uses Herhsey Text. It has been hacked out of the Inkscape extension.
from LineDream import TextLines
# Create a path that says 'LineDreamIsAwesome'
TextLines('LineDreamIsAwesome', kerning=5)
Coming soon...
All primitives have some common public attributes that are handy.
from LineDream import Line
# lets create a triangle
l = Line([(10,9)], close_path=True)
l.add_vertex(10,20)
l.add_vertex(15,15)
A list of all the vertices that make up the shape. NOTE: This is not available for Circle or Ellipse. Soon, this will be migrated to a Numpy array.
print(l.vertices)
>>> [(10,9),(10,20),(15,15)]
print(l.min_x)
>>> 10
print(l.max_x)
>>> 15
print(l.min_y)
>>> 9
print(l.max_y)
>>> 20
The center of all the points.
print(l.center)
>>> (12.5, 14.5)
Primitives have particular attributes that can be used to change the look of your art. If you're paying attention, you can see these attrs map directly to SVG attributes.
These attributes can be set as part of the object, or as **kwargs
in the constructor.
from LineDream import Circle, Rectangle
#create a circle at 200, 100 with a radius of 20
c = Circle(200,100, 20)
# set the outer stroke to white
c.stroke_color='white'
# set the fill of the circle to red
c.fill_color = 'red
# create a rectangle, the center at (50,40)
# it has a width of 20, and a height of 10
# set the fill to beige as a keyword argument.
Rectangle(50, 40, 20, 10, fill_color='beige')
Color of the inside of the shape
c.fill_color='red
Color of the outer stroke of the object
c.stroke_color='red'
Width of the outer stroke. This can be None
c.stroke_width='red
For Line() objects, boolean if the path should be closed. If True
, this will draw a straight line from the first vertex, to the last.
c.close_path=False
Primitives have methods to transform their vertices.
from LineDream import Line
# create a triangle with the Line primitive.
l = Line([(10,10),(10,20),(15,15)], close_path=True)
The transform method will shift all vertices of a shape a given x,y amount.
# This will move the line 10 pixels to the right,
# and 30 pixels down.
l.transform(10,30)
Rotate the shape a given degrees (this is in degrees... NOT radians). There is an optional origin
**kwarg. This takes a tuple of coordinates in which to rotate around.
# This will move rotate the shape 10 degrees.
# Since no origin is given,
# it will rotate around the found center of the shape.
l.rotate(10)
# this will rotate the shape 30 degrees,
# using (20,50) as the origin.
l.rotate(30, (20,50))
This will scale the shape. There is an optional origin
**kwarg. This takes a tuple of coordinates in which to scale from.
# This will move scale the shape by 2x.
# Since no origin is given,
# it will scale around the found center of the shape.
l.scale(2.0)
# this will scale the shape 3x,
# using (20,50) as the origin of the scale.
l.scale(3.0, (20,50))