001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit http://imagingbook.com for additional details. 008 *******************************************************************************/ 009 010package imagingbook.pub.noise.hashing; 011 012/** 013 * Gradient (Perlin) noise implementation. 014 */ 015public abstract class Hash32 extends HashFun { 016 017 static final int maxInt = 0x7fffffff; 018 019 static final int[] smallPrimes = { // used for N-dimensional hashing 020 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 021 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 022 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 023 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 024 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 025 353, 359, 367, 373, 379, 383, 389, 397, 401, 409 026 }; 027 028 protected Hash32() { 029 super(); 030 } 031 032 protected Hash32(int seed) { 033 super(seed); 034 } 035 036 /** 037 * "Hashes" an <tt>int</tt> key to a "pseudo-random" <tt>int</tt> value 038 * in [-2147483648, 2147483647]. 039 * This method is supposed to be overridden by subclasses if needed. 040 * 041 * @param key key for random generator 042 * @return A integer value in [-2147483648, 2147483647]. 043 */ 044 abstract int hashInt(int key); 045 046 public double hash(int u) { 047 int h = hashInt(73*u + seed) & maxInt; 048 return (double) h / maxInt; 049 } 050 051// public double[] hash(int u, int v) { 052// int hx = hashInt(59*u + 67*v + seed) & maxInt; 053// int hy = hashInt(73*u + 79*v + seed) & maxInt; 054// return new double[] {(double) hx / maxInt, (double) hy / maxInt}; 055// } 056 057 // call 1 hash function and extract 12-bit blocks 058 public double[] hash(int u, int v) { 059 final int M = 0x00000FFF; 060 int h = hashInt(59*u + 67*v + seed); 061 int hx = h & M; // extract bits 0..11 062 int hy = (h >> 12) & M; // extract bits 12..23 063 return new double[] {(double) hx / M, (double) hy / M}; 064 } 065 066 // call 3 different hash functions for 3 dimensions 067// public double[] hash(int u, int v, int w) { 068// int M = 0x7FFFFFFF; 069// int hx = hashInt(59*u + 67*v + 71*w + seed) & M; 070// int hy = hashInt(73*u + 79*v + 83*w + seed) & M; 071// int hz = hashInt(89*u + 97*v + 101*w + seed) & M; 072// return new double[] {(double) hx/M, (double) hy/M, (double) hz/M}; 073// } 074 075 076 // call 1 hash function and extract bit blocks 077 public double[] hash(int u, int v, int w) { 078 final int M = 0x000000FF; 079 int h = hashInt(59*u + 67*v + 71*w + seed); 080 int hx = h & M; // extract bits 0..7 081 int hy = (h >> 8) & M; // extract bits 8..15 082 int hz = (h >> 16) & M; // extract bits 16..23 083 return new double[] {(double) hx / M, (double) hy / M, (double) hz / M}; 084 } 085 086 /* 087 * N-dimensional permutation hash; this version does not use 088 * any bit splitting. Instead, the hashInt() function is 089 * applied repeatedly for every gradient dimension by 090 * using the dimension number (k) as a local seed - 091 * in addition to the global seed (seed). 092 */ 093 public double[] hash(int[] p) { 094 final int N = p.length; 095 double[] g = new double[N]; 096 for (int k = 0; k < N; k++) { // dimension k 097 int sum = seed; 098 for (int l = 0; l < N; l++) { // dimension k 099 sum = sum + smallPrimes[l + k] * p[l]; 100 } 101 int h = hashInt(sum + k) & maxInt; 102 g[k] = (double) h / maxInt; 103 } 104 return g; 105 } 106 107}