Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

snap to closest hexagon centre in hex based grid

I am attempting to create a grid based game. so far i have a hexagonal tile based grid, with a coordinate scheme as shown below:

col 0
 | col 1
 |   | col 2
 |   |  |
 __  | __    __    __    __   
/00\__/02\__/04\__/06\__/08\__
\__/01\__/03\__/05\__/07\__/09\--- row 0
/10\__/12\__/14\__/16\__/18\__/
\__/11\__/13\__/15\__/17\__/19\--- row 1
/20\__/22\__/24\__/26\__/28\__/
\__/21\__/23\__/25\__/27\__/29\--- row 2
/30\__/32\__/34\__/36\__/38\__/
\__/  \__/  \__/  \__/  \__/   --- row 3

And looks like this in real life just with random colours for each hexagon:

What i am struggling to figure out is, when the user clicks on a hexagon how do i determine what hexagon they have clicked on?

the code i have tried so far is as follows:

private: System::Void MyForm_MouseDown(System::Object^  sender,
    System::Windows::Forms::MouseEventArgs^  e) {

    int CloseI=0,CloseJ=0;
    CloseJ = FindNearesetX(e->X);
    CloseI = FindNearesetY(e->Y);
    //Grid[down(y)][along(x)]
    P1.X = Grid[CloseI][CloseJ].GetX();
    P1.Y = Grid[CloseI][CloseJ].GetY();
} // END MOUSE DOWN EVENT

int FindNearesetX(int ActualX){
    int ClosestJPos;
    ClosestJPos = ((ActualX-Grid[0][0].GetX())/(1.5*HexSideLength));
    return ClosestJPos;
}//END FIND NEAREST X

int FindNearesetY(int ActualY){
    int ClosestIPos;
    ClosestIPos = ((ActualY-Grid[0][0].getY())/(HexHeight));
    return ClosestIPos;
}//END FIND NEAREST Y

private: System::Void MyForm_MouseMove(System::Object^  sender,
    System::Windows::Forms::MouseEventArgs^  e) {
    this->Invalidate();

    P2.X = e->X;
    P2.Y = e->Y; 
} // END MOUSE MOVE EVENT       

This however did not work how i wanted, this is because when the user clicks to the left of the centre point of a hexagon it snaps to the hexagon to the left of the one they clicked, and also if they click above the centre point on all odd columns it snaps to the hexagon above the one they clicked on.

I have been stuck on this one for 2 days now and really want to get it figured out. Thanks

like image 578
JabbaWook Avatar asked Dec 19 '22 17:12

JabbaWook


1 Answers

The point clicked will always be closest to the center of hexagon in which the click occurs, unless the point is exactly between two hexagons in which case it will be equidistant from the two centers. The equation for the distance between two points is the SQRT( (x1-x2)^2 + (y1-y2)^2 ).

You do not have to test the distance to every hexagon. By creating x/y thresholds you can limit the test to just nearby hexagons. For example, if hexagons have a width of 10 and the point is at (51, 73) you do not have to test hexagons with x-coordinates of < 40 or > 70.

like image 165
Tyler Durden Avatar answered Feb 09 '23 21:02

Tyler Durden