patterned
patterned

Reputation: 444

Can someone explain why this coordinate math works?

Visual a canvas with square spaces that an object can move along in the x and y directions, but not diagonal. Movement is based on mouse coordinates captured from a mouse click (mouseX, mouseY). Assume obj.move() moves from its relative location to the provided (x,y) location.

if (Math.abs(mouseX-objX) > Math.abs(mouseY-objY)){
    if(mouseX > objX){
        obj.move(SQUARE_SIZE, 0);
    }else{
        obj.move(-SQUARE_SIZE, 0);
    }
}else{
    if(mouseY > objY){
        obj.move(0, SQUARE_SIZE);
    }else{
        obj.move(0, -SQUARE_SIZE);
    }
}

I understand all the code, but I cannot grasp the mathematical concept. Can someone explain this graphically or point me somewhere on the right path?

Not important right now (until I understand this math), but if I wanted to include diagonal movement into this, how would I go about it?

Upvotes: 1

Views: 140

Answers (2)

bcorso
bcorso

Reputation: 47166

When dealing with directions you need both a distance and a direction. For example if dX = -2, the distance is |dX| = 2 and the direction is sign(dX) = -1. You can simplify your code by using these terms.

int dx = mouseX - objX, distX = Math.abs(dX), dirX = Math.signum(dX);
int dy = mouseY - objY, distY = Math.abs(dY), dirY = Math.signum(dY);

// Move diagonal
if(distX == distY))
    obj.move(dirX * SQUARE_SIZE, dirY * SQUARE_SIZE);

// Move horizontal
else if(distX > distY)
    obj.move(dirX * SQUARE_SIZE, 0);

// Move vertical
else
    obj.move(0, dirY * SQUARE_SIZE);

Examples:

Lets say you start at position 0 (green) and the mouse is clicked at position 3 (red):

Example 1 (no diagonal):

enter image description here

  1. (from pos:0) dX = 2, dy = -1, so |dX| > |dy|, and dirX > 0, move right (SQUARE_SIZE)
  2. (from pos:1) dX = 1, dy = -1, so |dX|<= |dy|, and dirY < 0, move down (-SQUARE_SIZE)
  3. (from pos:2) dX = 1, dy = 0, so |dX| > |dy|, and dirX > 0, move right (SQUARE_SIZE)
  4. (from pos:3) Done

Example 2 (with diagonal):

enter image description here

  1. (from pos:0) dX = 2, dy = -1, so |dX| > |dy|, and dirX > 0, move right (SQUARE_SIZE)
  2. (from pos:1) dX = 1, dy = -1, so |dX| = |dy|, and dirX > 0 and dirY < 0, (SQUARE_SIZE, -SQUARE_SIZE)
  3. (from pos:2) Done

Upvotes: 2

Blub
Blub

Reputation: 3822

It just checks if the offset of the mouse from the object into the x direction is larger than into the y.

If it is larger, it will move into the x direction, the actual direction depending on whether the mouse is to the left or right of the current object.

If it is smaller, it will move into the y direction, again the actual direction depending on whether the mouse is above or below the current object.

Upvotes: 1

Related Questions