Hexagonal Gird - still fixing...
This is a new approach to store hexagonal gird as a tree node. Each hex have 3 coordinates x,y & z. The sum of all the coordinates must equal to zero (x+y+z=0).
To populate the gird I used a recursive function that will call itself twice until it had reached the required radius/size
-----
Resources:
http://www.researchgate.net/publication/2883527_A_Coordinate_System_for_Hexagonal_Pixels/file/72e7e5227851201cc4.pdf
http://www.redblobgames.com/grids/hexagons/#hex-to-pixel
http://devmag.org.za/2013/08/31/geometry-with-hex-coordinates/
/**
* Copyright WLAD ( http://wonderfl.net/user/WLAD )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/aVG7
*/
package
{
import flash.display.Shape;
import flash.display.Sprite;
public class FlashTest extends Sprite
{
private var gird:Gird;
private var convas:Sprite;
public function FlashTest()
{
// write as3 code here..
var sx:Number = stage.stageWidth / 2;
var sy:Number = stage.stageHeight / 2;
gird = new Gird(20);
convas = new Sprite();
convas.graphics.lineStyle(3, 0xFF0000, 0.5);
convas.x = sx;
convas.y = sy;
addChild(convas);
gird.draw(convas, 3);
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;
class Hexagon
{
private var _x:int;
private var _y:int;
private var _z:int;
public var neighbors:Vector.<Hexagon>;
public function Hexagon(x:int = 0, y:int = 0, z:int = 0)
{
_x = x;
_y = y;
_z = z;
neighbors = new Vector.<Hexagon>();
}
public function connect(neighbor:Hexagon):void
{
neighbors.push(neighbor);
}
public function add( h:Hexagon ):void
{
_x += h.x;
_y += h.y;
_z += h.z;
}
public function clone():Hexagon
{
return new Hexagon( _x, _y, _z );
}
public function get x():int
{
return _x;
}
public function set x(value:int):void
{
_x = value;
}
public function get y():int
{
return _y;
}
public function set y(value:int):void
{
_y = value;
}
public function get z():int {return _z;}
public function set z(value:int):void
{
_z = value;
}
}
class Gird
{
private var _flat:Boolean;
private var _size:Number = 0;
public function Gird(size:Number, flat:Boolean = true)
{
_flat = flat;
_size = size;
}
private var _width:Number = 0;public function get width():Number
{
if (_width == 0)
_width = _flat ? _size * 2 : 0;
return _width;
}
private var _height:Number = 0;public function get height():Number
{
if (_height == 0)
_height = _flat ? Math.sqrt(3) / 2 * width : 0;
return _width;
}
private var _distH:Number = 0;public function get distH():Number
{
if (_distH == 0)
_distH = _flat ? 3 / 4 * width : 0;
return _distH;
}
private var _distV:Number = 0;public function get distV():Number
{
if (_distV == 0)
_distV = _flat ? height : 0;
return _distV;
}
public function draw(s:Sprite, radius:uint):void
{
/// Zero
var origin:Hexagon = new Hexagon();
drawHexagon( s, origin );
var drawOnNewHex:Function =
function( h:Hexagon ):void {
drawHexagon( s, h );
};
// Populate the X axis
populate( 2, radius, origin, drawOnNewHex );
// Populate the Y axis
populate( 4, radius, origin, drawOnNewHex );
// Populate the Z axis
populate( 6, radius, origin, drawOnNewHex );
}
public function populate( direction:uint, ttl:int = 1, origin:Hexagon = null, onNew:Function = null):void //, populateLeft:int = 1, populateRight:int = 0):void
{
// Prevent stack overflow
if ( ttl <= 0 ) return;
var o:Hexagon = origin.clone();
o.add( this.direction( direction ) );
//o.connect( origin );
//if( leftConnect ) if( o is most left ) o.connect( leftConnect )
if ( onNew != null ) onNew( o );
populate( direction, ttl - 1, o, onNew);
// if( populateLeft > 0 ) ...
o = origin.clone();
o.add( this.direction( direction - 1 ) );
if ( onNew != null ) onNew( o );
populate( direction - 1, ttl - 1, o, onNew);
}
public function hex2cartesian( h:Hexagon ):Point
{
var p:Point = new Point();
p.x = (h.x + h.y / 2) * (_size * 3/2);
p.y = (Math.sqrt(3) * h.y / 2 ) * distV;
// convert cube to axial
//http://www.redblobgames.com/grids/hexagons/#neighbors
var q:int = h.x;
var r:int = h.z + (h.x + ( h.x & 1 ) ) / 2;
//http://www.redblobgames.com/grids/hexagons/#hex-to-pixel
p.x = _size * 3/2 * q
p.y = _size * Math.sqrt( 3 ) * ( r + q / 2 )
//p.x = width * h.x;
//p.y = _size * h.x + ( -2 + _size ) * h.y;
//p.y = ( 2 * h.x - 1 * h.y ) * ( Math.sqrt( 3 ) * 1 );
//p.y = 0;
return p;
}
public function direction(dir:uint):Hexagon
{
while ( dir > 5 ) dir -= 6; while ( dir < 0 ) dir += 6;
switch( dir )
{
case 0: return new Hexagon( 0, -1, 1 ); break;
case 1: return new Hexagon( 1, -1, 0 ); break;
case 2: return new Hexagon( 1, 0, -1 ); break;
case 3: return new Hexagon( 0, 1, -1 ); break;
case 4: return new Hexagon( -1, 1, 0 ); break;
case 5: return new Hexagon( -1, 0, 1 ); break;
}
// imposible return
return null;
}
private function drawHexagon(s:Sprite, h:Hexagon):void
{
var p:Point = hex2cartesian( h );
//p.x = h.x * distH;
//var y:Number =
var t:T = new T( h.x + "," + h.y + "," + h.z , p.x, p.y );
s.addChild( t );
//s.graphics.drawCircle(p.x, p.y, 2);
var v:Vec = new Vec(_size, 0);
var a:Number = Math.PI / 3;
s.graphics.moveTo(p.x + v.x, p.y + v.y);
var n:int = 6;
while (n-- > 0)
{
v.radians += a;
s.graphics.lineTo(p.x + v.x, p.y + v.y);
}
}
}
class Vec
{
/**
* @author http://wonderfl.net/user/Vladik
*/
public var x:Number, y:Number;
public function Vec(x:Number = 0, y:Number = 0)
{
this.x = x;
this.y = y;
}
public function get lenght():Number
{
return Math.sqrt(x * x + y * y);
}
public function set lenght(value:Number):void
{
if (lenght == 0)
scale(0);
else
scale(value / lenght);
}
public function set degrees(value:Number):void
{
radians = value * Math.PI / 180;
}
public function get degrees():Number
{
return radians * 180 / Math.PI;
}
public function set radians(value:Number):void
{
var f:Number = lenght;
x = Math.cos(value) * f;
y = Math.sin(value) * f;
}
public function scale(n:Number):void
{
x *= n;
y *= n;
}
public function get radians():Number
{
return Math.atan2(y, x);
}
}
class T extends TextField
{
public function T(txt:String = "Text", x:Number = 0, y:Number = 0)
{
var tf:TextFormat = new TextFormat("_sans", 12, 0x000000);
this.setTextFormat(tf);
this.defaultTextFormat = tf;
this.autoSize = 'left';
this.text = txt;
this.selectable = this.wordWrap = this.multiline = this.mouseEnabled = false;
this.x = x - this.width / 2;
this.y = y - this.height / 2;
}
}