How to store vertices positions of a hexgrid in a 2D Array?

Im facing this issue. I want to create an hexgrid and be able to create in this fashion:

//grid extents
int numCols,numRows;
for (int i=0; i<numCols; ++i){
 for (int j=0; j<numRows; ++j){

 //x and y coordinates of my hexagon's vertices
 float xpos,ypos;


 //2D array storing verteces of my hextopology  
 vertices[i][j] = new VertexClass(xpos, ypos);

 // statements to change xpos/ypos and create hex
 } 
}

All methods I found to make hexgrid, first create an hex object and then replicate it over a grid thus creating duplicate verteces position ad joining edges. I want to avoid duplicating verteces position. How can I declare statements to make such a grid?

Thanks

May I ask why not have the duplicate vertices? I don’t think the draws involved consume very much time.

You could write your own, and have if-statements to inspect whether you are drawing the first row or column, and only draw all six sides in that case. Then for the rest, draw only the remaining sides.

I’m using the following to calculate the locations of the vertices, given a top corner (outside the hex). By creating a Polygon, I’m able to use its “contains” function to tell if the mouse is within the bounds. When you draw, you can pick the sides you want to draw. The orientation here is pointy side up. Shouldn’t be too hard to change to make it flat-side up.


// some constants
    public static final int SIDELENGTH = 32;  // length of a side in pixels
    public static final int COSSIDE = (int)(SIDELENGTH * Math.cos((30 * Math.PI)/180));

// for top corner (xloc, yloc)
    int[] xpts = new int[6];
    int[] ypts = new int[6];
    xpts[0] =  xLoc + COSSIDE;
    xpts[1] = xpts[0]+ COSSIDE;
    xpts[2] = xpts[1];
    xpts[3] = xpts[0];
    xpts[4] = xLoc;
    xpts[5] = xpts[4];
	
    ypts[0] = yLoc;
    ypts[1] = yLoc + (SIDELENGTH/2);
    ypts[2] = ypts[1] + SIDELENGTH;
    ypts[3] = ypts[0] + SIDELENGTH*2;
    ypts[4] = ypts[2];
    ypts[5] = ypts[1];

    this.polygon = new Polygon(xpts, ypts, 6);

I’m sorry, I didn’t read your question closely enough.

Maybe just sort the positions by their starting x and y values? For example, set it up so that each row in the array has the same y starting value?

Of course it all depends upon what you want to do with the data once you have it. Will the orientation be fixed or can the hexes rotate? Will you be using the data for bounds checking ever?

To find the vertices of a given hex x,y, you can write a formula to get the correct indices of their locations in the array.

no worries. what I would like to do is this
-have different basic grid layouts (hex, quad, tria)
-able to extract from the created grid every single basic shape (so its vertices) and store it in a list

I will have so different classes each one for each basic shape. For example a triangle class to be instatiated needs 3 points. Im doing this because the starting grid will be deformed according to some rules but topology will remain unchanged and so made up od “deformed” shape. Still later I want to retrieve all “pieces” of the deformed grid. Hope this is clear.

Now, for quads, is straightforward, I manaed to do it for triangles…but with hexagons Im really struggling…I read many articles but still stuck. How would you sort the points?

Ok Ill show you with one pic the problem I have so maybe you can give more inputs :smiley:
Now I have a shifted grid which I used for triangles, the code looks like


float side = 10;
for (int i=0; i<numCols; ++i){
				for(int j=0; j<numRows; ++j) {
					float xpos,ypos;
					if (j%2!=0 && i%2!=0 ){
					 xpos = side*(i+0.5f);
					 ypos = (0.866f*side) * j;
					
					
					} else{
						 xpos = side*(i);
						 ypos = (0.866f*side) * (j+0.5f);
					}
					
					Vector[i][j] = new Vector( xpos, ypos);
				}
			}


Ok I can have unsed points although I was trying to avoid it but it seems I cannot skip with hexagons. So the situation is like in the picture below. Now once I created the grid how do I sort to create the hex tiling as in the picture? I need the indeces of the six verteces to sort all point in my grid…of course at the edge of the grid there will be some unsed (unsorted) points - those within green line in my pic.

Thanks for any help!

http://www.designedbyenergy.com/site/wp-content/uploads/misc/grid.jpg

I can’t see your picture, unfortunately. Have you posted it on a working URL?

