Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Hexagonal coordinate.
- // Stores as 3d coordinate system.
- // Assuming our hexagon is x+y+z = 0; plane intersection of a cube & origin
- function displacement( dx, dy, dz ){
- return {
- dx:dx,
- dy:dy,
- dz:dz
- };
- }
- var neighbours = [
- displacement( 1, -1, 0),
- displacement( 1, 0, -1),
- displacement( 0, 1, -1),
- displacement( -1, 1, 0),
- displacement( -1, 0, 1),
- displacement( 0, -1, 1)
- ];
- var diagonals = [
- displacement( 2, -1, -1),
- displacement( 1, 1, -2),
- displacement( -1, 2, -1),
- displacement( -2, 1, 1),
- displacement( -1, -1, +2),
- displacement( 1, -2, 1)
- ];
- function coordinate( x, z ){
- this.x = x;
- this.z = z;
- this.y = -(x+z);
- this.toset = function(){
- return {x:x,
- z:z}
- }
- }
- //-----------------------------------------------------------------
- // Static Methods
- //-----------------------------------------------------------------
- // to round x,y,z given into the coordinate space
- coordinate.round = function( x, y, z ){
- var rx = Math.round( x ),
- ry = Math.round( y ),
- rz = Math.round( z ),
- x_err = Math.abs( rx - x ),
- y_err = Math.abs( ry - y ),
- z_err = Math.abs( rz - z );
- if(x_err > y_err && x_err > z_err){
- rx = -( ry + rz );
- }else if(y_err > z_err){
- ry = -( rx + rz );
- }else{
- rz = -( rx + ry );
- }
- return new coordinate( rx, rz );
- }
- // Are they equal
- coordinate.areEqual = function( coor1, coor2 ){
- if( !coor1 || !coor2 )
- return false;
- return coor1.x === coor2.x &&
- coor1.y === coor2.y &&
- coor1.z === coor2.z;
- }
- //-----------------------------------------------------------------
- // Prototyped Methods
- //-----------------------------------------------------------------
- // Is that same as i am ?
- coordinate.prototype.equal = function( coor2 ){
- return coordinate.areEqual( this, coor2 );
- }
- // Gets neighbour coordinate from coordinate,
- coordinate.prototype.getNeighbour = function ( dir, len ){
- len = len || 1;
- var disp = neighbours[dir];
- return new coordinate(
- this.x + disp.dx * len,
- this.y + disp.dy * len,
- this.z + disp.dz * len);
- }
- // Gets getDiagonal coordinate from coordinate
- coordinate.prototype.getDiagonal = function ( dir, len ){
- len = len || 1;
- var disp = diagonals[dir];
- disp.dx *= len;
- disp.dy *= len;
- disp.dz *= len;
- return new coordinate(
- this.x + disp.dx,
- this.y + disp.dy,
- this.z + disp.dz
- );
- }
- //Computes distance from a point.
- //We can do /2 method but i prefer this
- //Makes more sense.
- coordinate.prototype.distanceFrom = function( coor2 ){
- return Math.max( Math.abs( this.x - coor2.x ),
- Math.abs( this.y - coor2.y ),
- Math.abs( this.z - coor2.z ) );
- }
- // Returns a set of points
- coordinate.prototype.lineTo = function( coor2 ){
- if( this.equal( coor2 ) )
- return [];
- var change = new displacement(
- coor2.x - this.x,
- coor2.y - this.y,
- coor2.z - this.z
- ),
- N = Math.max( change.dx, change.dy, change.dz ),
- fraction = 0,
- complement = 0,x,y,z,
- result = [],
- prev = null,p;
- for( var i = 0; i <= N; i++ ){
- // Ah fuck this is insanely stupid but oh well
- // TODO: find a better idea.
- fraction = i/N;
- complement = 1-fraction;
- x = this.x * fraction + coor2.x * complement;
- y = this.y * fraction + coor2.y * complement;
- z = this.z * fraction + coor2.z * complement;
- p = coordinate.round( x, y, z );
- if( !coordinate.areEqual( p, prev ) ){
- result.push( p );
- prev = p;
- }
- }
- result = result.reverse();
- return result;
- }
- // Ring at distance Radius from hex-coordinate
- coordinate.prototype.ring = function( Radius ){
- var result = [];
- // Get first point on ring.
- var temp = this.getNeighbour(4,Radius);
- for( var i = 0; i < 6; i ++ ){
- for( var j = 0; j < Radius; j++ ){
- result.push(temp);
- temp = temp.getNeighbour(i);
- }
- }
- return result;
- };
- // Gives a region from innerRadius to outerRadius
- // For complete region omit the second parameter
- coordinate.prototype.region = function(outerRadius,innerRadius){
- innerRadius = innerRadius || 0;
- var result = [],ring=null;
- for( Radius = innerRadius; Radius <= outerRadius; Radius++ ){
- ring = this.ring(Radius);
- ring.forEach(function(element){
- result.push(element);
- });
- }
- return result;
- }
- // Some helpers for representation amongst different ways to represent this data
- // Though this should goto coordinate_utils.js
- coordinate.prototype.toAxial = function(){
- return {
- q:this.x,
- r:this.z
- };
- };
- coordinate.prototype.fromAxial = function( q, r ){
- this.x = q;
- this.z = r;
- this.y = -(x+z);
- };
- coordinate.prototype.toEvenQoffset = function(){
- return {
- q: x,
- r: z + (x + x&1)/2
- }
- };
- coordinate.prototype.fromEvenQoffset = function( q, r ){
- this.x = q;
- this.z = r - (q + q&1)/2;
- this.y = -(x+z);
- };
- coordinate.prototype.toOddQoffset = function(){
- return {
- q: x,
- r: z + (x - x&1)/2
- }
- };
- coordinate.prototype.fromOddQoffset = function( q, r ){
- this.x = q;
- this.z = r - (q - q&1)/2;
- this.y = -(x+z);
- };
- coordinate.prototype.toEvenRoffset = function(){
- return {
- q: x + (z + z&1)/2,
- r: z
- }
- };
- coordinate.prototype.fromEvenRoffset = function( q, r ){
- this.x = q - (r + r&1)/2;
- this.z = r;
- this.y = -(x+z);
- };
- coordinate.prototype.toOddRoffset = function(){
- return {
- q: x + (x - x&1)/2,
- r: z
- }
- };
- coordinate.prototype.fromOddRoffset = function( q, r ){
- this.x = q - (r - r&1)/2;
- this.z = r;
- this.y = -(x+z);
- };
- // Export for Node
- module.exports = coordinate;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement