00001
00002
00003
00004
00005 #ifndef MERCATOR_RANDCACHE_H
00006 #define MERCATOR_RANDCACHE_H
00007
00008 #include <vector>
00009 #include <wfmath/MersenneTwister.h>
00010
00011
00012
00013
00014
00015 class RandCache
00016 {
00017 public:
00018 typedef WFMath::MTRand::uint32 uint32;
00019 typedef std::vector<uint32>::size_type size_type;
00020
00021 struct Ordering {
00022 virtual ~Ordering() {}
00023 virtual size_type operator()(int x, int y) = 0;
00024 };
00025
00026 RandCache(uint32 seed, Ordering* o) :
00027 m_rand(seed), m_ordering(o) {}
00028 RandCache(uint32* seed, uint32 seed_len, Ordering* o) :
00029 m_rand(seed, seed_len), m_ordering(o) {}
00030 ~RandCache() {delete m_ordering;}
00031
00032 double operator()(int x, int y)
00033 {
00034 size_type cache_order = (*m_ordering)(x, y);
00035
00036
00037 if(cache_order >= m_cache.size()) {
00038 size_type old_size = m_cache.size();
00039 m_cache.resize(cache_order + 64);
00040 while(old_size < m_cache.size())
00041 m_cache[old_size++] = m_rand.randInt();
00042 }
00043
00044 return double(m_cache[cache_order] * (1.0/4294967295.0));
00045 }
00046
00047 private:
00048 WFMath::MTRand m_rand;
00049 std::vector<uint32> m_cache;
00050 Ordering* m_ordering;
00051 };
00052
00053
00054 class ZeroSpiralOrdering : public RandCache::Ordering
00055 {
00056 public:
00057 RandCache::size_type operator () (int x, int y)
00058 {
00059 if (x==0 && y==0) return 0;
00060
00061 int d=std::max(std::abs(x), std::abs(y));
00062 int min=(2*d-1)*(2*d-1);
00063
00064 if (y == d) return min + 2*d - x;
00065 if (x == -d) return min + 4*d - y;
00066 if (y == -d) return min + 6*d + x;
00067 else {
00068 if (y >=0) return min + y;
00069 else return min + 8*d + y;
00070 }
00071 }
00072 };
00073
00074
00075 class SpiralOrdering : public ZeroSpiralOrdering
00076 {
00077 private:
00078 int m_x, m_y;
00079 public:
00080 SpiralOrdering(int x, int y) : ZeroSpiralOrdering(), m_x(x), m_y(y) {}
00081 RandCache::size_type operator () (int x, int y)
00082 {
00083 return ZeroSpiralOrdering::operator()(x-m_x, y-m_y);
00084 }
00085 };
00086
00087
00088 #endif
00089
00090
00091