mercator  0.4.0
A terrain generation library for the Worldforge system.
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 <memory>
12 #include <wfmath/MersenneTwister.h>
13 
14 // construct with something like:
15 // RandCache r(seed, new MyOrdering(args));
16 // where MyOrdering is derived from RandCache::Ordering.
17 
19 class RandCache
20 {
21  public:
23  typedef WFMath::MTRand::uint32 uint32;
25  typedef std::vector<uint32>::size_type size_type;
26 
28  struct Ordering {
29  virtual ~Ordering() = default;
31  virtual size_type operator()(int x, int y) = 0;
32  };
33 
38  RandCache(uint32 seed, std::unique_ptr<Ordering> o) :
39  m_rand(seed), m_ordering(std::move(o)) {}
45  RandCache(uint32* seed, uint32 seed_len, std::unique_ptr<Ordering> o) :
46  m_rand(seed, seed_len), m_ordering(std::move(o)) {}
47  ~RandCache() = default;
48 
53  double operator()(int x, int y)
54  {
55  size_type cache_order = (*m_ordering)(x, y);
56 
57  // make sure we've cached the value
58  if(cache_order >= m_cache.size()) {
59  size_type old_size = m_cache.size();
60  m_cache.resize(cache_order + 64); //do 64 at once
61  while(old_size < m_cache.size())
62  m_cache[old_size++] = m_rand.randInt();
63  }
64 
65  return double(m_cache[cache_order] * (1.0/4294967295.0));
66  }
67 
68  private:
70  WFMath::MTRand m_rand;
72  std::vector<uint32> m_cache;
74  std::unique_ptr<Ordering> m_ordering;
75 };
76 
79 {
80 public:
81  RandCache::size_type operator () (int x, int y) override
82  {
83  if (x==0 && y==0) return 0;
84 
85  int d=std::max(std::abs(x), std::abs(y));
86  int min=(2*d-1)*(2*d-1);
87 
88  if (y == d) return min + 2*d - x;
89  if (x == -d) return min + 4*d - y;
90  if (y == -d) return min + 6*d + x;
91  else { //if (x == d) {
92  if (y >=0) return min + y;
93  else return min + 8*d + y;
94  }
95  }
96 };
97 
100 {
101 private:
103  int m_x;
105  int m_y;
106 public:
111  SpiralOrdering(int x, int y) : ZeroSpiralOrdering(), m_x(x), m_y(y) {}
112  RandCache::size_type operator () (int x, int y) override
113  {
114  return ZeroSpiralOrdering::operator()(x-m_x, y-m_y);
115  }
116 };
117 
118 
119 #endif
120 
121 
122 
RandCache(uint32 *seed, uint32 seed_len, std::unique_ptr< Ordering > o)
Constructor.
Definition: RandCache.h:45
A cache of random values.
Definition: RandCache.h:19
RandCache(uint32 seed, std::unique_ptr< Ordering > o)
Constructor.
Definition: RandCache.h:38
A spiral around x,y.
Definition: RandCache.h:99
A spiral around 0,0.
Definition: RandCache.h:78
STL namespace.
WFMath::MTRand::uint32 uint32
Unsigned 32bit integer.
Definition: RandCache.h:23
std::vector< uint32 >::size_type size_type
Size type of std::vector.
Definition: RandCache.h:25
double operator()(int x, int y)
Retrieve a random value associated with parameters.
Definition: RandCache.h:53
RandCache::size_type operator()(int x, int y) override
Determine the order.
Definition: RandCache.h:81
Interface to define the ordering of the random number cache.
Definition: RandCache.h:28
virtual size_type operator()(int x, int y)=0
Determine the order.
SpiralOrdering(int x, int y)
Constructor.
Definition: RandCache.h:111