I'm trying to implement LOGO with a physical turtle. I got all the basics done, but I got completely sunk when implementing the "Window" mode.
Original LOGO had 3 modes: "Border" - the turtle bumps into border of the screen and stops there, "Wrap" - the screen is a torus, turtle rides out the left side of the screen, reappears directly right from the exit point, and "Window" - the turtle can travel over enormous playfield stretching far outside the borders of the screen, and whatever happens off-screen is simply never drawn. It was the favored mode as it wouldn't spoil the drawn part if the picture exceeded past the screen borders.
Now, I got to the point where the 'forward' command can generate carthesian start and end coordinates of any move. In 'Window' mode they may happen anywhere, on screen or off screen. If they happen on screen, the turtle normally moves along the line from start to end. If they exit, the turtle drives up to the border, while virtual 'cursor' continues to the end coord. If they both occur off-screen nothing happens physically, just the 'cursor' is moved in memory. If they re-enter the screen, the turtle is moved from wherever it was to the entry point without drawing, then proceeds to the end point, drawing or not depending on pen settings.
This all happens with floating point maths, so numbers are never exact - I've set an 'epsilon' of 0.0001mm of tolerance, anything closer should be considered a match.
I have methods for:
- is_outside_eps(point) # more than epsilon from border - is_outside(point) # just floating point comparison, no epsilon tolerance - is_at_border(point) # within epsilon from border - go(startpoint,endpoint) # perform normal turtle movement, using pen settings - nodraw(startpoint,endpoint) # move the turtle from startpoint to endpoint, no drawing - dummymove(startpoint,endpoint) #move the cursor from startpoint to endpoint, no physical results - find_intersects(startpoint,endpoint) ...and a number of derived helpers. If more is needed, more will be written.
find_intersects returns a list of coords where the vector start->end crosses any borders, alongside with direction (1 = into, -1 = out of). It can return two entry points or two exits if the vector passes through a corner, though this isn't a problem - they are in the same spot, so one can be ignored safely.
Where I got stumped is all the edge conditions. I found 16 so far, and I really, really hope this can be simplified, and I don't have to cover all the combinations:
For example, a turtle at the border, when told to move directly outside, should stay put, only the virtual cursor moved. But the same turtle told to turn towards center of the drawing area and move 1000 units forward (way outside the drawing area on the opposite side) should cross over to the opposite border and stop there while the cursor continues.
Is there some smart way to handle that, or am I sentenced to writing at least 16 different cases for handling all the possible situations?
