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
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{
80public:
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{
101private:
103 int m_x;
105 int m_y;
106public:
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
A cache of random values.
Definition: RandCache.h:20
RandCache(uint32 seed, std::unique_ptr< Ordering > o)
Constructor.
Definition: RandCache.h:38
RandCache(uint32 *seed, uint32 seed_len, std::unique_ptr< Ordering > o)
Constructor.
Definition: RandCache.h:45
WFMath::MTRand::uint32 uint32
Unsigned 32bit integer.
Definition: RandCache.h:23
double operator()(int x, int y)
Retrieve a random value associated with parameters.
Definition: RandCache.h:53
std::vector< uint32 >::size_type size_type
Size type of std::vector.
Definition: RandCache.h:25
A spiral around x,y.
Definition: RandCache.h:100
RandCache::size_type operator()(int x, int y) override
Determine the order.
Definition: RandCache.h:112
SpiralOrdering(int x, int y)
Constructor.
Definition: RandCache.h:111
A spiral around 0,0.
Definition: RandCache.h:79
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.