开发者

Algorithm to find direction between two keys on the num pad?

Given the following direction enum:

typedef enum {
    DirectionNorth = 0,
    DirectionNorthEast,
    DirectionEast,
    DirectionSouthEast,
    DirectionSouth,
    DirectionSouthWest,
    DirectionWest,
    DirectionNorthWest
} Direction;

And number matrix similar to the numeric pad:

7 8 9
4 5 6
1 2 3

How would you write a function to return the direction between adjacent numbers from the matrix? Say:

1, 2 => DirectionEast
2, 1 => DirectionWest
4, 8 => DirectionNorthEast
1, 7 => undef

You may change the numeric values of the enum if you want to. Readable solutions preferred. (Not a homew开发者_开发知识库ork, just an algorithm for an app I am working on. I have a working version, but I’m interested in more elegant takes.)


int direction_code(int a, int b)
{
    assert(a >= 1 && a <= 9 && b >= 1 && b <= 9);
    int ax = (a - 1) % 3, ay = (a - 1) / 3,
        bx = (b - 1) % 3, by = (b - 1) / 3,
        deltax = bx - ax, deltay = by - ay;
    if (abs(deltax) < 2 && abs(deltay) < 2)
        return 1 + (deltay + 1)*3 + (deltax + 1);
    return 5;
}

resulting codes are

1 south-west
2 south
3 south-east
4 west
5 invalid
6 east
7 north-west
8 north
9 north-east


I would redefine the values in the enum so that North, South, East and West take a different bit each.

typedef enum {
    undef = 0,
    DirectionNorth = 1,
    DirectionEast = 2,
    DirectionSouth = 4,
    DirectionWest = 8,
    DirectionNorthEast = DirectionNorth | DirectionEast,
    DirectionSouthEast = DirectionSouth | DirectionEast,
    DirectionNorthWest = DirectionNorth | DirectionWest,
    DirectionSouthWest = DirectionSouth | DirectionWest
} Direction;

With those new values:

int ax = ( a - 1 ) % 3, ay = ( a - 1 ) / 3;
int bx = ( b - 1 ) % 3, by = ( b - 1 ) / 3;

int diffx = std::abs( ax - bx );
int diffy = std::abs( ay - by );

int result = undef;
if( diffx <= 1 && diffy <= 1 )
{
    result |= ( bx == ax - 1 ) ? DirectionWest : 0;
    result |= ( bx == ax + 1 ) ? DirectionEast : 0;
    result |= ( by == ay - 1 ) ? DirectionSouth : 0;
    result |= ( by == ay + 1 ) ? DirectionNorth : 0;
}
return static_cast< Direction >( result );

Update: Finally, I think its correct now.


With this matrix of numbers the following holds true: 1) a difference of 1 (+ve or -ve) always implies that the direction is either east or west. 2) similary, a difference of 3 for direction north or south. 3) a difference of 4 north east or south west. 4) a difference of 2 north west or south east.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