Martin McBride, 2020-08-18
Tags geometry shape
Categories generativepy generative art
The geometry module provides classes for drawing shapes. While you can draw any shape you wish using the Pycairo API, the geometry classes make it easier and more readable.
For each shape there is typically:
- A utility function. This simply creates the shape and adds it to the path.
- A shape class. This allows you to create a shape with more control. In most cases there will be different ways to create the shape, and you can choose the most convenient option. Once the shape is created, you can fill it, stroke it, fill and stroke it, or just add it to the current path.
Shape classes use fluent notation to make the code readable.
All shapes inherit from the
Shape class described here. The available shapes are all defined in the geometry module, but they are documented in separate pages:
There are also some line decorators that can be used to annotate lines:
Example - rectangle
To create a rectangle using the utility function you can do this (assuming we have a valid
ctx, for example inside a
rectangle(ctx, 1, 2, 4, 3) ctx.set_source_rgba(*Color(1, 0, 0)) ctx.fill()
rectangle function adds a rectangle to the path with its corner at (1, 2), and with width 4, height 3.
We then set the colour to red and fill the rectangle.
We can do a similar thing with a
Rectangle object like this:
Rectangle(ctx).of_corner_size(1, 2, 4, 3).stroke(Color(0, .5, 0), 0.1)
This time we define the same rectangle, but instead of filling it we stroke it with a green line of thickness 0.1 units.
All classes have the same constructor. The constructor, of course, takes the name of the shape.
Shape(ctx) Rectangle(ctx) # etc...
|ctx||Context||The Pycairo Context to draw to|
Creates a shape object with
ctx as its target drawing context.
Shape class is an abstract base class (you cannot create a
Shape object). It adds several methods that are available to all the concrete shape classes:
addadds the shape to the context.
fillfills the shape.
strokestrokes the shape.
fill_strokefills and strokes the shape.
pathcreates a path object from the shape, that can be used with the Path object.
clipadds the current shape to the clip path.
as_sub_pathadd a shape to an existing shape to create a complex shape.
extend_pathadds new lines lines and curves to an existing shape to create a complex shape.
Adds the shape to the context but does not draw it. The shape is added as a new path.
Adds the shape to the context and fills it.
|color||generativepy.Color||The fill colour.|
|fill_rule||enum||The fill rule.|
color specfies the colour that will be used to fill the shape. it defaults to black.
fill_rule only applies to complex paths such as self intersecting paths. It controls which parts of the path will be filled, and which will be left as "holes". Possible values are
Adds the shape to the context and strokes it.
stroke(color=Color(0), line_width=1, dash=, cap=SQUARE, join=MITER, miter_limit=None)
|color||generativepy.Color||The stroke colour.|
|line_width||number||The line width.|
|dash||array of numbers||The dash style.|
|cap||enum||The type of line cap.|
|join||enum||The type of line join.|
|miter_limit||number||The mitre limit.|
Draws a line with the supplied
line_width. The default is a black line of width 1. The line width is in user units.
dash creates dashed lines, specified by an array of numbers. For example:
creates a dash pattern where the dashes are 5 units long, separated by gaps that are 5 units long.
[3, 4]creates a dash pattern where the dashes are 3 units long, separated by gaps that are 4 units long.
cap controls the style of the line ends:
drawing.ROUNDcreates rounded line ends.
drawing.SQUAREcreates square line ends that extend slightly beyond the line start and end points.
drawing.BUTTcreates square line ends that end exactly on the line start and end points.
join controls the style of the corners (where two line sections meet):
drawing.MITREcreates pointed corners.
drawing.ROUNDcreates rounded corners.
drawing.BEVELis similar to
MITREbut the sharp point the corner is cut off.
miter_limit is used in conjunction with the
MITRE join style. For joins at small angles, the mitre can become very long.
miter_limit automatically switches to
BEVEL mode at low angles.
miter_limit is enabled by default at an angle of about 11 degrees, which is suitable for most applications.
Adds the shape to the context and fills then strokes it.
fill_stroke(fill_color, stroke_colour, line_width=1)
|fill_color||generativepy.Color||The fill colour.|
|stroke_color||generativepy.Color||The stroke colour.|
|line_width||number||The line width.|
fill_stroke, the two colour parameters
stroke_color are not optional. You must supply both colours, which means that the shape will be filled and stroked with flat colours.
To fill and stroke a shape with alternative sources (such as patterns or gradients) you should
add the shape, then stroke and fill it with native Context calls.
Creates a path object from the current context.
path() # Returns a path
path is called in a similar way to
fill, but instead of filling the current shape, it takes a snapshot of the shape and returns it as a Pycairo path object.
You can save this object and pass it into a Path object later. When you fill or stroke the
Path, it will recreate the shape. This can be useful if you need to use the same shape more than once, or if you want to pass a shape into another function as a parameter.
You can also iterate over the path using Pycairo functions to do fancy things like placing text along a curve. Refer to the Pycairo documentation for more information.
You should generally treat the returned Pycairo path as an opaque object - that is to say, you can pass it around but you shouldn't generally try to modify it or use its internal data.
path returns a flattened path. That is a path where all the curves have been converted to straight line segments. The path will be reproduced perfectly at the same scale, but if you store a path and then redraw it using a large scale factor you might see some distortion of the curve.
For more details see the path tutorial.
Creates a clip region from the current context.
clip is called in a similar way to
fill, but instead of filling the current shape, it establishes a clipping region using the shape.
When the clipping region is in force, anything else you draw will be clipped to that region. Anything outside that region will be protected from any drawing operations.
If you apply more than a clipping region A, and then apply another clipping region B, the result will be that the intersection of the two regions.
If you want to apply a clipping region temporarily, and remove it later, the best way is to use the context save and restore method, see useful context methods.
For more details on clipping, see the clipping tutorial.
Adds a new shape to the context, without removing any existing shapes. This can be used to create complex shapes.
This method allows you to create complex paths, consisting of two or more separate shapes. This allows you to do things such as creating shapes with holes, or creating complex clip paths.
For more details see the complex paths tutorial.
Extends an existing path with extra lines or curves.
|close||bool||True to close the path after adding this section|
This function is used to join several open shapes, to form a more complex shape. It can be used to join any combination of the following shapes:
Polygon, but the shape should be left open (using the
Circle, but only in arc mode (using the
When the final shape is added, you can optionally set the
close flag to created a closed shape. You should not add any further sections after this final call. Alternatively, if the
close flag is not set it will create an open shape.
For more details see the composite paths tutorial.