Permalink
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...
1 parent c287055 commit cbde034ec207b4aa4ac70e3e976ccb9cdefd44aa @scolobb committed Jun 22, 2012
Showing with 96 additions and 0 deletions.
  1. +96 −0 sympy/categories/diagram_drawing.py
@@ -324,6 +324,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):
"""
@@ -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)

0 comments on commit cbde034

Please sign in to comment.