#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Display hack to imitate one of those laser projector things that
make a lot of dots swirling around on the ceiling or floor.
"""
import math
import pygame
matrix_width = 7 # Number of points across the matrix.
ww, hh = 640, 400 # Screen size.
coords = range(-(matrix_width/2), matrix_width/2+1)
scr = pygame.display.set_mode((ww, hh), pygame.FULLSCREEN)
cx, cy = ww/2, hh/2 # Center x and y.
spacing = min(ww, hh) / (matrix_width-1) # Spacing between the points.
matrix = [(x*spacing, y*spacing, x**2+y**2) for x in coords for y in coords]
max_r2 = max(r2 for xx, yy, r2 in matrix) # maximum r²
full_brightness = max_r2 * 3/2 # r² at which brightness would be 100%
pygame.mouse.set_visible(False)
theta = 0 # Angle around a circle the points move in.
while pygame.event.poll().type not in (pygame.QUIT, pygame.MOUSEBUTTONDOWN):
scr.fill(0) # Clear screen to black.
ss = math.sin(theta)/2 + 0.5
cc = math.cos(theta)/2
for x2, y2, r2 in matrix:
# Brightness. Originally this was α (thus the name aa) but I
# decided simple saturating addition was both simpler and more
# faithful to the laser device.
aa = 255*(max_r2-r2)/full_brightness
x2s = x2*ss - y2*cc
y2c = x2*cc + y2*ss
for x1, y1, _ in matrix:
xx = int(x1 + cx + x2s)
yy = int(y1 + cy + y2c)
if not 0 <= xx < ww or not 0 <= yy < hh:
continue
rr, gg, bb, _ = scr.get_at((xx, yy))
scr.set_at((xx, yy), (rr, min(255, gg+aa), bb))
theta += 0.03
pygame.display.flip()