Skip to content

Commit

Permalink
New hue example, tidy up others
Browse files Browse the repository at this point in the history
  • Loading branch information
Gadgetoid committed Nov 30, 2020
1 parent d9bb8b4 commit 4b805c6
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 75 deletions.
102 changes: 32 additions & 70 deletions examples/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,29 @@
import os
import pygame
import time
import random
import signal
import colorsys
import math
from hyperpixel2r import Touch


print("""HyperPixel 2 Lots of Circles Demo
Run with: sudo SDL_FBDEV=/dev/fb0 python3 demo.py
""")


hue_to_rgb = []


for i in range(0, 255):
hue_to_rgb.append(colorsys.hsv_to_rgb(i / 255.0, 1, 1))


def checker(x, y, step):
u_width = 48
u_height = 48
x -= (u_width / 2)
y -= (u_height / 2)
angle = (step / 10.0)
s = math.sin(angle)
c = math.cos(angle)
xs = x * c - y * s
ys = x * s + y * c
xs -= math.sin(step / 200.0) * 40.0
ys -= math.cos(step / 200.0) * 40.0
scale = step % 20
scale /= 20
scale = (math.sin(step / 50.0) / 8.0) + 0.25
xs *= scale
ys *= scale
xo = abs(xs) - int(abs(xs))
yo = abs(ys) - int(abs(ys))
v = 0 if (math.floor(xs) + math.floor(ys)) % 2 else 1 if xo > .1 and yo > .1 else .5
r, g, b = hue_to_rgb[step % 255]
return (r * (v * 255), g * (v * 255), b * (v * 255))


# zoom tunnel
def tunnel(x, y, step):
u_width = 16
u_height = 16
u_width = 32
u_height = 32
speed = step / 100.0
x -= (u_width / 2)
y -= (u_height / 2)
Expand Down Expand Up @@ -77,7 +58,6 @@ def tunnel(x, y, step):
return (col[0] * 255, col[1] * 255, col[2] * 255)



class Hyperpixel2r:
screen = None

Expand All @@ -87,7 +67,7 @@ def __init__(self):
# http://www.karoltomala.com/blog/?p=679
disp_no = os.getenv("DISPLAY")
if disp_no:
print ("I'm running under X display = {0}".format(disp_no))
print("I'm running under X display = {0}".format(disp_no))

# Check which frame buffer drivers are available
# Start with fbcon since directfb hangs with composite output
Expand All @@ -100,7 +80,7 @@ def __init__(self):
try:
pygame.display.init()
except pygame.error:
print('Driver: {0} failed. ({1})'.format(driver, dir(pygame.error)))
print('Driver: {0} failed.'.format(driver))
continue
found = True
break
Expand All @@ -111,54 +91,36 @@ def __init__(self):
size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
print("Framebuffer size: {:d} x {:d}".format(*size))
self.screen = pygame.display.set_mode((640, 480), pygame.FULLSCREEN | pygame.DOUBLEBUF | pygame.NOFRAME | pygame.HWSURFACE)
# Clear the screen to start
self.screen.fill((0, 0, 0))
# Initialise font support
pygame.font.init()
# Render the screen
self.screen.fill((0, 0, 0))
pygame.display.update()

def __del__(self):
"Destructor to make sure pygame shuts down, etc."

def test(self):
for colour in [(255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 0, 0)]:
self.screen.fill(colour)
pygame.display.update()
time.sleep(1.0)

def demo(self, t):
#t = int(time.time() * 60)
for x in range(16):
for y in range(16):
r, g, b = tunnel(x, y, t)
r = min(255, int(r))
g = min(255, int(g))
b = min(255, int(b))
for px in range(5):
for py in range(5):
self.screen.set_at(((x * 30) + px, (y * 30) + py), (r, g, b))
pygame.display.update()
def demo(self):
while True:
t = int(time.time() * 40)
for x in range(32):
for y in range(32):
r, g, b = tunnel(x, y, t)
r = min(255, int(r))
g = min(255, int(g))
b = min(255, int(b))
pygame.draw.circle(self.screen, (r, g, b), ((x * 15) + 6, (y * 15) + 6 + 7), 7)

pygame.display.flip()

def touch(self, x, y, state):
pass

def pen(self, x, y, state):
print(x, y, state)
r, g, b = [int(c * 255) for c in colorsys.hsv_to_rgb(time.time() / 10.0, 1.0, 1.0)]
if state:
self.screen.set_at((x, y), (r, g, b))
pygame.display.update()

# Create an instance of the PyScope class
display = Hyperpixel2r()
touch = Touch()


@touch.on_touch
def handle_touch(touch_id, x, y, state):
display.pen(x, y, state)

#display.test()
step = 0
while True:
display.demo(step)
step += 1
signal.pause()
#time.sleep(10)
display.touch(x, y, state)


display.demo()
140 changes: 140 additions & 0 deletions examples/hue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!/usr/bin/env python3
import os
import pygame
import math
from colorsys import hsv_to_rgb
from hyperpixel2r import Touch
# import rgbmatrix5x5


"""
HyperPixel 2 Hue
Run with: sudo SDL_FBDEV=/dev/fb0 python3 hue.py
"""


class Hyperpixel2r:
screen = None

def __init__(self):
# Based on "Python GUI in Linux frame buffer"
# http://www.karoltomala.com/blog/?p=679
disp_no = os.getenv("DISPLAY")
if disp_no:
print("I'm running under X display = {0}".format(disp_no))

