commit 36f296babe054920b174b5db07ecb10531122d20
parent 2fd7381d4f37ec002bf50a1d145aae53424e2e16
Author: bkopf <vetlehaf@stud.ntnu.no>
Date: Sat, 17 Nov 2018 18:37:21 +0100
Start implementing line detection
Diffstat:
M | a2svg.py | | | 153 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- |
M | ascii.txt | | | 37 | ++++++++++++++++++++----------------- |
2 files changed, 153 insertions(+), 37 deletions(-)
diff --git a/a2svg.py b/a2svg.py
@@ -1,10 +1,13 @@
#!/bin/python
+font_size = 12
class Figure:
def __init__(self, ascii_text):
self._elements = []
- self._process_queue = []
+ self._process_queue = [] # You might want to refactor this away.
+ # OR make it more useful in the
+ # process_all method
self._ascii_text = [line.strip('\n') for line in ascii_text]
self._height = len(ascii_text)
self._width = max([len(line) for line in ascii_text])
@@ -27,7 +30,7 @@ class Figure:
for x, cell in enumerate(line):
self._figarray[y][x] = cell
- def process(self):
+ def process_all(self):
for y in range(self._height):
for x in range(self._width):
if not self._processed[y][x]:
@@ -48,12 +51,16 @@ class Figure:
for r in rects:
r.extract_text(self)
self._elements += rects
+ # If not a rectangle, it must be a line joint
else:
- new_element = Joint((y, x))
+ new_lines = self.polyline(y, x, "FIND")
+ self._elements += new_lines
if symbol == '-':
- new_element = Line((y, x))
+ new_lines = self.polyline(y, x, "RIGHT")
+ self._elements += new_lines
if symbol == '|':
- new_element = Line((y, x), vertical=True)
+ new_lines = self.polyline(y, x, "DOWN")
+ self._elements += new_lines
#new_element.process()
self._processed[y][x] = True
@@ -66,6 +73,100 @@ class Figure:
figure_string += '\n'
return figure_string
+ def __has_char(self, y, x, char):
+ if y < 0 or y >= self._height:
+ return False
+ if x < 0 or x >= self._width:
+ return False
+ # Processed characters should not be considered
+ if self._processed[y][x]:
+ return False
+ if self._figarray[y][x] == char:
+ return True
+ return False
+
+ def __line_end_in(self, y, x):
+ if self.__has_char(y, x, '+'):
+ return True
+ if self.__has_char(y, x, '<'):
+ return True
+ if self.__has_char(y, x, '>'):
+ return True
+ if self.__has_char(y, x, '^'):
+ return True
+ if self.__has_char(y, x, 'v'):
+ return True
+ return False
+
+ """
+ Finds all lines in a polyline recursively
+ MAYBE: The best option is to just use SVG 'Line'. Polylines do not handle
+ crossing lines well, I think. (So TODO : refactor name)
+ """
+ def polyline(self, y, x, direction):
+ # Find lines
+ line_list = []
+ if direction == "FIND":
+ if self.__has_char(y+1, x, '|'):
+ line_list += self.polyline(y+1, x, "DOWN")
+ if self.__has_char(y-1, x, '|'):
+ line_list += self.polyline(y+1, x, "UP")
+ if self.__has_char(y, x-1, '-'):
+ line_list += self.polyline(y, x-1, "LEFT")
+ if self.__has_char(y, x+1, '-'):
+ line_list += self.polyline(y, x+1, "RIGHT")
+ return line_list
+
+ elif direction == "LEFT":
+ x_test = x
+ while self.__has_char(y, x_test, '-'):
+ self._processed[y][x_test] = True
+ x_test -= 1
+ if self.__line_end_in(y, x_test):
+ line_list.append(Line((y, x_test), (y, x)))
+ else:
+ line_list.append(Line((y, x_test+1), (y, x)))
+ x = x_test
+ elif direction == "RIGHT":
+ x_test = x
+ while self.__has_char(y, x_test, '-'):
+ self._processed[y][x_test] = True
+ x_test += 1
+ if self.__line_end_in(y, x_test):
+ line_list.append(Line((y, x), (y, x_test)))
+ else:
+ line_list.append(Line((y, x), (y, x_test + 1)))
+ x = x_test
+ elif direction == "UP":
+ y_test = y
+ while self.__has_char(y_test, x, '|'):
+ self._processed[y_test][x] = True
+ y_test -= 1
+ if self.__line_end_in(y_test, x):
+ line_list.append(Line((y_test, x), (y, x)))
+ else:
+ line_list.append(Line((y_test+1, x), (y, x)))
+ y = y_test
+ elif direction == "DOWN":
+ y_test = y
+ while self.__has_char(y_test, x, '|'):
+ self._processed[y_test][x] = True
+ y_test += 1
+ if self.__line_end_in(y_test, x):
+ line_list.append(Line((y, x), (y_test, x)))
+ else:
+ line_list.append(Line((y, x), (y_test-1, x)))
+ y = y_test
+ else:
+ pass
+
+ # If the line we're testing has a '+' char, find new lines recursively
+ if self.__has_char(y, x, '+'): # This should deffo be moved to the bottom
+ line_list += self.polyline(y, x, "FIND")
+
+ return line_list
+
+
"""
Checks if a joint belongs to a rectangle (and if there are subrectangles)
@@ -148,7 +249,9 @@ class Figure:
print("{} ".format('p' if cell else ' '), end="")
print()
- rect_list = [Rectangle((x_start, y_start), (x_stop, y_stop))]
+ new_rect = Rectangle((x_start, y_start), (x_stop, y_stop))
+ new_rect.extract_text(self)
+ rect_list = [new_rect]
# Check if we're dealing with a rectangle chain
sub_rects = self.rectangle(y_stop, x_start)
if sub_rects:
@@ -160,9 +263,8 @@ class Figure:
return rect_list
-
"""Return SVG text of the entire figure"""
- def draw_svg(self):
+ def get_svg(self):
svg_text = ""
for el in self._elements:
svg_text += el.draw() + "\n"
@@ -194,7 +296,6 @@ class Rectangle:
return return_string
def draw(self):
- font_size = 12
svg_text = "\t<rect x=\"{}\" y=\"{}\" ".format(
self._x_start * font_size,
self._y_start * font_size)
@@ -244,16 +345,30 @@ class Joint:
# The best alternative here is to use a *polyline*
# https://www.w3schools.com/graphics/svg_polyline.asp
class Line:
- def __init__(self, start_pos, vertical=False):
- self._start = start_pos
- self._end = None#end_pos
- pass
+ def __init__(self, pos_start, pos_stop):
+ (self._y_start, self._x_start) = pos_start
+ (self._y_stop, self._x_stop) = pos_stop
- def process():
+ def process(self):
pass
- def draw():
- pass
+ def draw(self):
+ svg_text = "\t<line x1=\"{}\" y1=\"{}\" x2=\"{}\" y2=\"{}\" ".format(
+ self._x_start * font_size,
+ self._y_start * font_size,
+ self._x_stop * font_size,
+ self._y_stop * font_size)
+ svg_text += "style=\"stroke:rgb(0,0,0);stroke-width:1\" />"
+ return svg_text
+
+ def __str__(self):
+ text = "Line, ({}, {}) to ({}, {})\n".format(
+ self._y_start,
+ self._x_start,
+ self._y_stop,
+ self._x_stop
+ )
+ return text
class Arrow():
pass
@@ -265,16 +380,14 @@ with open("ascii.txt") as f:
drawing = Figure(ascii_text)
print(drawing)
-drawing.process()
+drawing.process_all()
for el in drawing.get_elements():
- el.extract_text(drawing)
print(el)
svg_text = "<svg xmlns=\"http://www.w3.org/2000/svg\">\n"
-svg_text += drawing.draw_svg()
+svg_text += drawing.get_svg()
svg_text += "</svg>"
-#file:///home/vh/nextcloud/git/general/snippets/test.svg
with open("test.svg", "w+") as f:
f.write(svg_text)
f.close()
diff --git a/ascii.txt b/ascii.txt
@@ -8,29 +8,29 @@
|
|
+-----------+---------+
- +----->| unexpected |
- | +---------------------+
- |
+ +----->| unexpected |<-+
+ | +---------------------+ |
+ | v
+-------+--------+ +----------------------+
| Block 1 | | Additional block |
+-------+--------+ +----------+-----------+
| v
| +----------------------+
+--------->| Second block |
- +----------------------+
- | |
- | - List of stuff here |
- | - Good stuff too, |
- | I'd say |
- | |
- | |
- | |
- | |
- | |
- +----------------------+
-
-
-
+ | +----------------------+
+ | | |
+ | | - List of stuff here |
+ | | - Good stuff too, |
+ | | I'd say |
+ | | |
+ | | |
+ | | |
+ | | |
+ | | |
+ | +----------------------+
+ |
+ |
+ v
+-----------------------+
| SEC 1 |
+-----------------------+
@@ -38,3 +38,6 @@
+-----------------------+
| SEC 3 |
+-----------------------+
+
+
+