Supports arbitrary areas and paths.
Classes | |
class | exception |
Base class for hex exceptions. More... | |
class | invalid_argument |
class | out_of_range |
struct | Point |
X-Y coordinate. More... | |
class | Grid |
A square field of hexagons that form the universe in which the other objects exist. More... | |
class | Edge |
The interface between a hex and one of its six neighbours. More... | |
class | Hex |
A single hexagonal quanta of area. More... | |
class | Area |
A connected set of hexes. More... | |
class | Path |
A sequence of adjacent hexes. More... | |
class | Boundary |
A sequence of adjacent edges. More... | |
Namespaces | |
namespace | move |
Find routes and movement horizons on a hex grid. | |
namespace | svg |
Output hex:: objects as Scalable Vector Graphics (SVG) - which you can easily convert to PNG or JPG. | |
Typedefs | |
typedef double | Distance |
Enumerations | |
enum | Direction { A = 0, B = 1, C = 2, D = 3, E = 4, F = 5 } |
The six directions are labelled A to F anti-clockwise. More... | |
Functions | |
void | go (int &i, int &j, Direction d, int distance=1) |
Translates coordinates i,j in direction d. | |
void | go (int &i, int &j, const std::string &steps) |
Translates coordinates i,j along steps. | |
std::string | steps (const Hex *from, const Hex *to) |
Calculates a minimum-length path between two hexes. | |
int | distance (const Hex *from, const Hex *to) |
The length of the shortest path between two hexes. | |
std::set< Hex * > | range (Hex *h, int distance) |
Calculates the set of hexes that are range r from hex h. | |
std::set< Hex * > | set_difference (const std::set< Hex * > &a, const std::set< Hex * > &b) |
The set difference between a and b. | |
std::set< Hex * > | set_intersection (const std::set< Hex * > &a, const std::set< Hex * > &b) |
The set intersection between a and b. | |
std::set< Hex * > | set_union (const std::set< Hex * > &a, const std::set< Hex * > &b) |
The set union between a and b. | |
std::string | set_str (const std::set< Hex * > &a) |
Generates a string representation of hex-set a. | |
bool | bounding_box (const std::set< Hex * > &a, int &i0, int &j0, int &i1, int &j1) |
Calculate a bounding box for hex-set a. | |
Area | fill (const std::set< Hex * > &beyond, Hex *h) |
Calc. | |
Area | fill (const std::set< Hex * > &beyond, const Area &a) |
Max. | |
std::set< Hex * > | extract_connected_set (std::set< Hex * > &s) |
Helper: Find the connected set (Area) that contains the first hex in s. | |
std::list< Area > | areas (const std::set< Hex * > &s) |
Find all of the Areas (connected sets) in s. | |
bool | is_connected (const std::set< Hex * > &s) |
TRUE iff s is connected. | |
std::list< Boundary > | skeleton (const std::list< Area > &a, bool include_boundary=true) |
The skeletons of areas a. | |
Direction | to_direction (char c) throw (hex::invalid_argument) |
char | to_char (Direction d) |
Direction & | operator+= (Direction &d, int i) |
Direction | operator+ (const Direction &d, int i) |
Direction & | operator++ (Direction &d) |
Prefix increment. | |
Direction | operator++ (const Direction &d, int) |
Postfix increment. | |
Direction & | operator-= (Direction &d, int i) |
Direction | operator- (const Direction &d, int i) |
Direction & | operator-- (Direction &d) |
Prefix decrement. | |
Direction | operator-- (const Direction &d, int) |
Postfix decrement. | |
std::ostream & | operator<< (std::ostream &os, const Direction &d) |
std::string | rotate (const std::string &steps, int i) |
steps is a string of characters A-F, representing a set of Directions. | |
Point | corner_offset (Point p, Direction d, float bias) |
Helper function. | |
std::list< Hex * > | path (Hex *start, const std::string &steps) throw (hex::out_of_range,hex::invalid_argument) |
Helper: populate _hexes from steps. | |
Variables | |
const Distance | M_SQRT3 = 1.73205080756887729352744634150587236 |
const Distance | I = 1.0 |
Distance between centres of adjacent hexes. | |
const Distance | J = M_SQRT3/2.0 |
Distance between adjacent hex rows. | |
const Distance | K = 1.0/M_SQRT3 |
Length of hex's edge. | |
const int | DIRECTIONS = 6 |
typedef double hex::Distance |
enum hex::Direction |
std::list< Area > hex::areas | ( | const std::set< Hex * > & | s | ) |
Find all of the Areas (connected sets) in s.
Definition at line 272 of file algorithm.cc.
References extract_connected_set().
Referenced by hex::Area::enclosed_areas().
00273 { 00274 std::set<Hex*> unallocated = s; 00275 std::list<Area> result; 00276 while(!unallocated.empty()) 00277 { 00278 result.push_back( extract_connected_set(unallocated) ); 00279 } 00280 return result; 00281 }
bool hex::bounding_box | ( | const std::set< Hex * > & | a, | |
int & | i0, | |||
int & | j0, | |||
int & | i1, | |||
int & | j1 | |||
) |
Calculate a bounding box for hex-set a.
Returns FALSE if a is empty.
Definition at line 196 of file algorithm.cc.
00197 { 00198 for(std::set<Hex*>::const_iterator h=a.begin(); h!=a.end(); ++h) 00199 { 00200 if(h==a.begin()) 00201 { 00202 i0 = i1 = (**h).i; 00203 j0 = j1 = (**h).j; 00204 } 00205 else 00206 { 00207 i0 = std::min(i0,(**h).i); 00208 j0 = std::min(j0,(**h).j); 00209 i1 = std::max(i1,(**h).i); 00210 j1 = std::max(j1,(**h).j); 00211 } 00212 } 00213 return !a.empty(); 00214 }
Point hex::corner_offset | ( | Point | p, | |
Direction | d, | |||
float | bias | |||
) |
Helper function.
Offsets p towards the start_point of edge d.
Definition at line 74 of file edge.cc.
References A, B, C, D, E, F, I, K, and hex::Point::offset().
Referenced by hex::Edge::join_point(), and hex::Edge::start_point().
00075 { 00076 Distance dx =0.0; 00077 Distance dy =0.0; 00078 switch(d) 00079 { 00080 case A: dx = I/2.0; dy = -K/2.0; break; 00081 case B: dx = I/2.0; dy = K/2.0; break; 00082 case C: dx = 0.0; dy = K ; break; 00083 case D: dx = -I/2.0; dy = K/2.0; break; 00084 case E: dx = -I/2.0; dy = -K/2.0; break; 00085 case F: dx = 0.0; dy = -K ; break; 00086 } 00087 if(bias==0.0) 00088 return p.offset(dx,dy); 00089 else 00090 return p.offset(dx*(1.0+bias),dy*(1.0+bias)); 00091 }
int hex::distance | ( | const Hex * | from, | |
const Hex * | to | |||
) |
The length of the shortest path between two hexes.
Definition at line 107 of file algorithm.cc.
References steps().
Referenced by hex::Area::go().
00108 { 00109 return steps(from,to).size(); 00110 }
std::set<Hex*> hex::extract_connected_set | ( | std::set< Hex * > & | s | ) | [inline] |
Helper: Find the connected set (Area) that contains the first hex in s.
Definition at line 249 of file algorithm.cc.
References range(), and set_intersection().
Referenced by areas(), and is_connected().
00250 { 00251 std::set<Hex*> result; 00252 std::set<Hex*> queue; // Hexes in result that have not yet been checked. 00253 Hex* h =*s.begin(); // Just pick a random hex in s. 00254 while(true) 00255 { 00256 result.insert(h); 00257 s.erase(h); 00258 if(s.empty()) 00259 break; // optimisation - not strictly necessary. 00260 std::set<Hex*> range1 =set_intersection( s, range(h,1) ); 00261 queue.insert( range1.begin(), range1.end() ); 00262 if(queue.empty()) 00263 break; 00264 h = *queue.begin(); 00265 queue.erase( queue.begin() ); 00266 } 00267 return result; 00268 }
Area hex::fill | ( | const std::set< Hex * > & | beyond, | |
const Area & | a | |||
) |
Max.
area that contains hexes in a, but does not intersect beyond.
Definition at line 225 of file algorithm.cc.
References A, DIRECTIONS, and hex::Area::hexes().
00226 { 00227 std::set<Hex*> queue =a.hexes(); 00228 std::set<Hex*> result =a.hexes(); 00229 while(!queue.empty()) 00230 { 00231 Hex* h = *queue.begin(); 00232 queue.erase( queue.begin() ); 00233 for(int d=0; d<DIRECTIONS; ++d) 00234 { 00235 Hex* hd =h->go(A+d); 00236 if(!beyond.count(hd) && !result.count(hd)) 00237 { 00238 queue.insert(hd); 00239 result.insert(hd); 00240 } 00241 } 00242 } 00243 return result; 00244 }
Area hex::fill | ( | const std::set< Hex * > & | beyond, | |
Hex * | h | |||
) |
Calc.
the max. area that contains h, but does not intersect beyond.
Definition at line 218 of file algorithm.cc.
Referenced by hex::Boundary::area().
00219 { 00220 return fill( beyond, Area(h) ); 00221 }
void hex::go | ( | int & | i, | |
int & | j, | |||
const std::string & | steps | |||
) |
Translates coordinates i,j along steps.
Definition at line 60 of file algorithm.cc.
References go(), and to_direction().
00061 { 00062 for(std::string::const_iterator s=steps.begin(); s!=steps.end(); ++s) 00063 if('A'<=*s && *s<='F') 00064 go(i,j,to_direction(*s)); 00065 else 00066 break; // Just bail out if we encounter a non-Direction character. 00067 }
void hex::go | ( | int & | i, | |
int & | j, | |||
Direction | d, | |||
int | distance = 1 | |||
) |
Translates coordinates i,j in direction d.
Definition at line 33 of file algorithm.cc.
References A, B, C, D, E, and F.
Referenced by hex::Hex::go(), go(), hex::Grid::hex(), range(), and steps().
00034 { 00035 for(; distance>0; --distance) 00036 if(j%2) 00037 switch(d) // odd 00038 { 00039 case A: ++i; break; 00040 case B: ++i; ++j; break; 00041 case C: ++j; break; 00042 case D: --i; break; 00043 case E: --j; break; 00044 case F: ++i; --j; break; 00045 } 00046 else 00047 switch(d) // even 00048 { 00049 case A: ++i; break; 00050 case B: ++j; break; 00051 case C: --i; ++j; break; 00052 case D: --i; break; 00053 case E: --i; --j; break; 00054 case F: --j; break; 00055 } 00056 }
bool hex::is_connected | ( | const std::set< Hex * > & | s | ) |
TRUE iff s is connected.
Definition at line 285 of file algorithm.cc.
References extract_connected_set().
Referenced by hex::Area::Area().
00286 { 00287 std::set<Hex*> unallocated = s; 00288 extract_connected_set( unallocated ); 00289 return unallocated.empty(); 00290 }
Direction hex::operator+ | ( | const Direction & | d, | |
int | i | |||
) |
Definition at line 54 of file direction.cc.
00055 { 00056 Direction result =d; 00057 result+=i; 00058 return result; 00059 }
Direction hex::operator++ | ( | const Direction & | d, | |
int | ||||
) |
Postfix increment.
Definition at line 68 of file direction.cc.
00069 { 00070 Direction result =d; 00071 ++result; 00072 return result; 00073 }
Direction & hex::operator++ | ( | Direction & | d | ) |
Direction & hex::operator+= | ( | Direction & | d, | |
int | i | |||
) |
Definition at line 44 of file direction.cc.
References DIRECTIONS.
00045 { 00046 int d_ =static_cast<int>( d ); 00047 d_= (d_+i) % DIRECTIONS; 00048 while(d_<0) 00049 d_ += DIRECTIONS; 00050 d=static_cast<Direction>( d_ ); 00051 return d; 00052 }
Direction hex::operator- | ( | const Direction & | d, | |
int | i | |||
) |
Direction hex::operator-- | ( | const Direction & | d, | |
int | ||||
) |
Postfix decrement.
Definition at line 92 of file direction.cc.
00093 { 00094 Direction result =d; 00095 --result; 00096 return result; 00097 }
Direction & hex::operator-- | ( | Direction & | d | ) |
Direction & hex::operator-= | ( | Direction & | d, | |
int | i | |||
) |
std::ostream & hex::operator<< | ( | std::ostream & | os, | |
const Direction & | d | |||
) |
Definition at line 99 of file direction.cc.
References to_char().
00100 { 00101 os << to_char(d); 00102 return os; 00103 }
std::list<Hex*> hex::path | ( | Hex * | start, | |
const std::string & | steps | |||
) | throw (hex::out_of_range,hex::invalid_argument) [inline] |
Helper: populate _hexes from steps.
Definition at line 74 of file path.cc.
References steps(), and to_direction().
Referenced by hex::Area::fillpaths().
00076 { 00077 // See also: go(int&,int&,const std::string&) 00078 std::list<Hex*> hexes; 00079 hexes.push_back(start); 00080 std::string::size_type cur =0; 00081 while(cur<steps.size() && steps[cur]!='?') 00082 { 00083 // Find direction 00084 Direction dir =to_direction( steps[cur] ); 00085 ++cur; 00086 bool repeat =(cur<steps.size() && steps[cur]=='*'); 00087 do{ 00088 Hex* next =hexes.back()->go( dir ); 00089 if(next) 00090 hexes.push_back( next ); 00091 else if(*steps.rbegin()=='?' || repeat) 00092 return hexes; // bail out instead of throwing 00093 else 00094 throw hex::out_of_range(start->str()+":"+steps); 00095 } while(repeat); 00096 } 00097 return hexes; 00098 }
std::set< Hex * > hex::range | ( | Hex * | h, | |
int | distance | |||
) |
Calculates the set of hexes that are range r from hex h.
The result may NOT be a valid Area, since it may be cut into several pieces by the edge of the grid.
Definition at line 114 of file algorithm.cc.
References A, C, DIRECTIONS, go(), hex::Hex::grid(), hex::Grid::hex(), hex::Hex::i, and hex::Hex::j.
Referenced by hex::Area::Area(), extract_connected_set(), and main().
00115 { 00116 std::set<Hex*> result; 00117 if(distance<1) 00118 { 00119 result.insert(h); 00120 } 00121 else 00122 { 00123 const Grid& grid =h->grid(); 00124 int i =h->i; 00125 int j =h->j; 00126 00127 try { 00128 go(i,j,hex::A,distance); // in/out: i,j 00129 result.insert( grid.hex(i,j) ); 00130 } catch(hex::out_of_range&) {} 00131 00132 for(int d=0; d<DIRECTIONS; ++d) 00133 { 00134 Direction direction =C+d; 00135 for(int count=0; count<distance; ++count) 00136 try { 00137 go(i,j,direction); // in/out: i,j 00138 result.insert( grid.hex(i,j) ); 00139 } catch(hex::out_of_range&) {} 00140 } 00141 } 00142 return result; 00143 }
std::string hex::rotate | ( | const std::string & | steps, | |
int | i | |||
) |
steps is a string of characters A-F, representing a set of Directions.
This function rotates each step by i.
Definition at line 106 of file direction.cc.
References to_char(), and to_direction().
00107 { 00108 // Rotate all letters A-F, but leave other characters alone. 00109 std::string result =steps; 00110 for(std::string::iterator c=result.begin(); c!=result.end(); ++c) 00111 if('A'<=*c && *c<='F') 00112 { 00113 Direction d =to_direction(*c); 00114 *c = to_char(d+i); 00115 } 00116 return result; 00117 }
std::set< Hex * > hex::set_difference | ( | const std::set< Hex * > & | a, | |
const std::set< Hex * > & | b | |||
) |
The set difference between a and b.
Definition at line 147 of file algorithm.cc.
Referenced by hex::Area::enclosed_areas().
00148 { 00149 std::set<Hex*> result; 00150 std::set_difference( 00151 a.begin(),a.end(), 00152 b.begin(),b.end(), 00153 std::inserter(result,result.end()) 00154 ); 00155 return result; 00156 }
std::set< Hex * > hex::set_intersection | ( | const std::set< Hex * > & | a, | |
const std::set< Hex * > & | b | |||
) |
The set intersection between a and b.
Definition at line 160 of file algorithm.cc.
Referenced by extract_connected_set().
00161 { 00162 std::set<Hex*> result; 00163 std::set_intersection( 00164 a.begin(),a.end(), 00165 b.begin(),b.end(), 00166 std::inserter(result,result.end()) 00167 ); 00168 return result; 00169 }
std::string hex::set_str | ( | const std::set< Hex * > & | a | ) |
Generates a string representation of hex-set a.
Definition at line 186 of file algorithm.cc.
00187 { 00188 std::ostringstream ss; 00189 for(std::set<Hex*>::const_iterator h=a.begin(); h!=a.end(); ++h) 00190 ss<<(**h).str()<<" "; 00191 return ss.str(); 00192 }
std::set< Hex * > hex::set_union | ( | const std::set< Hex * > & | a, | |
const std::set< Hex * > & | b | |||
) |
The set union between a and b.
Definition at line 173 of file algorithm.cc.
00174 { 00175 std::set<Hex*> result; 00176 std::set_union( 00177 a.begin(),a.end(), 00178 b.begin(),b.end(), 00179 std::inserter(result,result.end()) 00180 ); 00181 return result; 00182 }
std::list< Boundary > hex::skeleton | ( | const std::list< Area > & | a, | |
bool | include_boundary = true | |||
) |
The skeletons of areas a.
Definition at line 294 of file algorithm.cc.
00295 { 00296 std::list<Boundary> result; 00297 for(std::list<Area>::const_iterator iter=a.begin(); iter!=a.end(); ++iter) 00298 { 00299 std::list<Boundary> b =iter->skeleton(include_boundary); 00300 std::copy(b.begin(),b.end(),inserter(result,result.end())); 00301 } 00302 return result; 00303 }
std::string hex::steps | ( | const Hex * | from, | |
const Hex * | to | |||
) |
Calculates a minimum-length path between two hexes.
The result is one of many possible solutions.
Definition at line 71 of file algorithm.cc.
References A, B, C, D, E, F, go(), hex::Hex::i, hex::Hex::j, and to_char().
Referenced by hex::Grid::area(), distance(), hex::Area::go(), path(), hex::Path::steps(), and hex::Area::str().
00072 { 00073 std::string result =""; 00074 int i =from->i; 00075 int j =from->j; 00076 const int to_i =to->i; 00077 const int to_j =to->j; 00078 Direction direction; 00079 while(true) 00080 { 00081 if( j < to_j ) // go up 00082 { 00083 if( i < to_i ) direction = B; 00084 else if( i > to_i || j%2 ) direction = C; 00085 else direction = B; 00086 } 00087 else if( j > to_j ) // go down 00088 { 00089 if( i < to_i ) direction = F; 00090 else if( i > to_i || j%2 ) direction = E; 00091 else direction = F; 00092 } 00093 else // j == to_j // go across 00094 { 00095 if( i < to_i ) direction = A; 00096 else if( i > to_i ) direction = D; 00097 else break; // Done! 00098 } 00099 result += to_char(direction); 00100 go(i,j,direction); 00101 } 00102 return result; 00103 }
char hex::to_char | ( | Direction | d | ) |
Definition at line 37 of file direction.cc.
References A.
Referenced by operator<<(), rotate(), steps(), and hex::Boundary::str().
00038 { 00039 static const char root =static_cast<char>( A ); 00040 return static_cast<char>( 'A' + (static_cast<char>(d) - root) ); 00041 }
Direction hex::to_direction | ( | char | c | ) | throw (hex::invalid_argument) |
Definition at line 29 of file direction.cc.
References A.
Referenced by hex::Grid::boundary(), go(), path(), and rotate().
00030 { 00031 if(c<'A' || c>'F') 00032 throw hex::invalid_argument(std::string("to_direction:")+c); 00033 return A + static_cast<int>(c-'A'); 00034 }
const int hex::DIRECTIONS = 6 |
Definition at line 120 of file hex.h.
Referenced by hex::move::Topography::best_path(), fill(), hex::move::Topography::horizon(), hex::move::Topography::increase_hex_cost(), operator+=(), hex::move::Topography::override_hex_cost(), and range().
Distance between centres of adjacent hexes.
Definition at line 110 of file hex.h.
Referenced by hex::Hex::centre(), corner_offset(), and hex::Grid::width().
Distance between adjacent hex rows.
Definition at line 111 of file hex.h.
Referenced by hex::Hex::centre(), hex::Grid::height(), and hex::Grid::hex().
Length of hex's edge.
Definition at line 112 of file hex.h.
Referenced by hex::Hex::centre(), corner_offset(), hex::Grid::height(), and hex::Grid::hex().
const Distance hex::M_SQRT3 = 1.73205080756887729352744634150587236 |