diff --git a/src/corners.py b/src/corners.py --- a/src/corners.py +++ b/src/corners.py @@ -2,92 +2,92 @@ class Corners: - def __init__(self): - self.corners=[] - - ## Adds a new corner if there are less than four, replaces the closest otherwise. - def add(self,x,y): - a=EPoint(x,y) - # for i,c in enumerate(self.corners): # move an improperly placed point - # if a.dist(c)<20: - # self.corners[i]=a - # return - - if len(self.corners)<4: # add a new corner - self.corners.append(a) - - if len(self.corners)<4: - return - - index,minDist=0,float('inf') # replace the corner closest to the clicked point - for i,c in enumerate(self.corners): - if a.dist(c) KLMN | ABC | ABD | ACD | BCD | index | swap - # ------------ | :-: | :-: | :-: | :-: | ----: | ---- - # A BCD | + | + | + | + | 15 | 0 - # A BDC | + | + | - | - | 12 | CD - # A CBD | - | + | + | - | 6 | BC - # A CDB | - | - | + | + | 3 | AB - # A DBC | + | - | - | + | 9 | AD - # A DCB | - | - | - | - | 0 | BD - # - # For every non-degenerate quadrangle, there must be 1-3 edges going right-left (from a higher to a lower x coordinate). - # From these pick the one with the lowest slope (dy/dx) and declare its ending point the upper left corner. For the same slope pick the one further left. - # - # @return True for a convex quadrangle, False for concave and degenerate cases. - def canonizeOrder(self): - if len(self.corners)!=4: return False # erroneus call - - a,b,c,d=self.corners - abc=Corners._doubleTriangleArea(a,b,c) - abd=Corners._doubleTriangleArea(a,b,d) - acd=Corners._doubleTriangleArea(a,c,d) - bcd=Corners._doubleTriangleArea(b,c,d) - - if any(x==0 for x in (abc,abd,acd,bcd)): return False # collinear degenerate - - swaps=[(1,3),(0,1),(1,2),(0,3),(2,3),(0,0)] - index=(8 if abc>0 else 0)|(4 if abd>0 else 0)|(2 if acd>0 else 0)|(1 if bcd>0 else 0) - if index%3!=0: return False # concave degenerate - swap=swaps[index//3] - - self.corners[swap[0]], self.corners[swap[1]] = self.corners[swap[1]], self.corners[swap[0]] # counter-clockwise order - - kIndex=None - lowestSlope=float("inf") - - for i,corner in enumerate(self.corners): # find the NK edge: going right-left with the lowest slope, secondarily the one going down - ii=(i+1)%4 - slope=abs(Corners._slope(corner,self.corners[ii])) - if corner.x>self.corners[ii].x and (slope KLMN | ABC | ABD | ACD | BCD | index | swap + # ------------ | :-: | :-: | :-: | :-: | ----: | ---- + # A BCD | + | + | + | + | 15 | 0 + # A BDC | + | + | - | - | 12 | CD + # A CBD | - | + | + | - | 6 | BC + # A CDB | - | - | + | + | 3 | AB + # A DBC | + | - | - | + | 9 | AD + # A DCB | - | - | - | - | 0 | BD + # + # For every non-degenerate quadrangle, there must be 1-3 edges going right-left (from a higher to a lower x coordinate). + # From these pick the one with the lowest slope (dy/dx) and declare its ending point the upper left corner. For the same slope pick the one further left. + # + # @return True for a convex quadrangle, False for concave and degenerate cases. + def canonizeOrder(self): + if len(self.corners)!=4: return False # erroneus call + + a,b,c,d=self.corners + abc=Corners._doubleTriangleArea(a,b,c) + abd=Corners._doubleTriangleArea(a,b,d) + acd=Corners._doubleTriangleArea(a,c,d) + bcd=Corners._doubleTriangleArea(b,c,d) + + if any(x==0 for x in (abc,abd,acd,bcd)): return False # collinear degenerate + + swaps=[(1,3),(0,1),(1,2),(0,3),(2,3),(0,0)] + index=(8 if abc>0 else 0)|(4 if abd>0 else 0)|(2 if acd>0 else 0)|(1 if bcd>0 else 0) + if index%3!=0: return False # concave degenerate + swap=swaps[index//3] + + self.corners[swap[0]], self.corners[swap[1]] = self.corners[swap[1]], self.corners[swap[0]] # counter-clockwise order + + kIndex=None + lowestSlope=float("inf") + + for i,corner in enumerate(self.corners): # find the NK edge: going right-left with the lowest slope, secondarily the one going down + ii=(i+1)%4 + slope=abs(Corners._slope(corner,self.corners[ii])) + if corner.x>self.corners[ii].x and (slope