Advertisement
Guest User

hexGrid.js

a guest
Jun 5th, 2013
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. // Hexagonal coordinate.
  3. // Stores as 3d coordinate system.
  4. // Assuming our hexagon is x+y+z = 0; plane intersection of a cube & origin
  5.  
  6. function displacement( dx, dy, dz ){
  7.     return {
  8.         dx:dx,
  9.         dy:dy,
  10.         dz:dz
  11.     };
  12. }
  13.  
  14.  
  15. var neighbours = [
  16.     displacement(  1, -1,  0),
  17.     displacement(  1,  0, -1),
  18.     displacement(  0,  1, -1),
  19.     displacement( -1,  1,  0),
  20.     displacement( -1,  0,  1),
  21.     displacement(  0, -1,  1)
  22. ];
  23.  
  24. var diagonals = [
  25.     displacement(  2, -1, -1),
  26.     displacement(  1,  1, -2),
  27.     displacement( -1,  2, -1),
  28.     displacement( -2,  1,  1),
  29.     displacement( -1, -1, +2),
  30.     displacement(  1, -2,  1)
  31. ];
  32.  
  33. function coordinate( x, z ){
  34.     this.x = x;
  35.     this.z = z;
  36.     this.y = -(x+z);
  37.     this.toset = function(){
  38.         return {x:x,
  39.                 z:z}
  40.     }
  41. }
  42.  
  43. //-----------------------------------------------------------------
  44. // Static Methods
  45. //-----------------------------------------------------------------
  46. // to round x,y,z given into the coordinate space
  47. coordinate.round = function( x, y, z ){
  48.  
  49.     var rx = Math.round( x ),
  50.         ry = Math.round( y ),
  51.         rz = Math.round( z ),
  52.         x_err = Math.abs( rx - x ),
  53.         y_err = Math.abs( ry - y ),
  54.         z_err = Math.abs( rz - z );
  55.  
  56.     if(x_err > y_err && x_err > z_err){
  57.         rx = -( ry + rz );
  58.     }else if(y_err > z_err){
  59.         ry = -( rx + rz );
  60.     }else{
  61.         rz = -( rx + ry );
  62.     }
  63.  
  64.     return new coordinate( rx, rz );
  65. }
  66.  
  67. // Are they equal
  68. coordinate.areEqual = function( coor1, coor2 ){
  69.     if( !coor1 || !coor2 )
  70.         return false;
  71.  
  72.     return  coor1.x === coor2.x &&
  73.             coor1.y === coor2.y &&
  74.             coor1.z === coor2.z;
  75. }
  76.  
  77. //-----------------------------------------------------------------
  78. // Prototyped Methods
  79. //-----------------------------------------------------------------
  80. // Is that same as i am ?
  81. coordinate.prototype.equal = function( coor2 ){
  82.     return coordinate.areEqual( this, coor2 );
  83. }
  84. // Gets neighbour coordinate from coordinate,
  85. coordinate.prototype.getNeighbour =  function ( dir, len ){
  86.     len = len || 1;
  87.     var disp = neighbours[dir];
  88.     return new coordinate(
  89.         this.x + disp.dx * len,
  90.         this.y + disp.dy * len,
  91.         this.z + disp.dz * len);
  92. }
  93.  
  94. // Gets getDiagonal coordinate from coordinate
  95. coordinate.prototype.getDiagonal = function ( dir, len ){
  96.  
  97.     len = len || 1;
  98.     var disp  = diagonals[dir];
  99.    
  100.     disp.dx *= len;
  101.     disp.dy *= len;
  102.     disp.dz *= len;
  103.  
  104.     return new coordinate(
  105.         this.x + disp.dx,
  106.         this.y + disp.dy,
  107.         this.z + disp.dz
  108.     );
  109. }
  110.  
  111. //Computes distance from a point.
  112. //We can do /2 method but i prefer this
  113. //Makes more sense.
  114. coordinate.prototype.distanceFrom = function( coor2 ){
  115.     return Math.max( Math.abs( this.x - coor2.x ),
  116.                      Math.abs( this.y - coor2.y ),
  117.                      Math.abs( this.z - coor2.z ) );
  118. }
  119.  
  120. // Returns a set of points
  121. coordinate.prototype.lineTo = function( coor2 ){
  122.     if( this.equal( coor2 ) )
  123.         return [];
  124.     var change = new displacement(
  125.         coor2.x - this.x,
  126.         coor2.y - this.y,
  127.         coor2.z - this.z
  128.     ),
  129.     N = Math.max( change.dx, change.dy, change.dz ),
  130.     fraction = 0,
  131.     complement = 0,x,y,z,
  132.     result = [],
  133.     prev = null,p;
  134.     for( var i = 0; i <= N; i++ ){ 
  135.         // Ah fuck this is insanely stupid but oh well
  136.         // TODO: find a better idea.
  137.         fraction = i/N;
  138.         complement = 1-fraction;
  139.         x = this.x * fraction + coor2.x * complement;
  140.         y = this.y * fraction + coor2.y * complement;
  141.         z = this.z * fraction + coor2.z * complement;
  142.         p = coordinate.round( x, y, z );
  143.         if( !coordinate.areEqual( p, prev ) ){
  144.             result.push( p );
  145.             prev = p;
  146.         }
  147.     }
  148.     result = result.reverse();
  149.     return result;
  150. }
  151.  
  152. // Ring at distance Radius from hex-coordinate
  153. coordinate.prototype.ring = function( Radius ){
  154.     var result = [];
  155.     // Get first point on ring.
  156.     var temp = this.getNeighbour(4,Radius);
  157.     for( var i = 0; i < 6; i ++ ){
  158.         for( var j = 0; j < Radius; j++ ){
  159.             result.push(temp);
  160.             temp = temp.getNeighbour(i);
  161.         }
  162.     }
  163.     return result;
  164. };
  165.  
  166.  
  167. // Gives a region from innerRadius to outerRadius
  168. // For complete region omit the second parameter
  169. coordinate.prototype.region = function(outerRadius,innerRadius){
  170.     innerRadius = innerRadius || 0;
  171.     var result = [],ring=null;
  172.     for( Radius = innerRadius; Radius <= outerRadius; Radius++ ){
  173.         ring = this.ring(Radius);
  174.         ring.forEach(function(element){
  175.             result.push(element);
  176.         });
  177.     }
  178.     return result;
  179. }
  180.  
  181.  
  182.  
  183. // Some helpers for representation amongst different ways to represent this data
  184. // Though this should goto coordinate_utils.js
  185. coordinate.prototype.toAxial = function(){
  186.     return {
  187.         q:this.x,
  188.         r:this.z
  189.     };
  190. };
  191.  
  192. coordinate.prototype.fromAxial = function( q, r ){
  193.     this.x = q;
  194.     this.z = r;
  195.     this.y = -(x+z);
  196. };
  197.  
  198. coordinate.prototype.toEvenQoffset = function(){
  199.     return {
  200.         q: x,
  201.         r: z + (x + x&1)/2
  202.     }
  203. };
  204.  
  205. coordinate.prototype.fromEvenQoffset = function( q, r ){
  206.     this.x = q;
  207.     this.z = r - (q + q&1)/2;
  208.     this.y = -(x+z);
  209. };
  210.  
  211. coordinate.prototype.toOddQoffset = function(){
  212.     return {
  213.         q: x,
  214.         r: z + (x - x&1)/2
  215.     }
  216. };
  217.  
  218. coordinate.prototype.fromOddQoffset = function( q, r ){
  219.     this.x = q;
  220.     this.z = r - (q - q&1)/2;
  221.     this.y = -(x+z);
  222. };
  223.  
  224.  
  225. coordinate.prototype.toEvenRoffset = function(){
  226.     return {
  227.         q: x + (z + z&1)/2,
  228.         r: z
  229.     }
  230. };
  231.  
  232. coordinate.prototype.fromEvenRoffset = function( q, r ){
  233.     this.x = q - (r + r&1)/2;
  234.     this.z = r;
  235.     this.y = -(x+z);
  236. };
  237.  
  238. coordinate.prototype.toOddRoffset = function(){
  239.     return {
  240.         q: x + (x - x&1)/2,
  241.         r: z
  242.     }
  243. };
  244.  
  245. coordinate.prototype.fromOddRoffset = function( q, r ){
  246.     this.x = q - (r - r&1)/2;
  247.     this.z = r;
  248.     this.y = -(x+z);
  249. };
  250.  
  251. // Export for Node
  252. module.exports = coordinate;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement