From bf365bc725a63b6b6b81ff6bbbfb091a3e300387 Mon Sep 17 00:00:00 2001 From: Ian Jauslin Date: Wed, 24 Nov 2021 20:30:51 -0500 Subject: [PATCH] Fixes to motion of squares --- painter.py | 7 ++++-- polyomino.py | 61 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/painter.py b/painter.py index 484cf62..9974cf9 100644 --- a/painter.py +++ b/painter.py @@ -4,6 +4,7 @@ from kivy.core.window import Window from point import Point from polyomino import Square +from polyomino import Square_element # painter class class Painter(Widget): @@ -128,6 +129,7 @@ class Painter(Widget): if touch.button=="left" and self.modifiers==[] and self.undermouse!=None: # change in position delta=self.check_move(Point(touch.x/Square_element.size,touch.y/Square_element.size)-(self.offset+self.undermouse.squares[0].pos),self.undermouse) + self.undermouse.move(delta) # multiple particles # TODO: group moves #else: @@ -173,7 +175,8 @@ class Painter(Widget): # check whether a position intersects with any of the particles def check_interaction_any(self,candidate,offset): for particle in self.particles: - if particle.check_interaction(candidate,offset): + # do not check interaction if candidate=particle + if candidate!=particle and particle.check_interaction(candidate,offset): return True return False @@ -193,7 +196,7 @@ class Painter(Widget): # TODO: this assumes other is a square newdelta=other.squares[0].move_along(delta,particle.squares[0].pos) else: - newdelta=other.move_on_line_to_stick(particle.squares[0].pos,delta) + newdelta=other.squares[0].move_on_line_to_stick(particle.squares[0].pos,delta) if not self.check_interaction_any(particle,newdelta): return newdelta if accept_newpos: diff --git a/polyomino.py b/polyomino.py index 25af5a3..d401759 100644 --- a/polyomino.py +++ b/polyomino.py @@ -39,9 +39,15 @@ class Polyomino(): *((square.pos.x-0.5)*square.size,(square.pos.y-0.5)*square.size), *((square.pos.x-0.5)*square.size,(square.pos.y+0.5)*square.size), *((square.pos.x+0.5)*square.size,(square.pos.y+0.5)*square.size), - *((square.pos.x+0.5)*square.size,(square.pos.y-0.5)*square.size) + *((square.pos.x+0.5)*square.size,(square.pos.y-0.5)*square.size), + *((square.pos.x-0.5)*square.size,(square.pos.y-0.5)*square.size) )) + # move by delta + def move(self,delta): + for square in self.squares: + square.pos+=delta + # whether x is in the support of the polyomino def in_support(self,x): for square in self.squares: @@ -69,7 +75,7 @@ class Polyomino(): # square class Square(Polyomino): def __init__(self,x,y,**kwargs): - super(Square,self).__init__(kwargs,squares=[Square_element(x,y)]) + super(Square,self).__init__(**kwargs,squares=[Square_element(x,y)]) @@ -94,35 +100,52 @@ class Square_element(): # check whether a square at position pos is touching self def check_touch(self,pos): # allow for error - if in_interval(l_infinity(pos-solf.pos),1-1e-11,1+1e-11): + if in_interval(l_infinity(pos-self.pos),1-1e-11,1+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): # compute intersections with four lines making up square - intersections=[\ - Point(self.pos.x+1/2,pos.y+v.y/v.x*(self.pos.x+1/2-pos.x)),\ - Point(self.pos.x-1/2,pos.y+v.y/v.x*(self.pos.x-1/2-pos.x)),\ - Point(pos.x+v.x/v.y*(self.pos.y+1/2-pos.y),self.pos.y+1/2),\ - Point(pos.x+v.x/v.y*(self.pos.y-1/2-pos.y),self.pos.y-1/2)\ - ] + if v.x!=0: + if v.y!=0: + intersections=[\ + Point(self.pos.x+1,pos.y+v.y/v.x*(self.pos.x+1-pos.x)),\ + Point(self.pos.x-1,pos.y+v.y/v.x*(self.pos.x-1-pos.x)),\ + Point(pos.x+v.x/v.y*(self.pos.y+1-pos.y),self.pos.y+1),\ + Point(pos.x+v.x/v.y*(self.pos.y-1-pos.y),self.pos.y-1)\ + ] + else: + intersections=[\ + Point(self.pos.x+1,pos.y+v.y/v.x*(self.pos.x+1-pos.x)),\ + Point(self.pos.x-1,pos.y+v.y/v.x*(self.pos.x-1-pos.x)) + ] + else: + if v.y!=0: + intersections=[\ + Point(pos.x+v.x/v.y*(self.pos.y+1-pos.y),self.pos.y+1),\ + Point(pos.x+v.x/v.y*(self.pos.y-1-pos.y),self.pos.y-1)\ + ] + else: + print("error: move_on_line_to_stick called with v=0, please file a bug report with the developer",file=sys.stderr) + exit(-1) # compute closest one, on square closest=None dist=math.inf - for i in range(0,4): + for i in range(0,len(intersections)): # check that it is on square - if abs(intersections[i].x-self.pos.x)<=1/2+1e-11 and abs(intersections[i].y-self.pos.y)<=1/2+1e-11: + if abs(intersections[i].x-self.pos.x)<=1+1e-11 and abs(intersections[i].y-self.pos.y)<=1+1e-11: if (intersections[i]-pos)**20: if relmath.ceil(rel)+1e-11 and math.ceil(rel)!=0: # stick to corner - candidate.y=math.ceil(rel)+self.pos.y + candidate.y=math.ceil(rel)+self.pos.y-pos.y else: if rel>math.floor(rel)+1e-11 and delta.y+rel0: if relmath.ceil(rel)+1e-11 and math.ceil(rel)!=0: # stick to corner - candidate.x=math.ceil(rel)+self.pos.x + candidate.x=math.ceil(rel)+self.pos.x-pos.x else: if rel>math.floor(rel)+1e-11 and delta.x+rel