# Check which frame buffer drivers are available
# Start with fbcon since directfb hangs with composite output
drivers = ['fbcon', 'directfb', 'svgalib']
found = False
for driver in drivers:
# Make sure that SDL_VIDEODRIVER is set
if not os.getenv('SDL_VIDEODRIVER'):
os.putenv('SDL_VIDEODRIVER', driver)
try:
pygame.display.init()
except pygame.error:
print('Driver: {0} failed. ({1})'.format(driver, dir(pygame.error)))
continue
found = True
break

if not found:
raise Exception('No suitable video driver found!')

size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
print("Framebuffer size: {:d} x {:d}".format(*size))
self.screen = pygame.display.set_mode((640, 480), pygame.FULLSCREEN | pygame.DOUBLEBUF | pygame.NOFRAME | pygame.HWSURFACE, 16)
self.screen.fill((0, 0, 0))
pygame.display.update()

# For some reason the canvas needs a 7px vertical offset
# circular screens are weird...
self.center = (240, 247)
self.radius = 240
self.inner_radius = 150

self._running = False
self._hue = 0
self._val = 1.0
self._origin = pygame.math.Vector2(*self.center)
self._clock = pygame.time.Clock()

# Draw the hue wheel as lines emenating from the inner to outer radius
# we overdraw 3x as many lines to get a nice solid fill... horribly inefficient but it works
for s in range(360 * 3):
a = s / 3.0
cos = math.cos(math.radians(a))
sin = math.sin(math.radians(a))
x = self.center[0] - self.radius * cos
y = self.center[1] - self.radius * sin

ox = self.center[0] - self.inner_radius * cos
oy = self.center[1] - self.inner_radius * sin

colour = tuple([int(c * 255) for c in hsv_to_rgb(a / 360.0, 1.0, 1.0)])
pygame.draw.line(self.screen, colour, (ox, oy), (x, y), 3)

def __del__(self):
"Destructor to make sure pygame shuts down, etc."

def get_colour(self):
return tuple([int(c * 255) for c in hsv_to_rgb(self._hue, 1.0, self._val)])

def touch(self, x, y, state):
target = pygame.math.Vector2(x, y)
distance = self._origin.distance_to(target)
angle = pygame.Vector2().angle_to(self._origin - target)

if distance < self.inner_radius and distance > self.inner_radius - 40:
return

angle %= 360
angle /= 360.0

if distance < self.inner_radius:
self._val = angle
else:
self._hue = angle

# print("Displaying #{0:02x}{1:02x}{2:02x} {3}".format(*self.get_colour(), angle))

def run(self):
self._running = True
while self._running:
self._colour = tuple([int(c * 255) for c in hsv_to_rgb(self._hue, 1.0, self._val)])
pygame.draw.circle(self.screen, self.get_colour(), self.center, self.inner_radius - 10)
pygame.draw.circle(self.screen, (0, 0, 0), self.center, self.inner_radius - 30)
for s in range(360 * 3):
a = s / 3.0
cos = math.cos(math.radians(a))
sin = math.sin(math.radians(a))
x, y = self.center
ox = x - (self.inner_radius - 40) * cos
oy = y - (self.inner_radius - 40) * sin
colour = tuple([int(c * 255) for c in hsv_to_rgb(self._hue, 1.0, a / 360.0)])
pygame.draw.line(self.screen, colour, (ox, oy), (x, y), 3)

pygame.display.flip()
self._clock.tick(30)


display = Hyperpixel2r()
touch = Touch()

# uncomment to set up rgbmatrix
# rgbmatrix = rgbmatrix5x5.RGBMatrix5x5(i2c_dev=touch._bus)
# rgbmatrix.set_clear_on_exit()


@touch.on_touch
def handle_touch(touch_id, x, y, state):
display.touch(x, y, state)
# uncomment to set colour on rgbmatrix,
# or try it with Mote USB or something!
# rgbmatrix.set_all(*display.get_colour())
# rgbmatrix.show()


display.run()
14 changes: 9 additions & 5 deletions examples/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import time
import signal
import math
from colorsys import hsv_to_rgb
from hyperpixel2r import Touch


Expand Down Expand Up @@ -47,11 +48,7 @@ def __init__(self):
size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
print("Framebuffer size: {:d} x {:d}".format(*size))
self.screen = pygame.display.set_mode((640, 480), pygame.FULLSCREEN | pygame.DOUBLEBUF | pygame.NOFRAME | pygame.HWSURFACE)
# Clear the screen to start
self.screen.fill((0, 0, 0))
# Initialise font support
pygame.font.init()
# Render the screen
pygame.display.update()

self._step = 0
Expand Down Expand Up @@ -83,6 +80,14 @@ def test(self, timeout=2):
pygame.display.update()
time.sleep(0.25)

for y in range(480):
hue = y / 480.0
colour = tuple([int(c * 255) for c in hsv_to_rgb(hue, 1.0, 1.0)])
pygame.draw.line(self.screen, colour, (0, y), (479, y))

pygame.display.update()
time.sleep(1.0)

while self._step < len(self._steps):
r, g, b, x, y = self._steps[self._step]
pygame.draw.circle(self.screen, (r, g, b), (x, y), 90)
Expand All @@ -97,7 +102,6 @@ def test(self, timeout=2):
self._step += 1


# Create an instance of the PyScope class
display = Hyperpixel2r()
touch = Touch()

Expand Down

0 comments on commit 4b805c6

Please sign in to comment.