From e68c671fc502e1d8251ce02638e93c4978719a2f Mon Sep 17 00:00:00 2001 From: Ian Jauslin Date: Wed, 24 Nov 2021 22:49:42 -0500 Subject: [PATCH] Enforce recurrence depth, with error message --- painter.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/painter.py b/painter.py index 4950aab..a532b73 100644 --- a/painter.py +++ b/painter.py @@ -146,7 +146,7 @@ class Painter(Widget): # only move on left click if touch.button=="left" and self.modifiers==[] and self.undermouse!=None: # attempted move determined by the relative position to the relative position of click within self.undermouse - delta=self.adjust_move(Point(touch.x/Square_element.size,touch.y/Square_element.size)-(self.offset+self.undermouse.squares[0].pos)) + delta=self.adjust_move(Point(touch.x/Square_element.size,touch.y/Square_element.size)-(self.offset+self.undermouse.squares[0].pos),0) for particle in self.selected: particle.move(delta) @@ -196,13 +196,13 @@ class Painter(Widget): # try to move all selected particles by delta, adjust if needed to avoid overlap with unselected particles # we only track whether these elements collide with unselected particles, not with each other - def adjust_move(self,delta): + def adjust_move(self,delta,recursion_depth): # actual_delta is the smallest (componentwise) of all the computed delta's actual_delta=Point(math.inf,math.inf) for particle in self.selected: for element in particle.squares: # compute adjustment move due to unselected obstacles - adjusted_delta=self.adjust_move_element(delta,element) + adjusted_delta=self.adjust_move_element(delta,element,0) # only keep the smallest delta's (in absolute value) if abs(adjusted_delta.x)100: + print("warning: recursion depth exceeded when adjusting move by delta=(",delta.x,",",delta.y,")",file=sys.stderr) + return Point(0,0) + else: + return self.adjust_move(actual_delta,recursion_depth+1) # trying to move a single element by delta, adjust if needed to avoid overlap with unselected particles - def adjust_move_element(self,delta,element): + def adjust_move_element(self,delta,element,recursion_depth): # whether newpos is acceptable accept_newpos=True for other in self.unselected: @@ -237,7 +242,12 @@ class Painter(Widget): return delta else: # cannot move particle at all, try again - return self.adjust_move_element(newdelta,element) + # give up if tried too many times + if recursion_depth>100: + print("warning: recursion depth exceeded when adjusting move of element at (",element.pos.x,",",element.pos.y,") by delta=(",delta.x,",",delta.y,")",file=sys.stderr) + return Point(0,0) + else: + return self.adjust_move_element(newdelta,element,recursion_depth+1) # TODO adapt