またRaspberryPiですが、今度はお絵かきアプリを作ってみました。折れ線(Polyline)をつないで絵を描きます。ジョイスティックでカーソルを移動し、ボタンを押すと、そこを折れ点とし、さらに伸ばす、を繰り返します。
ななめの描き方のアルゴリズムがあるみたいですね。一応それらしく実装してみましたが…まあご覧の通りです。
 
そう言えば、signal.pause()を今回初めて知りました。いいですね〜。
# sensehatutil.py
from sense_hat import SenseHat, ACTION_PRESSED, ACTION_HELD, ACTION_RELEASED
import numpy as np
from enum import Enum
red = (255, 0, 0)
blue = (0, 0, 255)
yellow=(255,255,0)
purple=(128,0,128)
green=(0,255,0)
indigg=(75,0,130)
orange=(255,128,0)
pink=(255,193,203)
black=(0,0,0)
height = 8
width = 8
sense = SenseHat()
def Initialize():
    sense.clear()
    sense.set_rotation(0)
def CreateImageArray():
    return np.zeros((height, width, 3), np.uint8)
def SetArrayToPixels(imageArray):
    sense.set_pixels(imageArray.reshape(height*width,3))
def PutVertex(imageArray, pt, color):
    imageArray[pt[1], pt[0]] = color
    return imageArray
def PutRect(imageArray, lower, upper, color):
    for col in range(lower[0], upper[0]+1):
        imageArray[lower[1]:upper[1]+1, col] = color
    return imageArray
def PutLine(imageArray, p1, p2, color):
    if abs(p1[0]-p2[0]) > abs(p1[1]-p2[1]):
        if p1[0] == p2[0]:
            rs = min(p1[1], p2[1])
            re = max(p1[1], p2[1]) + 1
            imageArray[rs:re, p1[0]] = color
            return imageArray
        def f(x):
            return (float(p2[1])-float(p1[1]))/(float(p2[0])-float(p1[0]))*(float(x)-float(p1[0]))+float(p1[1])
        col_range = range(min(p1[0], p2[0]), max(p1[0], p2[0])+1)
        for col in col_range:
            row = int(round(f(col)))
            imageArray[row, col] = color
    else:
        if p1[1] == p2[1]:
            cs = min(p1[0], p2[0])
            ce = max(p1[0], p2[0]) + 1
            imageArray[p1[1], cs:ce] = color
            return imageArray
        def f(y):
            return (float(p2[0])-float(p1[0]))/(float(p2[1])-float(p1[1]))*(float(y)-float(p1[1]))+float(p1[0])
        row_range = range(min(p1[1], p2[1]), max(p1[1], p2[1])+1)
        for row in row_range:
            col = int(round(f(row)))
            imageArray[row, col] = color
    return imageArray
def PutPolyline(imageArray, ptArray, doClose, color):
    p1 = []
    p_prev = []
    for pt in ptArray:
        if p1 == []:
            p1 = pt
            p_prev = pt
            continue
        
        imageArray = PutLine(imageArray, p_prev, pt, color)
        p_prev = pt
    if doClose:
        imageArray = PutLine(imageArray, p_prev, p1, color)
    return imageArray
# main.py
from signal import pause
import sensehatutil as sh
sh.Initialize()
apex = (3,3)
ptArray = list()
def AddApex(event):
    global apex, ptArray
    if event.action != sh.ACTION_PRESSED:
        return
    ptArray.append(apex)
def MoveApex(event):
    global apex
    if event.action != sh.ACTION_PRESSED:
        return
    d = event.direction
    if d == 'right':
        apex = (min(apex[0] + 1, sh.width-1), apex[1])
    elif d == 'left':
        apex = (max(apex[0] - 1, 0), apex[1])
    elif d == 'up':
        apex = (apex[0], max(apex[1] - 1, 0))
    elif d == 'down':
        apex = (apex[0], min(apex[1] + 1, sh.height-1))
def Reflesh():
    global apex, ptArray
    img = sh.CreateImageArray()
    ptArrayTmp = list()
    for pt in ptArray:
        ptArrayTmp.append(pt)
    ptArrayTmp.append(apex)
    img = sh.PutPolyline(img, ptArrayTmp, False, sh.orange)
    for pt in ptArray:
        img = sh.PutVertex(img, pt, sh.purple)
    img = sh.PutVertex(img, apex, sh.red)
    sh.SetArrayToPixels(img)
sh.sense.stick.direction_middle = AddApex
sh.sense.stick.direction_right = MoveApex
sh.sense.stick.direction_left = MoveApex
sh.sense.stick.direction_up = MoveApex
sh.sense.stick.direction_down = MoveApex
sh.sense.stick.direction_any = Reflesh
Reflesh()
pause()

