-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathabstract_plotter.py
More file actions
111 lines (82 loc) · 2.83 KB
/
Copy pathabstract_plotter.py
File metadata and controls
111 lines (82 loc) · 2.83 KB
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
from bmp import MonoBitmapWriter
class Frame:
def __init__(self, *specs):
self.width, self.height, self.tm, self.bm, self.lm, self.rm = specs
def bottom(self):
return self.height - self.bm
def y_span(self):
return self.bottom() - self.tm
def right(self):
return self.width - self.rm
class AbstractPlotter:
def __init__(self, frame: Frame = None):
self.frame = frame if frame else self.default_frame()
self.pen = None
def line(self, x1, y1, x2, y2, color=None):
if color is not None:
self.set_pen(color)
x1 = round(x1)
y1 = round(y1)
x2 = round(x2)
y2 = round(y2)
for (x, y) in self.bresenham(x1, y1, x2, y2):
self.display_pixel(x, y)
def width(self) -> int:
return self.frame.width
def height(self) -> int:
return self.frame.height
def text(self, x, y, text):
pass
def default_frame(self) -> Frame:
pass
def show(self):
pass
def get_pixel(self, x, y) -> tuple:
pass
def set_pen(self, color: tuple):
self.pen = color
def circle(self, x, y, r, color):
pass
def display_pixel(self, x, y):
pass
def write_mono_bitmap(self, file_name):
with MonoBitmapWriter(file_name, self.frame.width, self.frame.height) as mbw:
bytes_in_row = self.frame.width // 8
row_bytes = bytearray(bytes_in_row)
for i in range(self.frame.height):
for j in range(bytes_in_row):
row_bytes[j] = 0
for k in range(8):
x = k + 8 * j
y = self.frame.height - (i + 1)
bit = ((0,0,0) != self.get_pixel(x, y))
row_bytes[j] |= bit << (7 - k)
mbw.add_row(row_bytes)
"""Implementation of Bresenham's line drawing algorithm
See en.wikipedia.org/wiki/Bresenham's_line_algorithm
Code from https://github.com/encukou/bresenham
"""
def bresenham(self, x0, y0, x1, y1):
"""Yield integer coordinates on the line from (x0, y0) to (x1, y1).
Input coordinates should be integers.
The result will contain both the start and the end point.
"""
dx = x1 - x0
dy = y1 - y0
xsign = 1 if dx > 0 else -1
ysign = 1 if dy > 0 else -1
dx = abs(dx)
dy = abs(dy)
if dx > dy:
xx, xy, yx, yy = xsign, 0, 0, ysign
else:
dx, dy = dy, dx
xx, xy, yx, yy = 0, ysign, xsign, 0
D = 2 * dy - dx
y = 0
for x in range(dx + 1):
yield x0 + x * xx + y * yx, y0 + x * xy + y * yy
if D >= 0:
y += 1
D -= 2 * dx
D += 2 * dy