Page 1 of 1

Need help with my basic hex grid

Posted: Thu Aug 18, 2016 4:58 am
by Rishavs
Hi

I was looking into hex grid using
http://www.redblobgames.com/grids/hexagons/ for reference.

My code is at
https://github.com/rishavs/HexGridLove2d/

I am able to create a hex grid and assign a cubic coordinate to the hexes.

However, I am not able to create a pixel to hex conversion. In my code i am trying to take any mouse click and find the hex it was clicked on.
For some reason, the hex coord comes correctly if i click towards the top left of any hex but wrong if i click on rest of the body.

I am assuming this has something to do with offset rows but I cant figure it out myself.
Can someone help me a bit here?

Edit:
quoting bits of my code.

Here is the grid generation:

Code: Select all

function create_hex_grid()
    
    local temp_hex = {}
    local temp_hex_points = {}
    local temp_hex_id = 0
    
    local hex_height = hex_size * 2
    local hex_width = math.sqrt(3) * hex_size
    
    local starting_hex_X = hex_width/2
    local starting_hex_Y = hex_height/2
    
    -- first create a staggered points grid
    for w=0, lvl_width_hex_count - 1 do
        for h = 0, lvl_height_hex_count - 1 do
            hexX = starting_hex_X + (w * hex_width) + ((hex_width/2) * (h % 2))
            hexY = starting_hex_Y + (h * hex_height * 3/4) 
            
            -- calculate and save the axial coordinates
            local cX = w - (h - (h % 2)) / 2;
            local cY = h
            local cZ = - cX - cY
            
            temp_hex_id = cX .. "x" .. cY .. "y" .. cZ .. "z";
            temp_hex_points = create_hex(hexX, hexY, hex_size - hex_grid_gap/2)
            temp_hex  = {
                center = {x = hexX, y = hexY},
                coord = {x = cX, y = cY, z = cZ},
                color = {get_random_color()},
                fill = "line",
                vertices = temp_hex_points
            }
            
            hex_grid_obj[temp_hex_id] = temp_hex
            
        end
    end
    
    -- print(inspect(hex_grid_obj))
    
end

function create_hex (hX, hY, hSize)
    local fn_hex_points = {}
    
    for i=0,5 do
        local vertAngle = 2 * math.pi / 6 * (i + 0.5)
        local vertX = hX + hSize * math.cos(vertAngle)
        local vertY = hY + hSize * math.sin(vertAngle)
        
        table.insert(fn_hex_points, vertX)
        table.insert(fn_hex_points, vertY)
    end
    
    return fn_hex_points
end
And here is the code for getting hex coord for pixel coord:

Code: Select all

function pixel_to_hex(x, y, size) 
    
    local fn_cX = (math.sqrt(3)/3 * x - y/3 ) / size
    local fn_cY = 2/3 * y / size
    local fn_cZ = -fn_cX - fn_cY

    return fn_cX, fn_cY, fn_cZ

end

function hex_round (cX_float, cY_float, cZ_float)
    local fn_cX = math.floor(math.floor (0.5 + cX_float))
    local fn_cY = math.floor(math.floor (0.5 + cY_float))
    local fn_cZ = math.floor(math.floor (0.5 + cZ_float))
    
    local cX_diff = math.abs(fn_cX - cX_float)
    local cY_diff = math.abs(fn_cY - cY_float)
    local cZ_diff = math.abs(fn_cZ - cZ_float)
    
    if cX_diff > cY_diff and cY_diff > cZ_diff then
        fn_cX = -fn_cY - fn_cZ
    else
        if cY_diff > cZ_diff then
            fn_cY = -fn_cX - fn_cZ
        else
            fn_cZ = -fn_cX - fn_cY
        end
    end
    
    
    if fn_cZ == -0 then fn_cZ = 0 end
    
    return fn_cX, fn_cY, fn_cZ
end

Re: Need help with my basic hex grid

Posted: Sat Aug 20, 2016 4:10 am
by pgimeno
I'm having trouble following that article. This one is easier for me, and it uses 2 coordinates per cell, which makes better sense to me:

http://blog.ruslans.com/2011/02/hexagon ... -math.html

Re: Need help with my basic hex grid

Posted: Sat Aug 20, 2016 12:34 pm
by Rishavs
Hi pgimeno. Thanks for trying.
I did manage to solve it by adding some offset to the algo.

Stranegly no article talks about this. Mathematically also this doesnt makes much sense.

My updated algo for pixel to hex is:

Code: Select all

function get_hex_id_from_point(x, y) 
    rx = x - math.sqrt(3) * hex_size/2
    ry = y - hex_size
    
    local cQ_float = (rx * math.sqrt(3)/3 - ry / 3) / hex_size 
    local cR_float =  ry * 2/3 / hex_size 
    local cS_float = -cQ_float - cR_float
    
    -- return cQ_float, cR_float, cS_float
    local cQ, cR, cS = get_round_hex_coord( cQ_float, cR_float, cS_float)
    
    -- check if hex exists
    local test_hex_id = cQ .. "q" .. cR .. "r" .. cS .. "s"
    
    if hex_grid_obj[test_hex_id] then
        return  cQ, cR, cS
    else
        return false
    end
end
and this is the offset i used after painfully observing the offset shape by clicking on each pixel;

rx = x - math.sqrt(3) * hex_size/2
ry = y - hex_size