-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds single thick lines and polylines. Joins are round, ends of single lines can be butt or round.
- Loading branch information
1 parent
9035351
commit 58ec39e
Showing
6 changed files
with
651 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import asyncio | ||
from array import array | ||
import framebuf | ||
import random | ||
import math | ||
|
||
from tempe.bitmaps import Bitmaps, ColoredBitmaps | ||
from tempe.colormaps.viridis import viridis | ||
from tempe.colormaps.viridis import viridis | ||
from tempe.data_view import Repeat, Range, Interpolated | ||
from tempe.geometry import RowGeometry, ColumnGeometry | ||
from tempe.surface import Surface | ||
from tempe.shapes import Rectangles | ||
from tempe.lines import WideLines, WidePolyLines | ||
from tempe.display import FileDisplay | ||
|
||
random.seed(0) | ||
|
||
surface = Surface() | ||
|
||
# a buffer one quarter the size of the screen | ||
working_buffer = array('H', bytearray(2*320*61)) | ||
|
||
# fill the background with white pixels | ||
background = Rectangles([(0, 0, 320, 240)], [0xffff]) | ||
surface.add_shape('BACKGROUND', background) | ||
|
||
|
||
# draw some lines | ||
lines = WideLines( | ||
ColumnGeometry([ | ||
Range(8, 96, 8), Repeat(20), Range(8, 184, 16), Repeat(100), | ||
Range(1, 11) | ||
]), | ||
Interpolated(viridis, 10), | ||
clip=(0, 0, 160, 120) | ||
) | ||
surface.add_shape('DRAWING', lines) | ||
|
||
|
||
# draw some lines in the opposite direction | ||
lines = WideLines( | ||
ColumnGeometry([ | ||
Range(8, 96, 8) + 160, Repeat(100), Range(8, 184, 16) + 160, Repeat(20), | ||
Range(1, 11) | ||
]), | ||
Interpolated(viridis, 10), | ||
clip=(160, 0, 160, 120), | ||
round=False, | ||
) | ||
surface.add_shape('DRAWING', lines) | ||
|
||
# draw some polylines | ||
polylines = WidePolyLines( | ||
RowGeometry([ | ||
( | ||
array('h', [ | ||
10 + 30 * i, 125, | ||
10 + 30 * i, 225, | ||
15 + 30 * i, 225, | ||
25 + 30 * i, 165, | ||
10 + 30 * i, 125, | ||
]), | ||
i+1, | ||
) | ||
for i in range(10) | ||
]), | ||
Interpolated(viridis, 10), | ||
clip=(0, 120, 320, 120) | ||
) | ||
surface.add_shape('DRAWING', polylines) | ||
|
||
def main(surface, working_buffer): | ||
|
||
|
||
async def init_display(): | ||
from devices.st7789 import ST7789 | ||
from machine import Pin, SPI | ||
|
||
spi = SPI(0, baudrate=62_500_000, phase=1, polarity=1, sck=Pin(18, Pin.OUT), mosi=Pin(19, Pin.OUT), miso=Pin(16, Pin.OUT)) | ||
backlight = Pin(20, Pin.OUT) | ||
display = ST7789(spi, cs_pin=Pin(17, Pin.OUT, value=1), dc_pin=Pin(16, Pin.OUT)) | ||
backlight(1) | ||
await display.init() | ||
return display | ||
|
||
# set up the display object | ||
display = asyncio.run(init_display()) | ||
|
||
# refresh the display | ||
display.clear() | ||
surface.refresh(display, working_buffer) | ||
|
||
if __name__ == '__main__': | ||
|
||
# if we have an actual screen, use it | ||
main(surface, working_buffer) | ||
|
||
elif __name__ != '__test__': | ||
|
||
# set up the display object | ||
display = FileDisplay('lines.rgb565', (320, 240)) | ||
# refresh the display | ||
with display: | ||
display.clear() | ||
surface.refresh(display, working_buffer) |
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,34 @@ | ||
import micropython | ||
|
||
|
||
@micropython.viper | ||
def line_points(x0: int, y0: int, x1: int, y1: int, w: int, d: int, vertices: ptr16): | ||
dx: int = x1 - x0 | ||
dy: int = y1 - y0 | ||
|
||
# stuff to handle inter division always round down, when we really | ||
# want away from 0 | ||
if dx == 0: | ||
mx = -((w + 1) // 2) | ||
else: | ||
if dy > 0: | ||
mx = -w * dy // d | ||
else: | ||
mx = -(w * dy // d) | ||
if dy == 0: | ||
my = (w + 1) // 2 | ||
else: | ||
if dx > 0: | ||
my = -(-w * dx // d) | ||
else: | ||
my = w * dx // d | ||
|
||
vertices[0] = x0 + mx | ||
vertices[1] = y0 + my | ||
vertices[2] = x1 + mx | ||
vertices[3] = y1 + my | ||
vertices[4] = x1 - mx | ||
vertices[5] = y1 - my | ||
vertices[6] = x0 - mx | ||
vertices[7] = y0 - my | ||
|
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,130 @@ | ||
from array import array | ||
from math import sqrt | ||
import micropython | ||
|
||
from .shapes import ColoredGeometry | ||
|
||
|
||
class WideLines(ColoredGeometry): | ||
"""Render multiple colored line segments with variable width. | ||
Geometry should produce x0, y0, x1, y1, width arrays. | ||
""" | ||
|
||
def __init__(self, geometry, colors, *, round=True, surface=None, clip=None): | ||
super().__init__(geometry, colors, surface=surface, clip=clip) | ||
self.round = round | ||
|
||
def draw(self, buffer, x=0, y=0): | ||
vertices = array('h', bytearray(16)) | ||
should_round = self.round | ||
for geometry, color in self: | ||
x0 = geometry[0] | ||
y0 = geometry[1] | ||
x1 = geometry[2] | ||
y1 = geometry[3] | ||
w = geometry[4] | ||
if w < 2: | ||
buffer.line(x0 - x, y0 - y, x1 - x, y1 - y, color) | ||
else: | ||
d = 2 * int(sqrt((x1 - x0)**2 + (y1 - y0)**2)) | ||
line_points(x0, y0, x1, y1, w, d, vertices) | ||
buffer.poly(-x, -y, vertices, color, True) | ||
if should_round: | ||
r = w // 2 | ||
buffer.ellipse(x0 - x, y0 - y, r, r, color, True) | ||
buffer.ellipse(x1 - x, y1 - y, r, r, color, True) | ||
|
||
def _bounds(self): | ||
max_x = -0x7fff | ||
min_x = 0x7fff | ||
max_y = -0x7fff | ||
min_y = 0x7fff | ||
for geometry in self.geometry: | ||
max_x = max(max_x, geometry[0] + geometry[4], geometry[2] + geometry[4]) | ||
min_x = min(min_x, geometry[0] - geometry[4], geometry[2] - geometry[4]) | ||
max_y = max(max_y, geometry[1] + geometry[4], geometry[3] + geometry[4]) | ||
min_y = min(min_y, geometry[1] - geometry[4], geometry[3] - geometry[4]) | ||
|
||
return (min_x, min_y, max_x - min_x, max_y - min_y) | ||
|
||
|
||
|
||
class WidePolyLines(ColoredGeometry): | ||
"""Render multiple colored polylines with variable width. | ||
Geometry should produce array of [x0, y0, x1, y1, ...] and width. | ||
""" | ||
|
||
def draw(self, buffer, x=0, y=0): | ||
vertices = array('h', bytearray(16)) | ||
for geometry, color in self: | ||
lines, w = geometry | ||
for i in range(0, len(lines) - 2, 2): | ||
x0 = lines[i] | ||
y0 = lines[i+1] | ||
x1 = lines[i+2] | ||
y1 = lines[i+3] | ||
if w < 2: | ||
buffer.line(x0 - x, y0 - y, x1 - x, y1 - y, color) | ||
else: | ||
d = 2 * int(sqrt((x1 - x0)**2 + (y1 - y0)**2)) | ||
line_points(x0, y0, x1, y1, w, d, vertices) | ||
buffer.poly(-x, -y, vertices, color, True) | ||
if w >= 2: | ||
r = w // 2 | ||
for i in range(0, len(lines), 2): | ||
x0 = lines[i] | ||
y0 = lines[i+1] | ||
buffer.ellipse(x0 - x, y0 - y, r, r, color, True) | ||
|
||
def _bounds(self): | ||
max_x = -0x7fff | ||
min_x = 0x7fff | ||
max_y = -0x7fff | ||
min_y = 0x7fff | ||
for geometry in self.geometry: | ||
lines, w = geometry | ||
for i in range(0, len(lines), 2): | ||
max_x = max(max_x, lines[i] + w) | ||
min_x = min(min_x, lines[i] - w) | ||
max_y = max(max_y, lines[i+1] + w) | ||
min_y = min(min_y, lines[i+1] - w) | ||
|
||
return (min_x, min_y, max_x - min_x, max_y - min_y) | ||
|
||
|
||
def line_points(x0, y0, x1, y1, w, d, vertices): | ||
dx = x1 - x0 | ||
dy = y1 - y0 | ||
|
||
# stuff to handle inter division always round down, when we really | ||
# want away from 0 | ||
if dx == 0: | ||
mx = -((w + 1) // 2) | ||
else: | ||
if dy > 0: | ||
mx = -w * dy // d | ||
else: | ||
mx = -(w * dy // d) | ||
if dy == 0: | ||
my = (w + 1) // 2 | ||
else: | ||
if dx > 0: | ||
my = -(-w * dx // d) | ||
else: | ||
my = w * dx // d | ||
|
||
vertices[0] = x0 + mx | ||
vertices[1] = y0 + my | ||
vertices[2] = x1 + mx | ||
vertices[3] = y1 + my | ||
vertices[4] = x1 - mx | ||
vertices[5] = y1 - my | ||
vertices[6] = x0 - mx | ||
vertices[7] = y0 - my | ||
|
||
try: | ||
from ._speedups import line_points | ||
except SyntaxError: | ||
pass |
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 |
---|---|---|
@@ -1,6 +1,19 @@ | ||
{ | ||
"urls": [ | ||
["tempe/__init__.py", "github:unital/tempe/src/tempe/__init__.py"], | ||
["tempe/_speedups.py", "github:unital/tempe/src/tempe/_speedups.py"], | ||
["tempe/_data_view_math.py", "github:unital/tempe/src/tempe/_data_view_math.py"], | ||
["tempe/bitmaps.py", "github:unital/tempe/src/tempe/bitmaps.py"], | ||
["tempe/data_view.py", "github:unital/tempe/src/tempe/data_view.py"], | ||
["tempe/display.py", "github:unital/tempe/src/tempe/display.py"], | ||
["tempe/geometry.py", "github:unital/tempe/src/tempe/geometry.py"], | ||
["tempe/lines.py", "github:unital/tempe/src/tempe/lines.py"], | ||
["tempe/markers.py", "github:unital/tempe/src/tempe/markers.py"], | ||
["tempe/raster.py", "github:unital/tempe/src/tempe/raster.py"], | ||
["tempe/shapes.py", "github:unital/tempe/src/tempe/shapes.py"], | ||
["tempe/surface.py", "github:unital/tempe/src/tempe/surface.py"], | ||
["tempe/text.py", "github:unital/tempe/src/tempe/text.py"], | ||
["tempe/util.py", "github:unital/tempe/src/tempe/util.py"] | ||
], | ||
"version": "0.1" | ||
} |
Oops, something went wrong.