简体   繁体   中英

How do I calculate the distance between two squares on a grid, including the target square

I've been trying variations on the following code...

public int Distance2D(int x1, int y1, int x2, int y2)
{
    //     ______________________
    //d = √ (x2-x1)^2 + (y2-y1)^2
    //

    //Our end result
    int result = 0;
    //Take x2-x1, then square it
    double part1 = Math.Pow((x2 - x1), 2);
    //Take y2-y1, then sqaure it
    double part2 = Math.Pow((y2 - y1), 2);
    //Add both of the parts together
    double underRadical = part1 + part2;
    //Get the square root of the parts
    result = (int)Math.Sqrt(underRadical);
    //Return our result
    return result;
}

The examples below are left for clarity, but were wrong due to my mistake

Distance2D(1, 1, 1, 2) // returns 1 - correct
Distance2D(1, 1, 2, 1) // returns 1 - correct
Distance2D(1, 1, 2, 2) // returns 1 - correct
Distance2D(1, 1, 5, 5) // returns 5 - correct

Distance2D(0, 2, 5, 8) // returns 7 - incorrect, should be 8
Distance2D(1, 1, 5, 3) // returns 4 - incorrect, should be 5
Distance2D(10, 112, 15, 118) // returns 7 - incorrect, should be 8

Is there a better formula for this?

Update

I had some of my expected values above incorrect due to mistakenly taking the origin of the 2nd coordinate from the location of the 1st.

I'm trying to get the number of moves a game piece would need to make to travel from one coordinate to another on a square grid. Moving one square at a time, diagonals count as 1 move also.

Thus ...

  • from 1,1 to 5,5 would take 4 diagonal movements and one horizontal/vertical move for a total of 5 moves. This returns correctly
  • from 1,1 to 5,3 would take 3 diagonal and 1 horizontal/vertical move for a total of 4 moves. This now returns correctly
  • from 1,1 to any of 1,2/2,1/2,2 is one move. These each return correctly
  • from 0,2 to 5,8 is 5 diagonal moves and one vertical move for a total of 6 moves. This returns 7 incorrectly

If I use Math.Round() on the result then I get the following errors...

  • from 0,2 to 5,8 returns 8 instead of 6
  • 1,1 to 5,5 returns 6 instead of 5

If I use Math.Ceiling() I get the following errors...

  • 0,2 to 5,8 returns 8 instead of 6
  • 1,1 to 2,2 returns 2 instead of 1
  • 1,1 to 5,3 returns 4 instead of 5

The problem is that performing a cast ( (int) ) effectively does a "floor" operation on your number, cutting off any decimal values, even if those decimal values are .99999 . It sounds like you're looking instead to round the value to the nearest integer, which can be done with the Math.Round() function.

Try this:

result = (int)Math.Round(Math.Sqrt(underRadical));

Update

The pythagorean theorem-based approach you're taking won't work for what you're trying to calculate. This is a completely different use case. Good news is, your use case is a lot simpler. Just figure out the distance you'd have to travel on each axis, then subtract whatever shortcuts you can take by moving diagonally. Something like this, I think:

var yDist = Math.Abs(y2 - y1);
var xDist = Math.Abs(x2 - x1);
var diagShortcut = Math.Min(yDist, xDist);
return yDist + xDist - diagShortcut;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM