diff semiconginev2/contrib/algorithms/noise.nim @ 1226:c8e3037aca66 compiletime-tests

add: contrib stuff
author sam <sam@basx.dev>
date Wed, 17 Jul 2024 23:41:51 +0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/semiconginev2/contrib/algorithms/noise.nim	Wed Jul 17 23:41:51 2024 +0700
@@ -0,0 +1,28 @@
+proc randomGradient(pos: Vec2f, seed: int32 = 0): Vec2f =
+  let randomAngle: float32 = TAU * (float32(int(hash((pos.x, pos.y, seed)))) / float32(high(int)))
+  return NewVec2f(cos(randomAngle), sin(randomAngle))
+
+proc interpolate(a: float32, b: float32, weight: float32): float32 =
+  # with Smootherstep
+  (b - a) * ((weight * (weight * 6.0 - 15.0) + 10.0) * weight * weight * weight) + a;
+
+proc Perlin*(pos: Vec2f, seed: int32 = 0): float32 =
+  let
+    # grid coordinates around target point
+    topleft = NewVec2f(trunc(pos.x), trunc(pos.y))
+    topright = topleft + NewVec2f(1, 0)
+    bottomleft = topleft + NewVec2f(0, 1)
+    bottomright = topleft + NewVec2f(1, 1)
+    # products for weights
+    topleft_dot = topleft.randomGradient(seed).Dot((pos - topleft))
+    topright_dot = topright.randomGradient(seed).Dot((pos - topright))
+    bottomleft_dot = bottomleft.randomGradient(seed).Dot((pos - bottomleft))
+    bottomright_dot = bottomright.randomGradient(seed).Dot((pos - bottomright))
+    xinterpol = pos.x - topleft.x
+    yinterpol = pos.y - topleft.y
+
+  return interpolate(
+    interpolate(topleft_dot, bottomleft_dot, yinterpol),
+    interpolate(topright_dot, bottomright_dot, yinterpol),
+    xinterpol
+  )