Mercator  0.4.0
RandCache.h
1 // This file may be redistributed and modified only under the terms of
2 // the GNU General Public License (See COPYING for details).
3 // Copyright (C) 2004 Damien McGinnes, Ron Steinke, Alistair Riddoch
4 
5 #ifndef MERCATOR_RANDCACHE_H
6 #define MERCATOR_RANDCACHE_H
7 
8 #include <vector>
9 #include <algorithm>
10 #include <cstdlib>
11 #include <wfmath/MersenneTwister.h>
12 
13 // construct with something like:
14 // RandCache r(seed, new MyOrdering(args));
15 // where MyOrdering is derived from RandCache::Ordering.
16 
18 class RandCache
19 {
20  public:
22  typedef WFMath::MTRand::uint32 uint32;
24  typedef std::vector<uint32>::size_type size_type;
25 
27  struct Ordering {
28  virtual ~Ordering() {}
30  virtual size_type operator()(int x, int y) = 0;
31  };
32 
37  RandCache(uint32 seed, Ordering* o) :
38  m_rand(seed), m_ordering(o) {}
44  RandCache(uint32* seed, uint32 seed_len, Ordering* o) :
45  m_rand(seed, seed_len), m_ordering(o) {}
46  ~RandCache() {delete m_ordering;}
47 
52  double operator()(int x, int y)
53  {
54  size_type cache_order = (*m_ordering)(x, y);
55 
56  // make sure we've cached the value
57  if(cache_order >= m_cache.size()) {
58  size_type old_size = m_cache.size();
59  m_cache.resize(cache_order + 64); //do 64 at once
60  while(old_size < m_cache.size())
61  m_cache[old_size++] = m_rand.randInt();
62  }
63 
64  return double(m_cache[cache_order] * (1.0/4294967295.0));
65  }
66 
67  private:
69  WFMath::MTRand m_rand;
71  std::vector<uint32> m_cache;
73  Ordering* m_ordering;
74 };
75 
78 {
79 public:
81  {
82  if (x==0 && y==0) return 0;
83 
84  int d=std::max(std::abs(x), std::abs(y));
85  int min=(2*d-1)*(2*d-1);
86 
87  if (y == d) return min + 2*d - x;
88  if (x == -d) return min + 4*d - y;
89  if (y == -d) return min + 6*d + x;
90  else { //if (x == d) {
91  if (y >=0) return min + y;
92  else return min + 8*d + y;
93  }
94  }
95 };
96 
99 {
100 private:
102  int m_x;
104  int m_y;
105 public:
110  SpiralOrdering(int x, int y) : ZeroSpiralOrdering(), m_x(x), m_y(y) {}
112  {
113  return ZeroSpiralOrdering::operator()(x-m_x, y-m_y);
114  }
115 };
116 
117 
118 #endif
119 
120 
121 
A cache of random values.
Definition: RandCache.h:18
RandCache(uint32 seed, Ordering *o)
Constructor.
Definition: RandCache.h:37
RandCache(uint32 *seed, uint32 seed_len, Ordering *o)
Constructor.
Definition: RandCache.h:44
RandCache::size_type operator()(int x, int y)
Determine the order.
Definition: RandCache.h:80
A spiral around x,y.
Definition: RandCache.h:98
A spiral around 0,0.
Definition: RandCache.h:77
WFMath::MTRand::uint32 uint32
Unsigned 32bit integer.
Definition: RandCache.h:22
std::vector< uint32 >::size_type size_type
Size type of std::vector.
Definition: RandCache.h:24
double operator()(int x, int y)
Retrieve a random value associated with parameters.
Definition: RandCache.h:52
Interface to define the ordering of the random number cache.
Definition: RandCache.h:27
virtual size_type operator()(int x, int y)=0
Determine the order.
SpiralOrdering(int x, int y)
Constructor.
Definition: RandCache.h:110