Jump to content

Drawing a hex


Wstar

Recommended Posts

What I want to do.

I need to build a hex map.  I have done this by using the imagepolygon() fuctions.  Problem is, I need to insert an image within the hex.  And the image IS a hex shape too.  I need to know if anyone has any ideas on doing this?  I do not think imagepolygon() can do this, or can it?

 

Here is my code for making the hex (yes i know its not a hex yet)

 

header("Content-type: image/png");
$im = imagecreate(200, 200);
$green = imagecolorallocate($im, 0, 255, 0);
$red = imagecolorallocate($im, 255, 0, 0);
$points = array(100, 10, 150, 10, 160, 80, 10, 150, 100, 10);
$vertices = count($points) / 2;
imagepolygon($im, $points, $vertices, $red);
imagepng($im);
imagedestroy($im);

Link to comment
Share on other sites

this will give your points

<?php
$step = 60;
$rad = 80;
$centrex = imagesx($im)/2;
$centrey = imagesy($im)/2;

for ($i=0; $i<360; $i+=$step)
{
    $points[] = $centrex + $rad*cos(deg2rad($i));
    $points[] = $centrey + $rad*sin(deg2rad($i));
}
?>

 

If you use imagefilledpolygon uou can use red area as a mask to copy the image.

 

Alternatively,

 

Copy your hexagonal map into the centre of the new image and fill the outside area green

Link to comment
Share on other sites

I get an error when I try the following code:

header("Content-type: image/png");

$step = 60;
$rad = 80;
$centrex = imagesx($im)/2;
$centrey = imagesy($im)/2;

for ($i=0; $i<360; $i+=$step)
{
    $points[] = $centrex + $rad*cos(deg2rad($i));
    $points[] = $centrey + $rad*sin(deg2rad($i));
}

$im = imagecreate(200, 200);
$green = imagecolorallocate($im, 0, 255, 0);
$red = imagecolorallocate($im, 255, 0, 0);
$vertices = 6;
imagepolygon($im, $points, $vertices, $red);
imagepng($im);
imagedestroy($im);

 

Can't seem to get it to work.  Also, what do you mean by use the $red as a mask to copy the image?  You mean just put the image in $red?  It didn't work for me.

Link to comment
Share on other sites

<?php
header("Content-type: image/png");
$im = imagecreate(200, 200);
$green = imagecolorallocate($im, 0, 255, 0);
$red = imagecolorallocate($im, 255, 0, 0);

$step = 60;
$rad = 80;
$centrex = imagesx($im)/2;
$centrey = imagesy($im)/2;

for ($i=0; $i<360; $i+=$step)
{
    $points[] = $centrex + $rad*cos(deg2rad($i));
    $points[] = $centrey + $rad*sin(deg2rad($i));
}

$vertices = count($points) / 2;
imagepolygon($im, $points, $vertices, $red);
imagepng($im);
imagedestroy($im);
?>

 

Use red to define the area of original image to be copied to the hex image

Link to comment
Share on other sites

I'm sorry, I'm not sure what you mean by;

Use red to define the area of original image to be copied to the hex image

 

I tried the following without luck.

 

<?php
header("Content-type: image/png");
$im = imagecreate(200, 200);
$green = imagecolorallocate($im, 0, 255, 0);
$red = '<img src="me.JPG" width="10" height="10">';

$step = 60;
$rad = 80;
$centrex = imagesx($im)/2;
$centrey = imagesy($im)/2;

for ($i=0; $i<360; $i+=$step)
{
    $points[] = $centrex + $rad*cos(deg2rad($i));
    $points[] = $centrey + $rad*sin(deg2rad($i));
}

$vertices = count($points) / 2;
imagepolygon($im, $points, $vertices, $red);
imagepng($im);
imagedestroy($im);
?>

 

Is there an example someone can provide?

 

Thanks for taking the time to help.

Link to comment
Share on other sites

I've attached a sample map image (manchester.jpg) and the result of this code in "hexmap.png"

<?php
header("Content-type: image/png");
$im = imagecreatetruecolor(200, 200);
$green = imagecolorallocate($im, 0, 255, 0);
$red = imagecolorallocate($im, 255, 0, 0);
$step = 60;
$rad = 100;
$centrex = imagesx($im)/2;
$centrey = imagesy($im)/2;

for ($i=0; $i<360; $i+=$step)
{
    $points[] = $centrex + $rad*cos(deg2rad($i));
    $points[] = $centrey + $rad*sin(deg2rad($i));
}

$vertices = count($points) / 2;
imagefilledpolygon($im, $points, $vertices, $red);

/**
* at this point we have a green square with a red hexagon in the centre.
*
* Now we introduce a map (200x200 also) and copy it just into the red area
* of our image
*/
$map = imagecreatefromjpeg('manchester.jpg');

/**
* scan the hex image for red pixels and copy the corresponding
* map pixel to the image
*/
for ($x=0; $x<200; $x++)
{
    for ($y=0; $y<200; $y++)
    {
        if (imagecolorat($im, $x, $y) == $red)
        {
            imagesetpixel($im, $x, $y, imagecolorat($map, $x, $y));
        }
        else 
        {
            imagesetpixel($im, $x, $y, $green);
        }
    }
}
imagepng($im);
imagedestroy($im);
?>

 

