SHOW:
|
|
- or go back to the newest paste.
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 | - | function displacement(dx,dy,dz){ |
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 | - | function coordinate(x,z){ |
32 | + | |
33 | function coordinate( x, z ){ | |
34 | this.x = x; | |
35 | this.z = z; | |
36 | this.y = -(x+z); | |
37 | - | return {x:x,z:z} |
37 | + | |
38 | return {x:x, | |
39 | z:z} | |
40 | } | |
41 | } | |
42 | - | coordinate.round = function(x,y,z){ |
42 | + | |
43 | //----------------------------------------------------------------- | |
44 | - | var rx = Math.round(x), |
44 | + | |
45 | - | ry = Math.round(y), |
45 | + | //----------------------------------------------------------------- |
46 | - | rz = Math.round(z), |
46 | + | |
47 | - | x_err = Math.abs(rx-x), |
47 | + | coordinate.round = function( x, y, z ){ |
48 | - | y_err = Math.abs(ry-y), |
48 | + | |
49 | - | z_err = Math.abs(rz-z); |
49 | + | var rx = Math.round( x ), |
50 | ry = Math.round( y ), | |
51 | rz = Math.round( z ), | |
52 | - | rx = -(ry+rz); |
52 | + | x_err = Math.abs( rx - x ), |
53 | y_err = Math.abs( ry - y ), | |
54 | - | ry = -(rx+rz); |
54 | + | z_err = Math.abs( rz - z ); |
55 | ||
56 | - | rz = -(rx+ry); |
56 | + | |
57 | rx = -( ry + rz ); | |
58 | }else if(y_err > z_err){ | |
59 | - | return new Coordinate(rx,rz); |
59 | + | ry = -( rx + rz ); |
60 | }else{ | |
61 | rz = -( rx + ry ); | |
62 | } | |
63 | - | coordinate.areEqual = function(coor1,coor2){ |
63 | + | |
64 | - | if( !!coor1 || !!coor2 ) |
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 | - | coordinate.prototype.equal = function(coor2){ |
72 | + | |
73 | - | return coordinate.areEqual(this,coor2); |
73 | + | |
74 | coor1.z === coor2.z; | |
75 | } | |
76 | - | coordinate.prototype.getNeighbour = function ( dir ){ |
76 | + | |
77 | //----------------------------------------------------------------- | |
78 | // Prototyped Methods | |
79 | //----------------------------------------------------------------- | |
80 | // Is that same as i am ? | |
81 | - | this.z + disp.dz ); |
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 | - | return Math.max( Math.abs(this.x - coor2.x), |
105 | + | |
106 | - | Math.abs(this.y - coor2.y), |
106 | + | |
107 | - | Math.abs(this.z - coor2.z) ); |
107 | + | |
108 | ); | |
109 | } | |
110 | ||
111 | - | if( this.equal(coor2) ) |
111 | + | |
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 | - | N = Math.max(change.dx,change.dy,change.dz), |
118 | + | |
119 | ||
120 | // Returns a set of points | |
121 | coordinate.prototype.lineTo = function( coor2 ){ | |
122 | if( this.equal( coor2 ) ) | |
123 | return []; | |
124 | - | for(var i = 0; i <= N; i++ ){ |
124 | + | |
125 | coor2.x - this.x, | |
126 | coor2.y - this.y, | |
127 | coor2.z - this.z | |
128 | ), | |
129 | - | x = this.x * fraction + coor2 * complement; |
129 | + | N = Math.max( change.dx, change.dy, change.dz ), |
130 | - | y = this.x * fraction + coor2 * complement; |
130 | + | |
131 | - | z = this.x * fraction + coor2 * complement; |
131 | + | |
132 | - | p = coordinate.round(); |
132 | + | |
133 | - | if( !coordinate.areEqual(p,prev) ){ |
133 | + | |
134 | - | result.push(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 | - | coordinate.prototype.fromAxial = function( q, r ) { |
149 | + | |
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 | - | coordinate.prototype.fromEvenQoffset = function( q, r ) { |
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 | - | coordinate.prototype.fromOddQoffset = function( q, r ) { |
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 | - | coordinate.prototype.fromEvenRoffset = function( q, r ) { |
189 | + | |
190 | }; | |
191 | ||
192 | coordinate.prototype.fromAxial = function( q, r ){ | |
193 | this.x = q; | |
194 | this.z = r; | |
195 | - | coordinate.prototype.toOddRoffset = function() { |
195 | + | |
196 | }; | |
197 | ||
198 | coordinate.prototype.toEvenQoffset = function(){ | |
199 | return { | |
200 | q: x, | |
201 | r: z + (x + x&1)/2 | |
202 | - | coordinate.prototype.fromOddRoffset = function( q, r ) { |
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; |