views:

77

answers:

1

Hi, I'm trying to create an honeycomb with as3 but I have some problem on cells positioning.

I've already created the cells (not with code) and for cycled them to a funcion and send to it the parameters which what I thought was need (the honeycomb cell is allready on a sprite container in the center of the stage).

to see the structure of the cycle and which parameters passes, please see the example below, the only thing i calculate in placeCell is the angle which I should obtain directly inside tha called function

alt text

Note: the angle is reversed but it isn't important, and the color are useful in example only for visually divide cases.

My for cycle calls placeCell and passes cell, current_case, counter (index) and the honeycomb cell_lv (cell level).

I thought it was what i needed but I'm not skilled in geometry and trigonometry, so I don't know how to position cells correctly:

    import flash.display.Sprite;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

function createHoneycomb (cells:int):void {

    var honeycomb:Sprite = new Sprite ();
    addChild (honeycomb);

    var cell_lv:int = 1;
    var increment:int = 6;
    var tot_cur_cells:int = 1;

    var current_case:int = 0;
    var case_counter:int = 1;
    var case_length:int = 1;
    var max_cases:int = 6;

    var nucleus:Sprite = new cell (); // hexagon from library
    honeycomb.addChild (nucleus);

    for (var i:int = 1; i <= cells; i ++) {

        if (case_counter < case_length) {
            case_counter ++;
        } else {
            current_case ++;
            if (current_case > max_cases) current_case = 1;
            case_counter = 1;
        }

        if (i == tot_cur_cells) { // if i reach the current level
            if (i > 1) cell_lv ++;
            case_length = cell_lv;
            tot_cur_cells += (increment * cell_lv);
        }

        var current_cell:Sprite = new cell (); // hexagon from library
        honeycomb.addChild (current_cell);

        placeCell (current_cell, case_counter, current_case, cell_lv);

    }
    function centerHoneycomb (e:Event):void {
        honeycomb.x = stage.stageWidth / 2
        honeycomb.y = Math.round (stage.stageHeight / 2);
    }

    stage.addEventListener (Event.RESIZE, centerHoneycomb)
    stage.dispatchEvent (new Event (Event.RESIZE));
}

function placeCell (cell:Sprite, counter:int, current_case:int, cell_lv:int):void {
    var margin:int = 2;

    // THIS IS MY PROBLEM
    var start_degree:Number = (360 / (cell_lv * 6));
    var angle:Number = (start_degree * ((current_case - 1) + counter) - start_degree);
    var radius:Number = (cell.width + margin) * cell_lv;

    cell.x = radius * Math.cos (angle);
    cell.y = radius * Math.sin (angle);
    // end of the problem

    if (angle != 0) trace ("LV " + cell_lv + "  current_case " + current_case + "   counter " + counter + " angle " + angle + " radius " + radius);
    else trace ("LV " + cell_lv + " current_case " + current_case + "   counter " + counter + " angle " + angle + "     radius " + radius);
}

createHoneycomb (64);

if you copy and paste this code, it works but you need to create an hexagon and call it in the actionscript library as cell

how can I do to solve it?

I've also thought to use a switch with the cases to align it, but i think is a little bit buggy doing this

+2  A: 

Okay, I really loved this question. It was interesting, and challenging, and I got a working result. I didn't use any of your code as the base though, but started from scratch, so depending on your final use, you might need to change a bit.

I did however created similar variables to those inside of your cells (in the picture). For each cell you have the following properties:

  • the iterating variable i is equally to your cell number
  • the radius r equals your level, and expresses the distance from the center (with 0 being the center)
  • the position p expresses the position in the current radius
  • the sector s equals your case, but starts with zero
  • p % r equals your index

I don't have an angle, simply because I don't position the individual hexagons using an angle. Instead I base the position of the (fixed) positions of the hexagons at radius 1 and calculate the missing ones in between.

You can see a working example with 61 cells (60 + the center), and of course the full code on Wonderfl.

poke
You did it! your code it's great! thank you very much for what you've done, i'll change it a bit for what i need, but it's perfect!
Vittorio Vittori
Very nice :) Good job
Ladislav