[attachment deleted by admin]

Link to comment
Share on other sites

Alright, one last problem.  Trying to loop the hex to create a row of hexs.

 

I've been trying and here is what I've ended up with, but still no luck.

 

Any ideas on what I'm doing wrong?

 

<?php
function hex_map($hex_size){

  // check hex size.  If too large or too small, default 
  if ($hex_size > 300 || $hex_size < 40){
    $hex_size = 100;
  }

  header("Content-type: image/png");
  
  // make the image area
  $im = imagecreatetruecolor(500, 500);
  $green = imagecolorallocate($im, 0, 66, 66);
  $red = imagecolorallocate($im, 255, 255, 0);
  
  // how many hex's can fit on a row
  $hex_row_count = (integer)($hex_size / 500);
  
  $count = 0;
  $next_hex = 0;
  
// loop to draw the hex map
while ($hex_row_count >= $count) {

    $next_hex += $hex_size;
  
  
    $step = 60;
    $rad = $hex_size;
    
    $centrex = $next_hex;
    $centrey = $hex_size;
  
    //$centrex = imagesx($im)/2;
    //$centrey = imagesy($im)/2;

    for ($i=0; $i<360; $i+=$step) {
      $points[] = $centrex + $rad*cos(deg2rad($i));
      $points[] = $centrey + $rad*sin(deg2rad($i));
    }

    $vertices = count($points) / 2;
    imagefilledpolygon($im, $points, $vertices, $red);

    $hex .= imagepng($im);
    
    $count++;
}

imagedestroy($im);
return $hex;
}

echo hex_map(50);
?>

Link to comment
Share on other sites

Like this

<?php
function hex_map($hex_size){

  // check hex size.  If too large or too small, default 
  if ($hex_size > 300 || $hex_size < 40){
    $hex_size = 100;
  }

  
  
  // make the image area
  $im = imagecreatetruecolor(500, 500);
  $green = imagecolorallocate($im, 0, 66, 66);
  $red = imagecolorallocate($im, 255, 255, 0);
  
  // how many hex's can fit on a row
  $hex_row_count = (integer)(500 / $hex_size);
  
  $count = 0;
  $next_hex = 0;
  
// loop to draw the hex map
while ($hex_row_count >= $count) {

    $next_hex += $hex_size;
  
  
    $step = 60;
    $rad = $hex_size/2;                              // radius is half the size
    
    $centrex = $next_hex;
    $centrey = $hex_size;
    
    $points = array();                              // new array
    for ($i=0; $i<360; $i+=$step) {
      $points[] = $centrex + $rad*cos(deg2rad($i));
      $points[] = $centrey + $rad*sin(deg2rad($i));
    }

    $vertices = count($points) / 2;
    imagefilledpolygon($im, $points, $vertices, $red);

    //$hex .= imagepng($im);
    
    $count++;
}

return $im;                 // return the image
}

$image = hex_map(50);

header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
?>

Link to comment
Share on other sites

I thank you greatly.  I just keep running into problem after problem.  Got it to repeat.  Trying to make a hex grid.  Thought it would be easy if I found out how to repeat the hexs.  I was wrong.  Is there any examples of hex grids in php using this method?  I just can't seem to get the calculations right for lining up the hexs.

 

I'm trying to make a image that is 500x500 and have it tiled with hexes (full hexs, and not half's on edges) and have the user define the hex size.  Ultimately, I want images in the hexes that are links (each having different coords).

 

Is there an easier way to do this?

 

 

Link to comment
Share on other sites

try this

<?php
function hex_map($hex_size){

    // check hex size.  If too large or too small, default 
    if ($hex_size > 300 || $hex_size < 40){
        $hex_size = 100;
    }



    // make the image area
    $im = imagecreatetruecolor(500, 500);
    $green = imagecolorallocate($im, 0, 66, 66);
    $red = imagecolorallocate($im, 255, 255, 0);

    // how many hex's can fit on a row
    $hex_row_count = floor(500 / $hex_size);

    $count = 0;
    $centrey = -$hex_size/2;
    for ($r=0; $r<$hex_row_count; $r++)
    {   
        if ($r%2 == 0)
        {
            $next_hex = $hex_size/2 ;
            $rowcount = $hex_row_count;
        }
        else
        {
            $next_hex = $hex_size ;
            $rowcount = $hex_row_count-1;
        }
        $centrey += $hex_size;
        // loop to draw the hex map
        for ($c=0; $c<$rowcount; $c++) {
            $step = 60;
            $rad = $hex_size/2;                              // radius is half the size

            $centrex = $next_hex;

            $points = array();                              // new array
            for ($i=30; $i<360; $i+=$step) {
              $points[] = $centrex + $rad*cos(deg2rad($i));
              $points[] = $centrey + $rad*sin(deg2rad($i));
            }

            $vertices = count($points) / 2;
            imagefilledpolygon($im, $points, $vertices, $red);

            //$hex .= imagepng($im);
            $next_hex += $hex_size;

            $count++;
        }
    } 
    return $im;                 // return the image
}

