From 159ac83e8625646b594e0d155df0bb9cdcce281a Mon Sep 17 00:00:00 2001 From: Ian Jauslin Date: Wed, 29 Sep 2021 03:24:23 -0400 Subject: [PATCH] check move --- cross.py | 58 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/cross.py b/cross.py index 2d7e397..2b158cf 100644 --- a/cross.py +++ b/cross.py @@ -14,7 +14,6 @@ class Cross(): self.pos=Point(x,y) self.color=kwargs.get("color",(0,0,1)) self.selected=False - self.stuckto=None # set position def setpos(self,x,y): @@ -46,7 +45,19 @@ class Cross(): # check whether a cross at pos interacts with cross def check_interaction(self,pos): - return (pos-self.pos).int()**2>=5 + # allow for error + return int(pos.x-self.pos.x+sgn(pos.x-self.pos.x)*1e-11)**2+int(pos.y-self.pos.y+sgn(pos.y-self.pos.y)*1e-11)**2>=5 + + # check whether a cross at position pos is touching self + def check_touch(self,pos): + rel=pos-self.pos + for i in [-3,-2,-1,1,2,3]: + # allow for error + if abs(rel.x-i)<1e-11 and abs(rel.y)<=4-abs(i)+1e-11 and abs(rel.y)>=3-abs(i)-1e-11: + return True + if abs(rel.y-i)<1e-11 and abs(rel.x)<=4-abs(i)+1e-11 and abs(rel.x)>=3-abs(i)-1e-11: + return True + return False # find position along a line that comes in contact with the line going through pos in direction v def move_on_line_to_stick(self,pos,v): @@ -92,7 +103,7 @@ class Cross(): closest=self.move_on_line_to_stick_relative(Point(-x.x,x.y),Point(-v.x,v.y)) return Point(-closest.x,closest.y) - # move along edge of cross while remaining stuck + # move along edge of cross def move_along(self,newpos,pos): rel=pos-self.pos # check if the particle is stuck in the x direction @@ -220,7 +231,7 @@ class Cross_painter(Widget): def on_touch_down(self,touch): # create new cross if touch.button=="right": - if self.check_add(Point(touch.x/Cross.size,touch.y/Cross.size)): + if self.check_interaction_any(Point(touch.x/Cross.size,touch.y/Cross.size),None): new=Cross(touch.x/Cross.size,touch.y/Cross.size) with self.canvas: new.draw() @@ -258,30 +269,37 @@ class Cross_painter(Widget): # none found return None + # check whether a position intersects with any of the crosses + def check_interaction_any(self,pos,exception): + for other in self.crosses: + if other!=exception: + if other.check_interaction(pos)==False: + return False + return True + # check that a cross can move to new position def check_move(self,newpos,cross): + # whether newpos is acceptable + accept_newpos=True for other in self.crosses: # do not compare a cross to itself if other!=cross: # move would make cross overlap with other if other.check_interaction(newpos)==False: - # check if cross is stuck to other - if cross.stuckto==other: + accept_newpos=False + # check if cross touches other + if other.check_touch(cross.pos): # move along other while remaining stuck - return other.move_along(newpos,cross.pos) + candidate=other.move_along(newpos,cross.pos) else: - # stick to the cross - cross.stuckto=other - return other.move_on_line_to_stick(cross.pos,newpos-cross.pos) - # reset stuckto if move is allowed - cross.stuckto=None - return newpos - - # check that a cross can be added at position - def check_add(self,pos): - for cross in self.crosses: - if cross.check_interaction(pos)==False: - return False - return True + candidate=other.move_on_line_to_stick(cross.pos,newpos-cross.pos) + if self.check_interaction_any(candidate,cross): + return candidate + if accept_newpos: + return newpos + else: + # cannot move cross at all, try again + return self.check_move(candidate,cross) +