Mercator
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 <cstdlib>
10 #include <wfmath/MersenneTwister.h>
11 
12 // construct with something like:
13 // RandCache r(seed, new MyOrdering(args));
14 // where MyOrdering is derived from RandCache::Ordering.
15 
17 class RandCache
18 {
19  public:
21  typedef WFMath::MTRand::uint32 uint32;
23  typedef std::vector<uint32>::size_type size_type;
24 
26  struct Ordering {
27  virtual ~Ordering() {}
29  virtual size_type operator()(int x, int y) = 0;
30  };
31 
37  m_rand(seed), m_ordering(o) {}
43  RandCache(uint32* seed, uint32 seed_len, Ordering* o) :
44  m_rand(seed, seed_len), m_ordering(o) {}
45  ~RandCache() {delete m_ordering;}
46 
51  double operator()(int x, int y)
52  {
53  size_type cache_order = (*m_ordering)(x, y);
54 
55  // make sure we've cached the value
56  if(cache_order >= m_cache.size()) {
57  size_type old_size = m_cache.size();
58  m_cache.resize(cache_order + 64); //do 64 at once
59  while(old_size < m_cache.size())
60  m_cache[old_size++] = m_rand.randInt();
61  }
62 
63  return double(m_cache[cache_order] * (1.0/4294967295.0));
64  }
65 
66  private:
68  WFMath::MTRand m_rand;
70  std::vector<uint32> m_cache;
73 };
74 
77 {
78 public:
80  {
81  if (x==0 && y==0) return 0;
82 
83  int d=std::max(std::abs(x), std::abs(y));
84  int min=(2*d-1)*(2*d-1);
85 
86  if (y == d) return min + 2*d - x;
87  if (x == -d) return min + 4*d - y;
88  if (y == -d) return min + 6*d + x;
89  else { //if (x == d) {
90  if (y >=0) return min + y;
91  else return min + 8*d + y;
92  }
93  }
94 };
95 
98 {
99 private:
101  int m_x;
103  int m_y;
104 public:
109  SpiralOrdering(int x, int y) : ZeroSpiralOrdering(), m_x(x), m_y(y) {}
111  {
113  }
114 };
115 
116 
117 #endif
118 
119 
120