Skip to content

Commit ebb5b97

Browse files
authored
Merge pull request #10 from makermelissa/master
Added line and polygon, refactored triangle
2 parents c8dff25 + 784e30d commit ebb5b97

File tree

4 files changed

+234
-74
lines changed

4 files changed

+234
-74
lines changed

adafruit_display_shapes/line.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2019 Limor Fried for Adafruit Industries
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
"""
23+
`line`
24+
================================================================================
25+
26+
Various common shapes for use with displayio - Line shape!
27+
28+
29+
* Author(s): Melissa LeBlanc-Williams
30+
31+
Implementation Notes
32+
--------------------
33+
34+
**Software and Dependencies:**
35+
36+
* Adafruit CircuitPython firmware for the supported boards:
37+
https://github.com/adafruit/circuitpython/releases
38+
39+
"""
40+
41+
from adafruit_display_shapes.polygon import Polygon
42+
43+
__version__ = "0.0.0-auto.0"
44+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes.git"
45+
46+
class Line(Polygon):
47+
# pylint: disable=too-many-arguments,invalid-name
48+
"""A line.
49+
50+
:param x0: The x-position of the first vertex.
51+
:param y0: The y-position of the first vertex.
52+
:param x1: The x-position of the second vertex.
53+
:param y1: The y-position of the second vertex.
54+
:param color: The color of the line.
55+
"""
56+
def __init__(self, x0, y0, x1, y1, color):
57+
super().__init__([(x0, y0), (x1, y1)], outline=color)

adafruit_display_shapes/polygon.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2019 Limor Fried for Adafruit Industries
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
"""
23+
`polygon`
24+
================================================================================
25+
26+
Various common shapes for use with displayio - Polygon shape!
27+
28+
29+
* Author(s): Melissa LeBlanc-Williams
30+
31+
Implementation Notes
32+
--------------------
33+
34+
**Software and Dependencies:**
35+
36+
* Adafruit CircuitPython firmware for the supported boards:
37+
https://github.com/adafruit/circuitpython/releases
38+
39+
"""
40+
41+
import displayio
42+
43+
__version__ = "0.0.0-auto.0"
44+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes.git"
45+
46+
47+
class Polygon(displayio.TileGrid):
48+
# pylint: disable=too-many-arguments,invalid-name
49+
"""A polygon.
50+
51+
:param points: A list of (x, y) tuples of the points
52+
:param fill: The color to fill the polygon. Can be a hex value for a color or
53+
``None`` for transparent.
54+
:param outline: The outline of the polygon. Can be a hex value for a color or
55+
``None`` for no outline.
56+
"""
57+
def __init__(self, points, *, outline=None):
58+
xs = []
59+
ys = []
60+
61+
for point in points:
62+
xs.append(point[0])
63+
ys.append(point[1])
64+
65+
x_offset = min(xs)
66+
y_offset = min(ys)
67+
68+
# Find the largest and smallest X values to figure out width for bitmap
69+
width = max(xs) - min(xs) + 1
70+
height = max(ys) - min(ys) + 1
71+
72+
self._palette = displayio.Palette(3)
73+
self._palette.make_transparent(0)
74+
self._bitmap = displayio.Bitmap(width, height, 3)
75+
76+
if outline is not None:
77+
# print("outline")
78+
self.outline = outline
79+
for index, _ in enumerate(points):
80+
point_a = points[index]
81+
if index == len(points) - 1:
82+
point_b = points[0]
83+
else:
84+
point_b = points[index + 1]
85+
self._line(point_a[0] - x_offset, point_a[1] - y_offset,
86+
point_b[0] - x_offset, point_b[1] - y_offset, 1)
87+
88+
super().__init__(self._bitmap, pixel_shader=self._palette, x=x_offset, y=y_offset)
89+
90+
# pylint: disable=invalid-name, too-many-locals, too-many-branches
91+
def _line(self, x0, y0, x1, y1, color):
92+
if x0 == x1:
93+
if y0 > y1:
94+
y0, y1 = y1, y0
95+
for _h in range(y0, y1):
96+
self._bitmap[x0, _h] = color
97+
elif y0 == y1:
98+
if x0 > x1:
99+
x0, x1 = x1, x0
100+
for _w in range(x0, x1):
101+
self._bitmap[_w, y0] = color
102+
else:
103+
steep = abs(y1 - y0) > abs(x1 - x0)
104+
if steep:
105+
x0, y0 = y0, x0
106+
x1, y1 = y1, x1
107+
108+
if x0 > x1:
109+
x0, x1 = x1, x0
110+
y0, y1 = y1, y0
111+
112+
dx = x1 - x0
113+
dy = abs(y1 - y0)
114+
115+
err = dx / 2
116+
117+
if y0 < y1:
118+
ystep = 1
119+
else:
120+
ystep = -1
121+
122+
for x in range(x0, x1):
123+
if steep:
124+
self._bitmap[y0, x] = color
125+
else:
126+
self._bitmap[x, y0] = color
127+
err -= dy
128+
if err < 0:
129+
y0 += ystep
130+
err += dx
131+
# pylint: enable=invalid-name, too-many-locals, too-many-branches
132+
133+
@property
134+
def outline(self):
135+
"""The outline of the polygon. Can be a hex value for a color or
136+
``None`` for no outline."""
137+
return self._palette[1]
138+
139+
@outline.setter
140+
def outline(self, color):
141+
if color is None:
142+
self._palette[1] = 0
143+
self._palette.make_transparent(1)
144+
else:
145+
self._palette[1] = color
146+
self._palette.make_opaque(1)

