【问题标题】:Drawing an honeycomb with as3用 as3 画一个蜂窝
【发布时间】:2010-05-22 10:29:58
【问题描述】:

我正在尝试使用as3 创建一个honeycomb,但我在单元格定位方面遇到了一些问题。

我已经创建了单元格(不是使用代码)和for cycled 将它们发送到funcion 并将我认为需要的参数发送给它(蜂窝单元格已经在中心的精灵容器上舞台)。

要查看循环的结构和传递的参数,请参见下面的示例,我在placeCell 中计算的唯一内容是我应该直接在名为function 的内部获得的角度

alt text http://img293.imageshack.us/img293/1064/honeycomb.png

注意:角度是颠倒的,但这并不重要,并且颜色在示例中仅用于视觉划分案例。

我的循环调用placeCell 并传递cellcurrent_casecounter(索引)和蜂窝cell_lv(单元级别)。

我认为这是我需要的,但我不擅长几何学和三角学,所以我不知道如何正确定位单元格:

    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);

如果您复制并粘贴此代码,it works您需要创建一个六边形并将其作为单元格在 actionscript 库中调用

我该如何解决?

我也想过用开关和箱子来对齐,但我觉得这样做有点麻烦

【问题讨论】:

  • 把cell()的代码也放上去,有趣的问题,希望能帮到你...
  • “我已经创建了单元格(不是使用代码)”.. 他将其创建为库中的资产,可能使用多边形工具。

标签: actionscript-3 geometry


【解决方案1】:

好的,我真的很喜欢这个问题。这很有趣,也很有挑战性,我得到了一个有效的结果。虽然我没有使用您的任何代码作为基础,而是从头开始,因此根据您的最终用途,您可能需要进行一些更改。

但是,我确实创建了与您的单元格内部的变量类似的变量(在图片中)。对于每个单元格,您都有以下属性:

  • 迭代变量i 等于您的单元格编号
  • 半径r等于你的level,表示到中心的距离(0是中心)
  • 位置p表示当前半径内的位置
  • sectors 等于您的case,但从零开始
  • p % r 等于您的索引

我没有角度,只是因为我没有使用角度来定位单个六边形。相反,我将六边形的(固定)位置的位置基于半径 1 并计算其间缺失的位置。

以下代码显示了我的 61 实现(60 + 中心;但它是可配置的)。您还可以Wonderfl上查看代码

package
{
    import flash.display.Sprite;

    public class Comb extends Sprite
    {
        public function Comb ()
        {
            Hexagon.scale = 0.5;
            this.x = stage.stageWidth / 2;
            this.y = stage.stageHeight / 2;

            // draw honeycomb with 60 cells
            drawComb( 60 );
        }

        private function drawComb ( n:uint ):void
        {
            var colors:Array = new Array( 0x33CC33, 0x006699, 0xCC3300, 0x663399, 0xFF9900, 0x336666 );
            var sectors:Array = new Array(
                new Array( 2, 0 ),
                new Array( 1, 1 ),
                new Array( -1, 1 ),
                new Array( -2, 0 ),
                new Array( -1, -1 ),
                new Array( 1, -1 ) );

            var w:Number = 0.50 * Hexagon.hxWidth;
            var h:Number = 0.75 * Hexagon.hxHeight;
            var r:uint, p:uint, s:uint;
            var hx:Hexagon;

            for ( var i:uint = 0; i <= n; i++ )
            {
                r = getRadius( i );
                p = getPosition( i, r );
                s = getSector( i, r, p );

                // create hexagon
                if ( r == 0 )
                    hx = new Hexagon( 0xCCCCCC );
                else
                    hx = new Hexagon( colors[s] );

                hx.x = w * ( r * sectors[s][0] - ( p % r ) * ( sectors[s][0] - sectors[ ( s + 1 ) % 6 ][0] ) );
                hx.y = h * ( r * sectors[s][1] - ( p % r ) * ( sectors[s][1] - sectors[ ( s + 1 ) % 6 ][1] ) );
                addChild( hx );
            }
        }

        private function getRadius ( i:uint ):uint
        {
            var r:uint = 0;
            while ( i > r * 6 )
                i -= r++ * 6;
            return r;
        }

        private function getPosition ( i:uint, r:uint ):uint
        {
            if ( r == 0 )
                return i;
            while ( r-- > 0 )
                i -= r * 6;
            return i - 1;
        }

        private function getSector ( i:uint, r:uint, s:uint ):uint
        {
            return Math.floor( s / r );
        }
    }
}

import flash.display.Shape;

class Hexagon extends Shape
{
    public static var hxWidth:Number = 90;
    public static var hxHeight:Number = 100;

    private static var _scale:Number = 1;

    public function Hexagon ( color:uint )
    {
        graphics.beginFill( color );
        graphics.lineStyle( 3, 0xFFFFFF );
        graphics.moveTo(   0, -50 );
        graphics.lineTo(  45, -25 );
        graphics.lineTo(  45,  25 );
        graphics.lineTo(   0,  50 ),
        graphics.lineTo( -45,  25 );
        graphics.lineTo( -45, -25 );
        graphics.lineTo(   0, -50 );

        this.scaleX = this.scaleY = _scale;
    }

    public static function set scale ( value:Number ):void
    {
        _scale = value;
        hxWidth = value * 90;
        hxHeight = value * 100;
    }

    public static function get scale ():Number
    {
        return _scale;
    }
}

【讨论】:

  • 你做到了!你的代码很棒!非常感谢您所做的一切,我会根据需要对其进行一些更改,但它很完美!
猜你喜欢
  • 2014-11-01
  • 2020-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
  • 2020-03-09
相关资源
最近更新 更多