If all you want are the points, I would give your for loops one pass per y-value, rather than one pass per hex. And store them sorted first by y then by x. Given that, it should be possible to create a formula to find the right indexes into the array for a particular hex.

It seems like you already have a handle on the trig involved to make successive horizontal passes.

I confess, when I made Hexara (www.hexara.com still a work in progress), which uses a hex grid, I wasn’t trying to search for shapes on the fly. Instead, I created a Hexagon object, with a polygon stored for its “contains” method, and gave each Hexagon a list of it’s neighbors, in a HashMap for when I’m doing tree searches of possible paths through the grid. I only have 20-something hexagons, sounds like you have a lot more than that.

You can easily make all the vertices for a hex grid just by looping through and offsetting every other row by 0.25 * hex width, or 0.5 * the length of a side (so 1 in your case). Like this.


for (int i = 0; i < rowCount; i++)
{
    for (int j = 0; j < colCount; j++)
    {
        float x = j * gridSize;
        float y = (i % 2 == 0) ? (i+0.5f) * gridSize : i * gridSize;
        vertexList.add(new Vertex(x,y)); 
    }
}

Im not sure about what this lines does

  float y = (i % 2 == 0) ? (i+offsetFraction) * gridSize : i * gridSize;

what are ? and : for? sorry Im new to programming.

Sure, that’s called a ternary operator which is basically shorthand for an if/else statement, and it’s a little faster to execute.


String resultString = amount > 50 ? "You won!" : "You lost!";

is the same as


String resultString = "You lost!";
if (amount > 50)
{
    resultString = "You won!";
}

Or also:


String resultString = null;
if (amount > 50)
{
    resultString = "You won!";
}
else
{
    resultString = "You lost!";
}

So basically I was just checking to see if we were at an even row, and if we were I offset by 0.5.

mhh here’s the solution I found - I wonder if I could cleanup the code a bit and make just 1 loop instead of 2 without the j%2 statement…
The two blocks of code for j%2 change only for Vector c and f respectively the other stayed unchanged - so it it possible to improve it?
xpos = side; and ypos=0.866*side; in this manner I force the grid to be of regular hexagons.

I execute outside the for loops a purgeLines() function to delete lines that share equal start and end points coordinates - so get rid of duplicates.

As Philfrei mentioned the other approach would be to the create a hexagon object itself and then replicate over a grid, and then purge duplicates points at joining hexagons and not at the edge of grid. Never used hashmaps but is something I would really like to harness when Ill get sometime.

float side = w / (numCols);
			particles = new Particle[numCols][numRows][2];
			for (int i=0; i<numCols; ++i){
				for(int j=0; j<numRows; ++j) {
					float xpos,ypos;
					if (j%2!=0  ){
					 xpos = side*(i-0.5f);
					 ypos = (0.866f*side) * j;
					
					
					} else{
						 xpos = side*(i);
						 ypos = (0.866f*side) *j;
					}
					
					vertices[i][j][0] = new Vector(xpos,
							ypos, 1.0f);
				}
			}
			for  (int j =0; j<numRows-2; ++j){
				if (j%2 ==0){
					for (int i=j%2*2; i<numCols-2; i+=3){
					
						
						 Vector a = vertices[i][j][0];  				
						 Vector b = vertices[i+1][j][0];
						Vector c = vertices[i+2][j+1][0];  
						 Vector d = vertices[i+1][j+2][0];
						 Vector e = vertices[i][j+2][0]; 
						 Vector f = vertices[i][j+1][0];   
                  
               draw.line(a,b);
                 draw.line(b,c);
                 draw.line(c,d);
                 draw.line(d,e);                  
                  draw.line(e,f);
                  draw.line(f,a);
                  
					
					}
				} else{
					for(int i=j%2*2; i<numCols-2; i+=3){

						 Vector a = vertices[i][j][0];  				
						 Vector b = vertices[i+1][j][0];
						 Vector c = vertices[i+1][j+1][0];  
						Vector d = vertices[i+1][j+2][0];
						 Vector e = vertices[i][j+2][0]; 
						 Vector f = vertices[i-1][j+1][0];   
                  
                draw.line(a,b);
                 draw.line(b,c);
                 draw.line(c,d);
                 draw.line(d,e);                  
                  draw.line(e,f);
                  draw.line(f,a);
						
					}
				}
				
			}

http://www.designedbyenergy.com/site/wp-content/uploads/misc/1.jpg