Defining "zones" for random movement of two servos

I've looked online for instructions for this but am not sure of the proper way to word what I'm looking for because the hits I'm getting aren't exactly what I'm looking for.

I am attempting to make a cat toy laser to mount to my wall. I am using this as the basis for my design. However, I would like to limit the movement of the servos to only the zones as defined here (top view of living room) in order to avoid the laser going on/behind furniture. I understand how to define the ranges independently, but I'm not sure how to limit the horizontal value based on the vertical value. Originally I was thinking to simply do that, but then realized this would still allow the servos to select positions that would take the path of the laser over furniture. Instead, I need to define "zones" of available positions that are selected prior to the specific positions being genreated. Additionally, before moving between Zones 1, 3 and 4 in the picture, it needs to return to zone 2 so that the laser doesn't move over furniture and out of the cat's vision.

So the steps would be: 1- Randomly select any zone if in zone 2 OR randomly select current zone or zone 2 if in zones 1,3 or 4 2- Randomly select horizontal/vertical position within selected zone

Anyone have any suggestions on how to do this? I have little experience doing anything like this and am not sure what to search for to get me in the right direction.

Direct link to .ino being used as a basis


just use constrain() to limit the movement to the zones you want.

Well, if you are moving the laser then you have the additional problem of not being able to move from zone1 to zone 4.

So. Each zone is a rectangle. Each zone has a list of neighbouring zones.

At any time (i.e.: at each execution of loop), the laser is moving from zone(A,x,y) to zone(B, x y). So you use a parametrization - a (say) floating point value named 'p' that varies between 0 and 1. Each cycle through the loop, you increment p and take a weighted average of the two points (weighted by 1-p vs p) to work out where the laser should be.

When you finally get p >=1, then move the destination point to be the new source point, and decide on a new destination point. Stay in the same zone, or pick a neighbouring zone, and then pick a point within the zone you have picked. Set p back to zero, and let the next increment of loop() resume moving the later.

Oh - you may want to add a bit of a delay before you resume moving. You may also want to add accelleration/decelleration to your movement, and you might even want to correct for geometry (convert x/y to azimuth/elevation of your laser)

Oh, and rather than simply calculating p, you might want to base it on millis() so as to be able to define the speed of your laser in terms of real time.

With respect to data structure, you would be looking at something like

const int ZONES = 4;
struct zone {
  int x,y,width,height;
  int neighboursCount;
  int neighbours[ZONES-1]; // a zone has a maximum of 
} zone[ZONES] = {
    123,456,789,123, // x, y , witdh height
    1, // zone 0 has one neighbour
  // etc