-
Notifications
You must be signed in to change notification settings - Fork 0
/
ezmatrix.py
197 lines (151 loc) · 5.65 KB
/
ezmatrix.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
from rgbmatrix import RGBMatrix, RGBMatrixOptions
import time
import math
import random
class EzMatrix(object):
"""Responsible for handling communication with matrix"""
def __init__(self, rows=32, cols=32, chain_length=1):
options = RGBMatrixOptions()
options.rows = rows
options.chain_length = chain_length
options.parallel = 1
options.hardware_mapping = 'adafruit-hat'
options.cols = cols
self.matrix = RGBMatrix(options = options)
def draw_canvas(self, canvas):
for y in range(len(canvas)):
for x in range(len(canvas[y])):
pixel = canvas[y][x]
self.matrix.SetPixel(x, y, pixel.r, pixel.g, pixel.b)
def run_anim(self, anim):
sleep = 0.07
for canvas in anim:
self.draw_canvas(canvas)
time.sleep(sleep)
self.matrix.Clear()
class Geometry():
"""Handles linear interpolation for drawing lines and rectangles"""
@staticmethod
def distance(start, end):
dx = end.x - start.x
dy = end.y - start.y
dx = dx ** 2
dy = dy ** 2
return math.sqrt(dx + dy)
@staticmethod
# linear interpolation
# takes in single value integers, not points
def lirp(start, end, t):
return start + t * (end - start)
@staticmethod
def lirp_points(start, end, t):
return Point(Geometry.lirp(start.x, end.x, t), Geometry.lirp(start.y, end.y, t))
@staticmethod
def get_points_in_line(start, end):
num_points = Geometry.distance(start, end)
points = []
for i in range(int(num_points)):
t = float(i) / float(num_points)
points.append(Geometry.lirp_points(start, end, t))
points.append(end)
return points
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return ('({}, {})'.format(self.x, self.y))
class Color():
def __init__(self, r, g, b):
self.r = r
self.g = g
self.b = b
def __repr__(self):
return('(R:{} G:{} B:{})'.format(self.r, self.g, self.b))
@classmethod
def red(cls):
return cls(255, 0, 0)
@classmethod
def green(cls):
return cls(0, 255, 0)
@classmethod
def blue(cls):
return cls(0, 0, 255)
@classmethod
def gray(cls):
return cls(128, 128, 128)
@classmethod
def white(cls):
return cls(255, 255, 255)
@classmethod
def off(cls):
return cls(0, 0, 0)
class Canvas(list):
"""Holds Color values in a list used for displaying colors on a matrix"""
def __init__(self, width=32, height=32):
lst = []
for row in range(height):
color_row = []
for col in range(width):
color_row.append(Color.off())
self.append(color_row)
self = lst
def add_subcanvas(self, subcanvas, translation=Point(0, 0)):
# adding a translation of Point(3, 3) would move the
# subcanvas right 3 and down 3
# translation: must be a Point
for y in range(len(subcanvas)):
for x in range(len(subcanvas[y])):
self[y + translation.y][x + translation.x] = subcanvas[y][x]
return self
def draw_line(self, start, end, color):
points = Geometry.get_points_in_line(start, end)
for point in points:
x = int(round(point.x, 0))
y = int(round(point.y, 0))
#print('({}, {})'.format(x, y))
self[y][x] = color
return self
def draw_rectangle(self, top_l, top_r, bot_l, bot_r, color):
self.draw_line(top_l, bot_l, color)
self.draw_line(bot_l, bot_r, color)
self.draw_line(bot_r, top_r, color)
self.draw_line(top_r, top_l, color)
return self
def has_data(self):
for row in self:
for color in row:
if color.r != 0 and color.g != 0 and color.b != 0:
return True
return False
class Animation(list):
"""Instead of using this you should just save animations as a list of Canvases"""
def __init__(self, length=32):
lst = []
for i in range(length):
self.append(Canvas())
self = lst
def rect_rotation(self, point, size, color):
point_left = point
point_bottom = Point(point_left.x, point_left.y + size)
point_right = Point(point_bottom.x + size, point_bottom.y)
point_top = Point(point_right.x, point_right.y - size)
for i, canvas in enumerate(self):
wait = float(1/float(size)) * float(len(self))
if i != 0 and i % wait < 1:
point_left.y += 1
point_bottom.x += 1
point_right.y -= 1
point_top.x -= 1
self[i] = canvas.draw_line(point_left, point_bottom, color)
self[i] = canvas.draw_line(point_bottom, point_right, color)
self[i] = canvas.draw_line(point_right, point_top, color)
self[i] = canvas.draw_line(point_top, point_left, color)
return self
def has_data(self):
for cvs in self:
for row in cvs:
for color in row:
if color.r != 0 and color.g != 0 and color.b != 0:
return True
return False