Circles and ellipses in generativepy
Categories: generativepy generativepy tutorial
This tutorial shows how to create circular shapes in generativepy, using the geometry module. This includes the following shapes:
- Circles
- Ellipses
- Arcs
- Sectors
- Segments
For simplicity, the shapes are drawn as outlines. See the fill and stroke tutorial for details of how to fill and stroke shapes with different styles, and the patterns tutorial to learn about special fills such as gradients.
Circle example code
Here is the code to create a circle, arc, sector, and segment :
from generativepy.drawing import make_image, setup
from generativepy.color import Color
from generativepy.geometry import Circle
def draw(ctx, pixel_width, pixel_height, frame_no, frame_count):
setup(ctx, pixel_width, pixel_height, background=Color(0.8))
blue = Color('blue')
grey = Color(0.4)
thickness = 2
Circle(ctx).of_center_radius((100, 100), 75).stroke(blue, thickness)
Circle(ctx).of_center_radius((300, 100), 75).stroke(grey, thickness, dash=[5])
Circle(ctx).of_center_radius((300, 100), 75).as_arc(0, 1).stroke(blue, thickness)
Circle(ctx).of_center_radius((100, 300), 75).stroke(grey, thickness, dash=[5])
Circle(ctx).of_center_radius((100, 300), 75).as_sector(1, 3).stroke(blue, thickness)
Circle(ctx).of_center_radius((300, 300), 75).stroke(grey, thickness, dash=[5])
Circle(ctx).of_center_radius((300, 300), 75).as_segment(-1, 1).stroke(blue, thickness)
make_image("circles-tutorial.png", draw, 400, 400)
This code is available on github in tutorial/shapes/circles.py.
Here is the resulting image:
Circle
This code, from the example above, draws a circle (top-left in the image above):
Circle(ctx).of_center_radius((100, 100), 75).stroke(blue, thickness)
The of_center_radius
method creates a circle centred at (100, 100)
with radius 75. These values are in user coordinates.
We stroke the circle with a blue line.
Arc
This code draws an arc (top-right of the image above):
Circle(ctx).of_center_radius((300, 100), 75).stroke(grey, thickness, dash=[5])
Circle(ctx).of_center_radius((300, 100), 75).as_arc(0, 1).stroke(blue, thickness)
The first line draws a grey, dashed circle. This is purely for illustration, it shows the full circle that the arc belongs to.
The second line draws the arc. An arc is part of the circumference of the circle. Drawing an arc is similar to drawing a circle, but we add a call to the as_arc
method to create an arc. This method takes a start angle and an end angle. The arc is the sections of the circle between those angles (see the section Angles below).
We stroke the arc with a blue line. This is the circle in the top-left of the image above.
Angles
The size of the arc is determined by the start and end angles, as illustrated by this diagram:
Angles are measured clockwise from the horizontal (3 o'clock) position.
Angles are measured in radians. 1 radian is about 57.3 degrees (the exact figure is 180 divided by pi). So an angle of 1 radian from the start position is approximately 5 o'clock.
We can also use negative angles, which move anti-clockwise from the horizontal, so an angle of -1 radians is about 1 o'clock.
The arc example above has a start angle of 0 and an end angle of 1, so it produces the arc shown by the blue curve.
Sector
This code draws a sector (bottom left of the image above):
Circle(ctx).of_center_radius((100, 300), 75).stroke(grey, thickness, dash=[5])
Circle(ctx).of_center_radius((100, 300), 75).as_sector(1, 3).stroke(blue, thickness)
Again, the first line draws a grey, dashed circle as a reference.
The second line draws the sector, again outlined in blue. A sector is a pie slice shape. The shape is formed from an arc, but with the two ends of the arc joined to the centre of the circle. This time the angle range of 1 to 3 (see the angle diagram).
Segment
This code draws a segment (bottom right of the image above):
Circle(ctx).of_center_radius((300, 300), 75).stroke(grey, thickness, dash=[5])
Circle(ctx).of_center_radius((300, 300), 75).as_segment(-1, 1).stroke(blue, thickness)
This is similar to the sector. A segment is just an arc with the two ends of the arc joined by a straight line. The angle range is -1 to +1.
Ellipse
Here is some example code to draw an ellipse, and also an elliptic arc, sector, and segment:
from generativepy.drawing import make_image, setup
from generativepy.color import Color
from generativepy.geometry import Ellipse
def draw(ctx, pixel_width, pixel_height, frame_no, frame_count):
setup(ctx, pixel_width, pixel_height, background=Color(0.8))
blue = Color('blue')
grey = Color(0.4)
thickness = 2
Ellipse(ctx).of_center_radius((100, 100), 75, 50).stroke(blue, thickness)
Ellipse(ctx).of_center_radius((300, 100), 75, 50).stroke(grey, thickness, dash=[5])
Ellipse(ctx).of_center_radius((300, 100), 75, 50).as_arc(0, 1).stroke(blue, thickness)
Ellipse(ctx).of_center_radius((100, 300), 50, 75).stroke(grey, thickness, dash=[5])
Ellipse(ctx).of_center_radius((100, 300), 50, 75).as_sector(1, 3).stroke(blue, thickness)
Ellipse(ctx).of_center_radius((300, 300), 50, 75).stroke(grey, thickness, dash=[5])
Ellipse(ctx).of_center_radius((300, 300), 50, 75).as_segment(-1, 1).stroke(blue, thickness)
This code is available on github in tutorial/shapes/ellipses.py.
Here is the resulting image:
This code is very similar to the circles example, but we use the Ellipse
object instead of a Circle
object. The difference is that the of_center_radius
has 3 parameters - the centre, x radius and the y radius. So:
of_center_radius((100, 100), 75, 50)
Gives an ellipse, centred at (100, 100), that is 150 wide and 100 high.
See also
- Polygons in generativepy
- Regular polygons in generativepy
- Bezier curves in generativepy
- Fill and stroke in generativepy
- Stroke styles in generativepy
- Fill styles in generativepy
- Text in generativepy
- Text offset in generativepy
- Text metrics in generativepy
- Composite paths in generativepy
- Complex paths in generativepy
- Images in generativepy
- Geometric markers in generativepy
- Path objects in generativepy
- Turtles in generativepy
Join the PythonInformer Newsletter
Sign up using this form to receive an email when new content is added:
Popular tags
2d arrays abstract data type alignment and angle animation arc array arrays bar chart bar style behavioural pattern bezier curve built-in function callable object chain circle classes clipping close closure cmyk colour combinations comparison operator comprehension context context manager conversion count creational pattern data science data types decorator design pattern device space dictionary drawing duck typing efficiency ellipse else encryption enumerate fill filter font font style for loop formula function function composition function plot functools game development generativepy tutorial generator geometry gif global variable gradient greyscale higher order function hsl html image image processing imagesurface immutable object in operator index inner function input installing iter iterable iterator itertools join l system lambda function latex len lerp line line plot line style linear gradient linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map marker style matplotlib monad mutability named parameter numeric python numpy object open operator optimisation optional parameter or pandas partial application path pattern permutations pie chart pil pillow polygon pong positional parameter print product programming paradigms programming techniques pure function python standard library radial gradient range recipes rectangle recursion reduce regular polygon repeat rgb rotation roundrect scaling scatter plot scipy sector segment sequence setup shape singleton slice slicing sound spirograph sprite square str stream string stroke structural pattern subpath symmetric encryption template tex text text metrics tinkerbell fractal transform translation transparency triangle truthy value tuple turtle unpacking user space vectorisation webserver website while loop zip zip_longest