Problem with GL_POLYGON - (Hexagon)

Started by
34 comments, last by superpig 17 years, 1 month ago
Hi Guys, Think my brain has just melted today .. aarrgghhh I have manged to draw a GL_POLYGON (6 sides hexagon) woohoo lol I am trying to build a hexagon tile system, but cant seem to get my hexagon drawing the right way. I have been banging my head all day, drawing it differently and using glRotatef all over the place but I can't get the thing right. Here is a screen shot Here is the code fot the hexagon:

void drawHexTile(float size, float posX, float posZ)
{	

	float	x, z = 0.0f;	// Pos X, Z 
	float	y = 0.0f;	// Pos Y height
     
	float	radius = size/2; //(radius is half of size)
	float	angle = 0.0f;  
	float	step = (PI / 3.0f);   


	glBegin(GL_TRIANGLE_FAN);

		glNormal3f(0.0f, 1.0f, 0.0f);
		
		glVertex3f(posX, y, posZ);		// Center vertex
		
		// not sure I really need this one
		glVertex3f(posX, y, posZ + radius);	// First vertex


		for (angle = 0.0f; angle < ((2.0f * PI) - step); angle += step) // draw counter-clockwise

		{
			// Find x and y of the next vertex
			x = radius * sin(angle);
			z = radius * cos(angle);
		

			// Next vertex
			glVertex3f(posX + x, y, posZ + z);
		}
		
		// Last vertex
		glVertex3f(posX, y, posZ + radius);
	
	glEnd();
}

Here is the code fot the grid:

	for (int x = 0; x < gridSizeX; x += tileSize)
	{
		for (int z = 0; z < gridSizeY; z += tileSize)
		{
			drawHexTile(tileSize, x, z);
		}
	}

I need to rotate or draw this hexagon round 90 degrees so I can build my grid with the tiles all joining corrctly. (see this article for inspiration on hexagon tiling) http://www.gamedev.net/reference/articles/article747.asp But as you can see from the screen shot, I have some issues Thanks Guys
----------------------------------------Now just hit that link that says 'Rate This User' [wink]
Advertisement
First off, I don't think you need to use sin/cos to create a hexagon, just put in the points manually (one less thing to go wrong). Also, you don't need to rotate, all you need to do is translate. Check out this article for an more in depth explination.
Your problem stems from the fact that you're drawing hexagons in a square grid. Hexagons can't tessellate in a square grid because they're hexagons, not squares.

So if you're drawing your hexagons by columns, then you draw each hexagon by twice the altitude of the hexagon below the previous hexagon. Now the next column is drawn 1.5 * radius of the hexagon away from the previous column in the x direction.

Every time you switch to another column of hexagons, you need to change the y offset. So for the first column, it's zero. For the second column, it's equal to the altitude of the hexagon. For the third column, it's zero again. For the fourth, it's equal to altitude...and so on and so forth.

EDIT: I really suggest you start using a right-handed coordinate system. I can already see some comments that do not accurately describe what your code is doing due to your funky system. Converting to a right-handed system will not only be easier for others to understand when helping you, it might also be easier for you later on.

[Edited by - CrimsonSun on February 25, 2007 5:23:39 PM]
Hey There,

Thanks for the quick replies guys.

I am working on off-seting the odd rows right now using

just using

if (x % 2 == 1)
oddRow = TRUE;

Then adding the offset to the drawHexTile();


I'm not sure I explain the original problem well though, if you look at the screen shot, the "flat" sides are next to each other.
Where it should be the "point" is 90 degrees round, so I can do the odd row offset.
And get them all meshing nicely together.

I was wondering about the right hand and left hand thing, or are you just talking as a DirectX guy.
It's just that OpenGL is left hand right ??
----------------------------------------Now just hit that link that says 'Rate This User' [wink]
Now I'm not too good at math and all, so my advice might not be the soundest around, but here's my input anyway:

You don't need to rotate your tiles around, just nudge them to the side.


bool OtherTile = false;for(int x = 0; x < gridSizeX; x += tileSize){    for(int z = 0; z < gridSizeY; z += tileSize)     {	if(OtherTile)            drawHexTile(tileSize, x, z);        else            drawHexTile(tileSize, x + (tileSize/2), z);                OtherTile = !OtherTile;    }}


