hex Namespace Reference


Detailed Description

Library for manipulating hexagonal grids.

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< Areaareas (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< Boundaryskeleton (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)
Directionoperator+= (Direction &d, int i)
Direction operator+ (const Direction &d, int i)
Directionoperator++ (Direction &d)
 Prefix increment.
Direction operator++ (const Direction &d, int)
 Postfix increment.
Directionoperator-= (Direction &d, int i)
Direction operator- (const Direction &d, int i)
Directionoperator-- (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 Documentation

typedef double hex::Distance

Definition at line 107 of file hex.h.


Enumeration Type Documentation

enum hex::Direction

The six directions are labelled A to F anti-clockwise.

Direction 'A' is 'East' along the x-axis. 'B' is 'North-East' and so-on.

Enumerator:
A  --->
B 
C 
D  <---
E 
F 

Definition at line 119 of file hex.h.

00119 {  A=0, B=1, C=2,  D=3, E=4, F=5 };


Function Documentation

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  ) 

Prefix increment.

Definition at line 62 of file direction.cc.

00063 {
00064   return d+=1;
00065 }

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 
)

Definition at line 80 of file direction.cc.

00081 {
00082   return d + (-i);
00083 }

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  ) 

Prefix decrement.

Definition at line 86 of file direction.cc.

00087 {
00088   return d-=1;
00089 }

Direction & hex::operator-= ( Direction &  d,
int  i 
)

Definition at line 75 of file direction.cc.

00076 {
00077   return d += (-i);
00078 }

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 }


Variable Documentation

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().

const Distance hex::I = 1.0

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().

const Distance hex::J = M_SQRT3/2.0

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().

const Distance hex::K = 1.0/M_SQRT3

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

Definition at line 109 of file hex.h.


Generated on Thu Feb 21 00:00:55 2008 for libhex by  doxygen 1.5.1