HEX
Server: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/8.4.25
System: Windows NT DESKTOP-4TAV2RJ 10.0 build 19045 (Windows 10) AMD64
User: fred (0)
PHP: 8.4.25
Disabled: NONE
Upload Files
File: C:/Users/fred/anaconda3/Lib/site-packages/holoviews/examples/gallery/demos/bokeh/dragon_curve.ipynb
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dragon curve example from the [L-systems](../../topics/geometry/lsystems.ipynb) topic notebook in ``examples/topics/geometry``.\n",
    "\n",
    "Most examples work across multiple plotting backends, this example is also available for:\n",
    "* [Matplotlib - dragon_curve](../matplotlib/dragon_curve.ipynb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import holoviews as hv\n",
    "from holoviews import opts\n",
    "import numpy as np\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## L-system definition"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following class is a simplified version of the approach used in the [L-systems](../../topics/geometry/lsystems.ipynb) notebook, made specifically for plotting the [Dragon Curve](https://en.wikipedia.org/wiki/Dragon_curve)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class DragonCurve(object):\n",
    "    \"L-system agent that follows rules to generate the Dragon Curve\"\n",
    "    \n",
    "    initial ='FX'\n",
    "    productions = {'X':'X+YF+', 'Y':'-FX-Y'}\n",
    "    dragon_rules = {'F': lambda t,d,a: t.forward(d),\n",
    "                    'B': lambda t,d,a: t.back(d),\n",
    "                    '+': lambda t,d,a: t.rotate(-a),\n",
    "                    '-': lambda t,d,a: t.rotate(a),\n",
    "                    'X':lambda t,d,a: None,\n",
    "                    'Y':lambda t,d,a: None }\n",
    "    \n",
    "    def __init__(self, x=0,y=0, iterations=1):\n",
    "        self.heading = 0\n",
    "        self.distance = 5\n",
    "        self.angle = 90\n",
    "        self.x, self.y = x,y\n",
    "        self.trace = [(self.x, self.y)]\n",
    "        self.process(self.expand(iterations), self.distance, self.angle)\n",
    "        \n",
    "    def process(self, instructions, distance, angle):\n",
    "        for i in instructions:          \n",
    "            self.dragon_rules[i](self, distance, angle)\n",
    "        \n",
    "    def expand(self, iterations):\n",
    "        \"Expand an initial symbol with the given production rules\"\n",
    "        expansion = self.initial\n",
    "        \n",
    "        for i in range(iterations):\n",
    "            intermediate = \"\"\n",
    "            for ch in expansion:\n",
    "                intermediate = intermediate + self.productions.get(ch,ch)\n",
    "            expansion = intermediate\n",
    "        return expansion\n",
    "\n",
    "    def forward(self, distance):\n",
    "        self.x += np.cos(2*np.pi * self.heading/360.0)\n",
    "        self.y += np.sin(2*np.pi * self.heading/360.0)\n",
    "        self.trace.append((self.x,self.y))\n",
    "    \n",
    "    def rotate(self, angle):\n",
    "        self.heading += angle\n",
    "        \n",
    "    def back(self, distance):\n",
    "        self.heading += 180\n",
    "        self.forward(distance)\n",
    "        self.heading += 180\n",
    "        \n",
    "    @property\n",
    "    def path(self):\n",
    "        return hv.Path([self.trace])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hmap = hv.HoloMap(kdims='Iteration')\n",
    "for i in range(7,17):\n",
    "    hmap[i] = DragonCurve(-200, 0, i).path\n",
    "\n",
    "hmap.opts(\n",
    "    opts.Path(axiswise=False, color='black', line_width=1, \n",
    "              title='', xaxis=None, yaxis=None, framewise=True))"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}