forked from ladyada/Adafruit_CircuitPython_Display_Shapes
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from bablokb/arc
add support for arcs
- Loading branch information
Showing
5 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# SPDX-FileCopyrightText: 2023 Bernhard Bablok | ||
# | ||
# SPDX-License-Identifier: MIT | ||
|
||
""" | ||
`arc` | ||
================================================================================ | ||
Various common shapes for use with displayio - Arc shape! | ||
* Author(s): Bernhard Bablok | ||
Implementation Notes | ||
-------------------- | ||
**Software and Dependencies:** | ||
* Adafruit CircuitPython firmware for the supported boards: | ||
https://github.com/adafruit/circuitpython/releases | ||
""" | ||
|
||
try: | ||
from typing import Optional | ||
except ImportError: | ||
pass | ||
|
||
import math | ||
import displayio | ||
from adafruit_display_shapes.polygon import Polygon | ||
|
||
try: | ||
import vectorio | ||
|
||
HAVE_VECTORIO = True | ||
except ImportError: | ||
HAVE_VECTORIO = False | ||
|
||
__version__ = "0.0.0+auto.0" | ||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes.git" | ||
|
||
|
||
class Arc(displayio.Group): | ||
# pylint: disable=too-few-public-methods, invalid-name | ||
"""An arc. Technically, an arc is a Group with one or two polygons. | ||
An arc is defined by a radius, an angle (in degrees) and a direction (also in | ||
degrees). The latter is the direction of the midpoint of the arc. | ||
The direction-parameter uses the layout of polar-coordinates, i.e. zero points | ||
to the right, 90 to the top, 180 to the left and 270 to the bottom. | ||
The Arc-class creates the arc as a polygon. The number of segments define | ||
how round the arc is. There is a memory-tradeoff if the segment-number is | ||
large. | ||
:param float radius: The (outer) radius of the arc. | ||
:param float angle: The angle of the arc in degrees. | ||
:param float direction: The direction of the middle-point of the arc in degrees (0) | ||
:param int segments: The number of segments of the arc. | ||
:param arc_width int: (Optional) The width of the arc. This creates an inner arc as well. | ||
:param int|None outline: The outline of the arc. Can be a hex value for a color or | ||
``None`` for no outline. | ||
:param int|None fill: The fill-color of the arc. Can be a hex value for a color or | ||
``None`` for no filling. Ignored if port does not support vectorio. | ||
""" | ||
|
||
def __init__( | ||
# pylint: disable=too-many-arguments, too-many-locals | ||
self, | ||
radius: float, | ||
angle: float, | ||
direction: float, | ||
segments: int, | ||
*args, | ||
arc_width: Optional[int] = 1, | ||
outline: Optional[int] = None, | ||
fill: Optional[int] = None, | ||
**kwargs, | ||
) -> None: | ||
super().__init__(*args, **kwargs) | ||
# shift direction by angle/2 | ||
direction = direction - angle / 2 | ||
# create outer points | ||
points = [] | ||
for i in range(segments + 1): | ||
alpha = (i * angle / segments + direction) / 180 * math.pi | ||
x0 = int(radius * math.cos(alpha)) | ||
y0 = -int(radius * math.sin(alpha)) | ||
points.append((x0, y0)) | ||
|
||
# create inner points | ||
if arc_width > 1: | ||
for i in range(segments, -1, -1): | ||
alpha = (i * angle / segments + direction) / 180 * math.pi | ||
x0 = int((radius - arc_width) * math.cos(alpha)) | ||
y0 = -int((radius - arc_width) * math.sin(alpha)) | ||
points.append((x0, y0)) | ||
|
||
# create polygon(s) and add to ourselves | ||
if arc_width > 1 and HAVE_VECTORIO and fill is not None: | ||
palette = displayio.Palette(1) | ||
palette[0] = fill | ||
self.append(vectorio.Polygon(pixel_shader=palette, points=points, x=0, y=0)) | ||
if outline is not None: | ||
self.append(Polygon(points, outline=outline, colors=1, close=arc_width > 1)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# SPDX-FileCopyrightText: 2023 Bernhard Bablok | ||
# SPDX-License-Identifier: MIT | ||
|
||
import time | ||
import board | ||
|
||
import displayio | ||
from adafruit_display_shapes.arc import Arc | ||
from adafruit_display_shapes.circle import Circle | ||
|
||
# use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.) | ||
# see guide for setting up external displays (TFT / OLED breakouts, RGB matrices, etc.) | ||
# https://learn.adafruit.com/circuitpython-display-support-using-displayio/display-and-display-bus | ||
display = board.DISPLAY | ||
|
||
w2 = int(display.width / 2) | ||
h2 = int(display.height / 2) | ||
|
||
WHITE = 0xFFFFFF | ||
RED = 0xFF0000 | ||
GREEN = 0x00FF00 | ||
BLUE = 0x0000FF | ||
|
||
# Make the display context | ||
group = displayio.Group() | ||
display.root_group = group | ||
|
||
# little circle in the center of all arcs | ||
circle = Circle(w2, h2, 5, fill=0xFF0000, outline=0xFF0000) | ||
group.append(circle) | ||
|
||
# red arc with white outline, 10 pixels wide | ||
arc1 = Arc( | ||
x=w2, | ||
y=h2, | ||
radius=min(display.width, display.height) / 4, | ||
angle=90, | ||
direction=90, | ||
segments=10, | ||
arc_width=10, | ||
outline=WHITE, | ||
fill=RED, | ||
) | ||
group.append(arc1) | ||
|
||
# green arc (single line) | ||
arc2 = Arc( | ||
x=w2, | ||
y=h2, | ||
radius=min(display.width, display.height) / 4 + 5, | ||
angle=180, | ||
direction=90, | ||
segments=20, | ||
arc_width=1, | ||
outline=GREEN, | ||
) | ||
group.append(arc2) | ||
|
||
# blue arc (or pie) | ||
arc3 = Arc( | ||
x=w2, | ||
y=h2, | ||
radius=min(display.width, display.height) / 4, | ||
angle=90, | ||
direction=-90, | ||
segments=10, | ||
arc_width=min(display.width, display.height) / 4 - 5, | ||
outline=BLUE, | ||
) | ||
group.append(arc3) | ||
|
||
while True: | ||
time.sleep(0.1) |