diff --git a/perlin_landscape.ipynb b/perlin_landscape.ipynb
new file mode 100644
index 0000000..55c43cc
--- /dev/null
+++ b/perlin_landscape.ipynb
@@ -0,0 +1,114 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "from lib import plot, noise\n",
+ "import IPython\n",
+ "import noise"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": "",
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "paper = plot.A6_PORTRAIT\n",
+ "p_svg = plot.SVGPlotter('plots/landscape.svg', paper)\n",
+ "p_hpgl = plot.HPGLPlotter(paper, 'plots/landscape_{index}.hpgl')\n",
+ "plotter = plot.MultiPlotter()\n",
+ "plotter.register_plotter(p_svg)\n",
+ "plotter.register_plotter(p_hpgl)\n",
+ "\n",
+ "plotter.move_to(paper.bottom_left())\n",
+ "plotter.line_to(paper.bottom_right())\n",
+ "plotter.line_to(paper.top_right())\n",
+ "plotter.line_to(paper.top_left())\n",
+ "plotter.line_to(paper.bottom_left())\n",
+ "\n",
+ "centre = paper.centre()\n",
+ "\n",
+ "shape = (100, 21)\n",
+ "scale = .6\n",
+ "octaves = 6\n",
+ "persistence = 0.4\n",
+ "lacunarity = 1.8\n",
+ "seed = np.random.randint(0, 100)\n",
+ "\n",
+ "world = np.zeros(shape)\n",
+ "\n",
+ "x_idx = np.linspace(0, 1, shape[0])\n",
+ "y_idx = np.linspace(0, 1, shape[1])\n",
+ "world_x, world_y = np.meshgrid(x_idx, y_idx)\n",
+ "\n",
+ "world = np.vectorize(noise.pnoise2)(world_x / scale,\n",
+ " world_y / scale,\n",
+ " octaves=octaves,\n",
+ " persistence=persistence,\n",
+ " lacunarity=lacunarity,\n",
+ " repeatx=1024,\n",
+ " repeaty=1024,\n",
+ " base=seed)\n",
+ "\n",
+ "def tf(coord):\n",
+ " return paper.width * 0.75 * (np.array(coord) - [0.5, 0.5]) + centre\n",
+ "\n",
+ "for i in reversed(range(len(y_idx) - 1)):\n",
+ " world[i, :] = np.min([world[i, :], world[i + 1, :] - (y_idx[0] - y_idx[1])], axis=0)\n",
+ "\n",
+ "for i, y in enumerate(y_idx):\n",
+ " plotter.move_to(tf((0, y + world[i, 0])))\n",
+ " for j, x in enumerate(x_idx[1:]):\n",
+ " plotter.line_to(tf((x, y + world[i, j])))\n",
+ "\n",
+ "plotter.finalise()\n",
+ "\n",
+ "IPython.display.SVG(filename=p_svg.file_name)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3.9.15 64-bit",
+ "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",
+ "version": "3.9.15"
+ },
+ "orig_nbformat": 4,
+ "vscode": {
+ "interpreter": {
+ "hash": "1dc4d77b1edb83bef89f833b7ed5251134c6a4899ef5e2c90c44e9927b4ae63a"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}