VoxelServer/Laboratory/2DPerlinNoise.ipynb

197 lines
49 KiB
Plaintext
Raw Permalink Normal View History

2018-10-17 11:15:40 +02:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.image as mpimg\n",
"import scipy.ndimage as ndimage\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import random"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2018-10-24 20:59:22 +02:00
"# 2D perlin Noise Generator\n",
"---"
2018-10-17 11:15:40 +02:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2018-10-24 20:59:22 +02:00
"## implementation of Perlin Noise\n",
"\n",
"a simple demonstration how perlin heightmaps can be generated in python"
2018-10-17 11:15:40 +02:00
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"n = 6\n",
"raw_noise = np.zeros(shape=(n+1, n+1,2))\n",
"\n",
"# initialize random seed\n",
2018-10-24 20:59:22 +02:00
"np.random.seed(42)\n",
2018-10-17 11:15:40 +02:00
"\n",
"# fill raw noise with random unit vectors\n",
"for i in range(n+1):\n",
" for j in range(n+1):\n",
" # TODO: very inefficient loop!\n",
" x = np.random.normal()\n",
" y = np.random.normal()\n",
" \n",
" # normalize:\n",
" mag = (x**2+y**2)**.5\n",
" x /= mag\n",
" y /= mag\n",
" \n",
" raw_noise[i,j,0] = x\n",
" raw_noise[i,j,1] = y \n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
2018-10-24 20:59:22 +02:00
"image/png": "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
2018-10-17 11:15:40 +02:00
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig1, ax1 = plt.subplots()\n",
"\n",
"ax1.imshow(np.linalg.norm(raw_noise, axis=2), cmap='binary')\n",
"#print(img_binary)\n",
"ax1.set_title(\"raw noise map (magnitudes of vectors on unit-circle)\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def lerp(a0, a1, w):\n",
" return a0 + w*(a1 - a0)\n",
"\n",
"def dotGridGradient(ix, iy, x,y):\n",
" dx = x - ix\n",
" dy = y - iy\n",
" \n",
" return dx * raw_noise[ix, iy,0] + dy * raw_noise[ix,iy,1]"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def perlin(x,y):\n",
" x0 = int(x)\n",
" y0 = int(y)\n",
" \n",
" x1 = x0 + 1\n",
" y1 = y0 + 1\n",
" \n",
" sx = x - x0\n",
" sy = y - y0\n",
" \n",
" n0 = dotGridGradient(x0,y0,x,y)\n",
" n1 = dotGridGradient(x1,y0,x,y)\n",
" ix0 = lerp(n0,n1,sx)\n",
" \n",
" n0 = dotGridGradient(x0,y1,x,y)\n",
" n1 = dotGridGradient(x1,y1,x,y)\n",
" ix1 = lerp(n0,n1,sx)\n",
" \n",
" return lerp(ix0,ix1,sy)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"perlin_factor = 32\n",
"n_perlin = perlin_factor*n\n",
"perlin_noise = np.zeros(shape=(n_perlin, n_perlin))\n",
"\n",
"for x in range(n_perlin):\n",
" for y in range(n_perlin):\n",
" perlin_noise[x,y] = perlin(x/perlin_factor,y/perlin_factor)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
2018-10-24 20:59:22 +02:00
"image/png": "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
2018-10-17 11:15:40 +02:00
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig2, ax2 = plt.subplots()\n",
"\n",
"ax2.imshow(perlin_noise, cmap='binary')\n",
"#print(img_binary)\n",
"ax2.set_title(\"stupid interpolated perlin noise map\")\n",
"plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
2018-11-27 19:04:35 +01:00
"version": "3.6.7"
2018-10-17 11:15:40 +02:00
}
},
"nbformat": 4,
"nbformat_minor": 2
}