Python - coordinates to rotate/move instructions

3.7k views Asked by At
coordinates = [(0, 2), (0, 1), (1, 2), (1, 1), (0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]

I have created a Python array stated above. It contains tuples of points (x,y). I will assume I start at the first point (not the orgin). I want to move to the points in the order given. The only movement functions I have are rotate90Degrees(direction) where direction is 1 or -1 for left and right, respectively. And forward(time) where time is how long to move. I will assume time = 1 is equivalent to one unit in the coordinate system. Is there a clever way to easily change the this into movement instructions without a huge if/else if/else? What I have so far:

start = coordinates[0]
for x in range(1,len(coordinates)):
    finish = coordinates[x]
    change.append((finish[0] - start[0],finish[1] - start[1]))
    start = coordinates[x]
2

There are 2 answers

0
Tom Zych On

Okay, so your robot is facing in some known cardinal direction and is at some known location, and you want it to move to another location.

First you need a list of tuples that map directions to displacements. I’ll use the standard unit circle, with angles as multiples of 90 degrees:

atod = [(1, 0), (0, 1), (-1, 0), (0, -1)]

So moving when facing in direction 0 means your x-coordinate increases by 1 per unit time and your y-coordinate is unchanged, and so forth. The directions are integers from 0 to 3 inclusive.

Now the code needs to figure out how to proceed. I’d start with whatever direction the robot’s currently facing. Say the desired displacement is (-2, 1) and dir is 0. atod[dir] is (1, 0). Ignore the one that’s zero; divide -2 by 1 and you get -2, so this direction is no good, we have to rotate. Which way? Check each one, see which way helps. If neither way helps, you need to do a 180, do it in whichever direction you like.

So we did our rotation and now we’re in direction 1 and atod[dir] is (0, 1). So we want to move forward by 1. Do so. Now you have to rotate again, move again, and you’re done.

0
aghast On

You can move along either north/south or east/west axis, since your rotations are limited to 90 degrees.

You can observe that any movement will have a north/south component, and an east/west component.

If you are consistent in your movements, then you are only one 90 degree turn away from your next step:

1. turn east or west
2. move east or west
3. turn north or south
4. move north or south
5. You should be at your target
6. turn east or west
7. move east or west
8. turn north or south
9. move north or south
10. you should be at your (next) target

... etc.

If we assume that your robot starts out facing north, then your loop should turn to the east/west first, then move, then turn north/south.

Here's a start. This could be your global data and main code.

Robot_pos = coordinates[0]
Robot_facing = NORTH

for next_pos in coordinates[1:]:
    move_robot(next_pos)

If we assume that x is east/west, and y is north/south, then you have something like this for move_robot:

def move_robot(new_pos):
    """
    Move robot from ``Robot_pos`` to ``new_pos`` given. The robot
    is assumed to be facing either north or south upon entry, so
    east/west movement is done first.
    """

    delta_x = ...
    turn_robot(EAST or WEST)
    forward( some amount )

    # similarly for Y

You'll have to be a little clever in your turn_robot() code to optimize turns for whether you start out facing in a positive or negative direction. It should always be a single 90 degree rotation, though.