Oh, and question:
for(int z = 0; z < gridSizeY; z += tileSize)

Why 'GridSizeY' when you are using the 'z' plane?
What you've got is a zxy coordinate system: you've got the flat ground on the zx plane and depth on the y-axis. Most (if not all) tutorials, examples, and books are going to use a right-handed coordinate system (an xyz system) where the flat ground is on the xy plane and depth is represented on the z-axis.
As was already said, you don't need to rotate anything, just translate it. What you're doing is drawing the hexagons as if they were squares. Instead of drawing a row at every height, spread them out by an altitude and draw a row every altitude. That should give you what you want.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~I program in C++, on MSVC++ '05 Express, and on Windows. Most of my programs are also for windows.
Hi Servant of the Lord ;)

Well spotted floor in my plan I see.

Had me worried for a second.

Because I will be using a char map / array :

char map[10][10] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 2, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 3, 3, 0, 0, 0, 1},
{1, 0, 0, 0, 3, 3, 0, 0, 0, 1},
{1, 0, 0, 0, 3, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 3, 0, 4, 4, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};

so I went for X & Y, to make it easier, as you would read a road map.
Although I will relate this to the 3D world usind X,Z co-ords.

But thanks for looking out.

As for the rest of your post, what can I say.

Spot on !!, well it's exactly what I am doing ;) so I agree with you haha.

the only problem I seem to have now is the following :

	for (int x = 0; x < gridSizeX; x += tileSize)	// row (X)	{		if (x % 2 == 1) // if (row X) is odd			rowOdd = TRUE;		else			rowOdd = FALSE;		for (int y = 0; y < gridSizeY; y += tileSize)	// col (Y)		{			if (!rowOdd)				drawHexTile((float)tileSize, (float)x, (float)y);			else				drawHexTile((float)tileSize/2, (float)x + (tileSize/2), (float)y);		}	}


As "rowOdd" never returns TRUE .....

What have I missed ??
----------------------------------------Now just hit that link that says 'Rate This User' [wink]
Hi CrimsonSun,

I think I got lost somewhere there !!

As far as I am aware, apart from the direction I am drawing polygons, which determins if they are culled or not.
I thought I had it all right.

I have a grid runnind X (rows) and Z (cols) and Y (0)

So surely Z is my depth right ??

The only thing moving on the Y is my free flaoting camera right now, so I can move around for testing.

Unless I missed something basic here, left handed in OpenGL ..
as per the screen shot, my camera is at 0,0,0

Forward would be -Z, left would be -X, and up would be +Y ... yeah ??

I am looking down the -Z axis ..(almost half way between -Z & -X)

maybe I need another screen shot to make this clear, a top down shot as you would see the map..

----------------------------------------Now just hit that link that says 'Rate This User' [wink]
First up:
if(!rowOdd)   drawHexTile((float)tileSize, (float)x, (float)y);else   //Here you don't need to cut the *size* of the tile in half   drawHexTile((float)tileSize/2, (float)x + (tileSize/2), (float)y);


Second, these lines:
for(int x = 0; x < 5; x += tileSize)    {        if(x % 2 == 1)	        rowOdd = TRUE;        else		    rowOdd = FALSE;

Are you problem. Look at it carefully. If 'x' is odd, it is TRUE, right? But you start 'x' off at '0', and every loop you add 'tileSize' to it. If 'tileSize' is an even number, rowOdd will never become TRUE.

Example:
tileSize = 8;Loop 1:x = 0;rowOdd = FALSE;Loop 2:x = 4;rowOdd = FALSE;Loop 3:x = 8;rowOdd = FALSE;etc...


You need to go like this:

if(rowOdd == TRUE) rowOdd = FALSE;
else rowOdd = TRUE;

Also, if you look at the tutorial sevensevens posted, you'll see you need to not only nudge the tiles to the side, but will also have to nudge each tile down some, but you shouldn't worry about that until you get the rows lined up first.

This topic is closed to new replies.

Advertisement