adafruit_display_shapes/triangle.py

Lines changed: 18 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@
3838
3939
"""
4040

41-
import displayio
41+
from adafruit_display_shapes.polygon import Polygon
4242

4343
__version__ = "0.0.0-auto.0"
4444
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes.git"
4545

4646

47-
class Triangle(displayio.TileGrid):
47+
class Triangle(Polygon):
4848
# pylint: disable=too-many-arguments,invalid-name
4949
"""A triangle.
5050
@@ -59,6 +59,7 @@ class Triangle(displayio.TileGrid):
5959
:param outline: The outline of the triangle. Can be a hex value for a color or
6060
``None`` for no outline.
6161
"""
62+
# pylint: disable=too-many-locals
6263
def __init__(self, x0, y0, x1, y1, x2, y2, *, fill=None, outline=None):
6364
# Sort coordinates by Y order (y2 >= y1 >= y0)
6465
if y0 > y1:
@@ -75,29 +76,29 @@ def __init__(self, x0, y0, x1, y1, x2, y2, *, fill=None, outline=None):
7576

7677
# Find the largest and smallest X values to figure out width for bitmap
7778
xs = [x0, x1, x2]
78-
width = max(xs) - min(xs) + 1
79-
height = y2 - y0 + 1
79+
points = [(x0, y0), (x1, y1), (x2, y2)]
8080

81-
self._palette = displayio.Palette(3)
82-
self._palette.make_transparent(0)
83-
self._bitmap = displayio.Bitmap(width, height, 3)
81+
# Initialize the bitmap and palette
82+
super().__init__(points)
8483

8584
if fill is not None:
8685
self._draw_filled(x0 - min(xs), 0, x1 - min(xs), y1 - y0, x2 - min(xs), y2 - y0)
87-
self._palette[2] = fill
86+
self.fill = fill
8887
else:
89-
self._palette.make_transparent(2)
88+
self.fill = None
9089

9190
if outline is not None:
92-
# print("outline")
93-
self._palette[1] = outline
94-
self._line(x0 - min(xs), 0, x1 - min(xs), y1 - y0, 1)
95-
self._line(x1 - min(xs), y1 - y0, x2 - min(xs), y2 - y0, 1)
96-
self._line(x2 - min(xs), y2 - y0, x0 - min(xs), 0, 1)
97-
98-
super().__init__(self._bitmap, pixel_shader=self._palette, x=min(xs), y=y0)
91+
self.outline = outline
92+
for index, _ in enumerate(points):
93+
point_a = points[index]
94+
if index == len(points) - 1:
95+
point_b = points[0]
96+
else:
97+
point_b = points[index + 1]
98+
self._line(point_a[0] - min(xs), point_a[1] - y0,
99+
point_b[0] - min(xs), point_b[1] - y0, 1)
99100

100-
# pylint: disable=invalid-name, too-many-locals, too-many-branches
101+
# pylint: disable=invalid-name, too-many-branches
101102
def _draw_filled(self, x0, y0, x1, y1, x2, y2):
102103
if y0 == y2: # Handle awkward all-on-same-line case as its own thing
103104
a = x0
@@ -134,47 +135,6 @@ def _draw_filled(self, x0, y0, x1, y1, x2, y2):
134135
if a > b:
135136
a, b = b, a
136137
self._line(a, y, b, y, 2)
137-
138-
def _line(self, x0, y0, x1, y1, color):
139-
if x0 == x1:
140-
if y0 > y1:
141-
y0, y1 = y1, y0
142-
for _h in range(y0, y1):
143-
self._bitmap[x0, _h] = color
144-
elif y0 == y1:
145-
if x0 > x1:
146-
x0, x1 = x1, x0
147-
for _w in range(x0, x1):
148-
self._bitmap[_w, y0] = color
149-
else:
150-
steep = abs(y1 - y0) > abs(x1 - x0)
151-
if steep:
152-
x0, y0 = y0, x0
153-
x1, y1 = y1, x1
154-
155-
if x0 > x1:
156-
x0, x1 = x1, x0
157-
y0, y1 = y1, y0
158-
159-
dx = x1 - x0
160-
dy = abs(y1 - y0)
161-
162-
err = dx / 2
163-
164-
if y0 < y1:
165-
ystep = 1
166-
else:
167-
ystep = -1
168-
169-
for x in range(x0, x1):
170-
if steep:
171-
self._bitmap[y0, x] = color
172-
else:
173-
self._bitmap[x, y0] = color
174-
err -= dy
175-
if err < 0:
176-
y0 += ystep
177-
err += dx
178138
# pylint: enable=invalid-name, too-many-locals, too-many-branches
179139

180140
@property
@@ -191,18 +151,3 @@ def fill(self, color):
191151
else:
192152
self._palette[2] = color
193153
self._palette.make_opaque(2)
194-
195-
@property
196-
def outline(self):
197-
"""The outline of the triangle. Can be a hex value for a color or
198-
``None`` for no outline."""
199-
return self._palette[1]
200-
201-
@outline.setter
202-
def outline(self, color):
203-
if color is None:
204-
self._palette[1] = 0
205-
self._palette.make_transparent(1)
206-
else:
207-
self._palette[1] = color
208-
self._palette.make_opaque(1)

examples/display_shapes_simpletest.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
from adafruit_display_shapes.circle import Circle
55
from adafruit_display_shapes.roundrect import RoundRect
66
from adafruit_display_shapes.triangle import Triangle
7+
from adafruit_display_shapes.line import Line
8+
from adafruit_display_shapes.polygon import Polygon
79

810
# Make the display context
9-
splash = displayio.Group(max_size=10)
11+
splash = displayio.Group(max_size=20)
1012
board.DISPLAY.show(splash)
1113

1214
# Make a background color fill
@@ -18,6 +20,16 @@
1820
splash.append(bg_sprite)
1921
##########################################################################
2022

23+
splash.append(Line(220, 130, 270, 210, 0xFF0000))
24+
splash.append(Line(270, 210, 220, 210, 0xFF0000))
25+
splash.append(Line(220, 210, 270, 130, 0xFF0000))
26+
splash.append(Line(270, 130, 220, 130, 0xFF0000))
27+
28+
#Draw a blue star
29+
polygon = Polygon([(255, 40), (262, 62), (285, 62), (265, 76), (275, 100),
30+
(255, 84), (235, 100), (245, 76), (225, 62), (248, 62)], outline=0x0000FF)
31+
splash.append(polygon)
32+
2133
triangle = Triangle(170, 50, 120, 140, 210, 160, fill=0x00FF00, outline=0xFF00FF)
2234
splash.append(triangle)
2335

0 commit comments

Comments
 (0)