simplex_noise.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import numpy as np
  2. class Grad:
  3. def __init__(self, x, y, z):
  4. self.x = x
  5. self.y = y
  6. self.z = z
  7. def to_array(self):
  8. return np.array([self.x, self.y])
  9. grad3 = [Grad(1,1,0),Grad(-1,1,0),Grad(1,-1,0),Grad(-1,-1,0),
  10. Grad(1,0,1),Grad(-1,0,1),Grad(1,0,-1),Grad(-1,0,-1),
  11. Grad(0,1,1),Grad(0,-1,1),Grad(0,1,-1),Grad(0,-1,-1)]
  12. p = [151,160,137,91,90,15,
  13. 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
  14. 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
  15. 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
  16. 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
  17. 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
  18. 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
  19. 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
  20. 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
  21. 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
  22. 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
  23. 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
  24. 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]
  25. # To remove the need for index wrapping, double the permutation table length
  26. # 2D simplex noise
  27. F2 = 0.5*(np.sqrt(3.0)-1.0)
  28. G2 = (3.0-np.sqrt(3.0))/6.0
  29. # private static short perm[] = new short[512];
  30. # private static short permMod12[] = new short[512];
  31. perm = []
  32. permMod12 = []
  33. for i in range(512):
  34. print(i & 255)
  35. perm.append(p[i & 255])
  36. permMod12.append(int(perm[i] % 12))
  37. def dot(g, x, y):
  38. return g.x*x + g.y*y
  39. def simplex_noise(xin, yin):
  40. #n0, n1, n2; Noise contributions from the three corners
  41. # Skew the input space to determine which simplex cell we're in
  42. s = (xin+yin)*F2 # Hairy factor for 2D
  43. i = int(xin+s) #ffloor
  44. j = int(yin+s) #ffloor
  45. t = float((i+j)*G2)
  46. X0 = float((i-t)) # Unskew the cell origin back to (x,y) space
  47. Y0 = float(j-t)
  48. x0 = float(xin-X0) # The x,y distances from the cell origin
  49. y0 = float(yin-Y0)
  50. # For the 2D case, the simplex shape is an equilateral triangle.
  51. # Determine which simplex we are in.
  52. #int i1, j1; Offsets for second (middle) corner of simplex in (i,j) coords
  53. if(x0>y0):
  54. i1=1
  55. j1=0 # lower triangle, XY order: (0,0)->(1,0)->(1,1)
  56. else:
  57. i1=0
  58. j1=1 # upper triangle, YX order: (0,0)->(0,1)->(1,1)
  59. # A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
  60. # a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
  61. # c = (3-sqrt(3))/6
  62. x1 = float(x0 - i1 + G2) # Offsets for middle corner in (x,y) unskewed coords
  63. y1 = float(y0 - j1 + G2)
  64. x2 = float(x0 - 1.0 + 2.0 * G2) # Offsets for last corner in (x,y) unskewed coords
  65. y2 = float(y0 - 1.0 + 2.0 * G2)
  66. # Work out the hashed gradient indices of the three simplex corners
  67. ii = int(i & 255)
  68. jj = int(j & 255)
  69. gi0 = permMod12[ii+perm[jj]]
  70. gi1 = permMod12[ii+i1+perm[jj+j1]]
  71. gi2 = permMod12[ii+1+perm[jj+1]]
  72. # Calculate the contribution from the three corners
  73. t0 = 0.5 - x0*x0-y0*y0
  74. if t0<0:
  75. n0 = 0.0
  76. else:
  77. t0 *= t0
  78. n0 = t0 * t0 * grad3[gi0].to_array() # (x,y) of grad3 used for 2D gradient
  79. # n0 = t0 * t0 * dot(grad3[gi0], x0, y0) # (x,y) of grad3 used for 2D gradient
  80. t1 = float(0.5 - x1*x1-y1*y1)
  81. if t1<0:
  82. n1 = 0.0
  83. else:
  84. t1 *= t1
  85. # n1 = t1 * t1 * dot(grad3[gi1], x1, y1)
  86. n1 = t1 * t1 * grad3[gi1].to_array()
  87. t2 = float(0.5 - x2*x2-y2*y2)
  88. if t2<0:
  89. n2 = 0.0
  90. else:
  91. t2 *= t2
  92. # n2 = t2 * t2 * dot(grad3[gi2], x2, y2)
  93. n2 = t2 * t2 * grad3[gi2].to_array()
  94. # Add contributions from each corner to get the final noise value.
  95. # The result is scaled to return values in the interval [-1,1].
  96. v = (n0 + n1 + n2)
  97. v_vec = v / np.sqrt(np.dot(v,v))
  98. return np.arctan(v_vec[1]/v_vec[0])