check move
This commit is contained in:
parent
a5caeec29a
commit
159ac83e86
56
cross.py
56
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
|
||||
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
|
||||
|
||||
# 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
|
||||
else:
|
||||
# cannot move cross at all, try again
|
||||
return self.check_move(candidate,cross)
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user