$image = hex_map(100);

header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
?>

 

If you make it a form image, the coordinates where the user clicked are posted with the form data. All you have to do then is calculate which hex was clicked from those coordinates.

Link to comment
Share on other sites

getting there

<?php
function hex_map($hex_size){

    // check hex size.  If too large or too small, default 
    if ($hex_size > 300 || $hex_size < 40){
        $hex_size = 100;
    }



    // make the image area
    $im = imagecreatetruecolor(500, 500);
    $green = imagecolorallocate($im, 0, 66, 66);
    $red = imagecolorallocate($im, 255, 255, 0);
    $black = imagecolorallocate($im, 0, 0, 0);
    // how many hex's can fit on a row
    $hex_row_count_h = floor(500 / ($hex_size));
    $hex_row_count_v = floor(500 / ($hex_size*0.75));

    $count = 0;
    $centrey = 0;
    for ($r=0; $r<$hex_row_count_v; $r++)
    {   
        if ($r%2 == 0)
        {
            $next_hex = $hex_size/2 ;
        }
        else
        {
            $next_hex = $hex_size-5 ;
        }
        $centrey += $hex_size * 0.75;
        // loop to draw the hex map
        for ($c=0; $c<$hex_row_count_h; $c++) {
            $step = 60;
            $rad = $hex_size/2;                              // radius is half the size

            $centrex = $next_hex;

            $points = array();                              // new array
            for ($i=30; $i<360; $i+=$step) {
              $points[] = $centrex + $rad*cos(deg2rad($i));
              $points[] = $centrey + $rad*sin(deg2rad($i));
            }

            $vertices = count($points) / 2;
            imagefilledpolygon($im, $points, $vertices, $red);
            imagepolygon($im, $points, $vertices, $black);
            //$hex .= imagepng($im);
            $next_hex += $hex_size * cos (M_PI/6);

            $count++;
        }
    } 
    return $im;                 // return the image
}

$image = hex_map(50);

header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
?>

Link to comment
Share on other sites

ahhh, i see.  I'll try it, thank you!  Also.  One small question.  Before the background was always green.  Now its black, even though the code still says to make the image green.  Why is that?  I'm wanting the background to be white.

Link to comment
Share on other sites

On line 35 I took a guess at the offset for even rows being about 5 pixels. This calculates it accurately

<?php
function hex_map($hex_size){

    // check hex size.  If too large or too small, default 
    if ($hex_size > 300 || $hex_size < 40){
        $hex_size = 100;
    }



    // make the image area
    $im = imagecreatetruecolor(500, 500);
    $green = imagecolorallocate($im, 0, 66, 66);
    $red = imagecolorallocate($im, 255, 255, 0);
    $black = imagecolorallocate($im, 0, 0, 0);
    // how many hex's can fit on a row
    $hex_row_count_h = floor(500 / ($hex_size));
    $hex_row_count_v = floor(500 / ($hex_size*0.75));

    $count = 0;
    $centrey = 0;
    
    $rad = $hex_size/2;                              // radius is half the hex_size
    $side = 2 * $rad * sin (deg2rad(30));            // offset is difference between radius and the
    $offset = $rad - $side * cos (deg2rad(30));      // distance from centre to a side of the hex.
    
    for ($r=0; $r<$hex_row_count_v; $r++)
    {   
        if ($r%2 == 0)
        {
            $next_hex = $hex_size/2 ;
        }
        else
        {
            $next_hex = $hex_size-$offset ;                 // apply the offset
        }
        $centrey += $hex_size * 0.75;
        // loop to draw the hex map
        for ($c=0; $c<$hex_row_count_h; $c++) {
            $step = 60;

            $centrex = $next_hex;

            $points = array();                              // new array
            for ($i=30; $i<360; $i+=$step) {
              $points[] = $centrex + $rad*cos(deg2rad($i));
              $points[] = $centrey + $rad*sin(deg2rad($i));
            }

            $vertices = count($points) / 2;
            imagefilledpolygon($im, $points, $vertices, $red);
            imagepolygon($im, $points, $vertices, $black);
            //$hex .= imagepng($im);
            $next_hex += $hex_size * cos (M_PI/6);

            $count++;
        }
    } 
    return $im;                 // return the image
}

$image = hex_map(200);

header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
?>

Link to comment
Share on other sites

  • 1 year later...

Hellay there,

 

sorry for pushing uo such an old post.

 

I've been brainstorming over my problem 2 days now...

 

I used this method to draw a HexMap.

My goal is / was.. to instert this Map into my database.

 

Is there a way to store these "drawn" koordinates into my database?

 

I would like to store them in there, so I can use the coordinates later on for other options (like choosing a HexField, or displaying something there)

 

Most probably the answer is ways to near for me to see..  :-\

 

Thanks in advance for any help..!

 

Best wishes,

 

Tweety

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.