Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

DiagramGrid: Decide how to place the outstanding vertex of the welded…

… triangle.

While _find_triangle_welding shows how to place one edge of the
triangle, it is important and nontrivial to decide where to place the
third vertex.  DiagramGrid is now capable to make this decision, while
also fixing some possible degenerate situations in the fringe.
  • Loading branch information...
commit cbde034ec207b4aa4ac70e3e976ccb9cdefd44aa 1 parent c287055
@scolobb authored
Showing with 96 additions and 0 deletions.
  1. +96 −0 sympy/categories/diagram_drawing.py
View
96 sympy/categories/diagram_drawing.py
@@ -325,6 +325,17 @@ def _fix_degerate(edge, pt1, pt2, fringe, grid):
return False
@staticmethod
+ def _empty_point(pt, grid):
+ """
+ Checks if the cell at coordinates ``pt`` is either empty or
+ out of the bounds of the grid.
+ """
+ if (pt[0] < 0) or (pt[1] < 0) or \
+ (pt[0] >= grid.height) or (pt[1] >= grid.width):
+ return True
+ return grid[pt] is None
+
+ @staticmethod
def _weld_triangle(triangles, fringe, grid, skeleton):
"""
Welds a triangle to the fringe and returns ``True``, if
@@ -346,6 +357,91 @@ def _weld_triangle(triangles, fringe, grid, skeleton):
# other vertex of the triangle and check for
# degenerate situations en route.
+ if (abs(a[0] - b[0]) == 1) and (abs(a[1] - b[1]) == 1):
+ # A diagonal edge.
+ target_cell = (a[0], b[1])
+ if grid[target_cell]:
+ # That cell is already occupied.
+ target_cell = (b[0], a[1])
+
+ if grid[target_cell]:
+ # Degenerate situation, this edge is not
+ # on the actual fringe. Correct the
+ # fringe and go on.
+ fringe.remove((a, b))
+ break
+ elif a[0] == b[0]:
+ # A horizontal edge. Suppose a triangle can be
+ # built in the upward direction.
+
+ up_left = a[0] - 1, a[1]
+ up_right = a[0] - 1, b[1]
+
+ if DiagramGrid._fix_degerate(
+ (a, b), up_left, up_right, fringe, grid):
+ # The fringe has just been corrected. Restart.
+ break
+
+ if DiagramGrid._empty_point(up_left, grid):
+ target_cell = up_left
+ elif DiagramGrid._empty_point(up_right, grid):
+ target_cell = up_right
+ else:
+ # No room above this edge. Check below.
+ down_left = a[0] + 1, a[1]
+ down_right = a[0] + 1, b[1]
+
+ if DiagramGrid._fix_degerate(
+ (a, b), up_left, up_right, fringe, grid):
+ # The fringe has just been corrected.
+ # Restart.
+ break
+
+ if DiagramGrid._empty_point(up_left, grid):
+ target_cell = down_left
+ elif DiagramGrid._empty_point(up_right, grid):
+ target_cell = down_right
+ else:
+ # This edge is not in the fringe, remove it
+ # and restart.
+ fringe.remove((a, b))
+ break
+
+ elif a[1] == b[1]:
+ # A vertical edge. Suppose a triangle can be built to
+ # the left.
+ left_up = a[0], a[1] - 1
+ left_down = b[0], a[1] - 1
+
+ if DiagramGrid._fix_degerate(
+ (a, b), left_up, left_down, fringe, grid):
+ # The fringe has just been corrected. Restart.
+ break
+
+ if DiagramGrid._empty_point(left_up, grid):
+ target_cell = left_up
+ elif DiagramGrid._empty_point(left_down, grid):
+ target_cell = left_down
+ else:
+ # No room to the left. See what's to the right.
+ right_up = a[0], a[1] + 1
+ right_down = b[0], a[1] + 1
+
+ if DiagramGrid._fix_degerate(
+ (a, b), right_up, right_down, fringe, grid):
+ # The fringe has just been corrected. Restart.
+ break
+
+ if DiagramGrid._empty_point(right_up, grid):
+ target_cell = right_up
+ elif DiagramGrid._empty_point(right_down, grid):
+ target_cell = right_down
+ else:
+ # This edge is not in the fringe, remove it
+ # and restart.
+ fringe.remove((a, b))
+ break
+
def __new__(cls, diagram):
premises = DiagramGrid._simplify_morphisms(diagram.premises)
conclusions = DiagramGrid._simplify_morphisms(diagram.conclusions)
Please sign in to comment.
Something went wrong with that request. Please try again.