{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# How to make a Voxelised DNA Structure\n", "\n", "DNA Structures are built from [L-string](https://en.wikipedia.org/wiki/L-system) seeded fractals.\n", "\n", "L-strings and L-systems provide a grammar that can be used to generate a fractal. In this work,\n", "Hilbert curves are generated that are then converted into cubic placement 'voxels' for use in\n", "modelling." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import sys\n", "from pathlib import Path\n", "\n", "try:\n", " # The voxelisation library produces the cubic voxelisation that\n", " # can be used to build DNA\n", " from fractaldna.structure_models import voxelisation as v\n", "\n", " # The hilbert module produces and handles L-Strings\n", " from fractaldna.structure_models import hilbert as h\n", "except (ImportError, ModuleNotFoundError):\n", " sys.path.append(str(Path.cwd().parent.parent.parent))\n", " from fractaldna.structure_models import voxelisation as v\n", " from fractaldna.structure_models import hilbert as h\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from mpl_toolkits.mplot3d import Axes3D" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Producing L-Strings\n", "\n", "The `hilbert` model encodes a few basic fractals which can create Hilbert curves. These are\n", "\n", "```\n", "h.X: n>XFX&F+>>XFX-F>X->\n", "h.A: B-F+CFC+F-D&FnD-F+&&CFC+F+B<<\n", "h.B: A&FnCFBnFnDnn-F-Dn|FnB|FCnFnA<<\n", "h.C: |Dn|FnB-F+CnFnA&&FA&FnC+F+BnFnD<<\n", "h.D: |CFB-F+B|FA&FnA&&FB-F+B|FC<<\n", "```\n", "\n", "Reference to these are all stored in `hilbert.SUBSTITIONS`.\n", "\n", "The L-String language works as follows:\n", "\n", "- interpret `F` as DrawForward(1);\n", "- interpret `+` as Yaw(90);\n", "- interpret `-` as Yaw(-90);\n", "- interpret `n` as Pitch(90);\n", "- interpret `&` as Pitch(-90);\n", "- interpret `>` as Roll(90);\n", "- interpret `<` as Roll(-90);\n", "- interpret `|` as Yaw(180);\n", "\n", "To 'iterate' an L-String, replace any reference to a subsititution with its value." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"h.X:\", h.X)\n", "print(\"h.A:\", h.A)\n", "print(\"h.B:\", h.B)\n", "print(\"h.C:\", h.C)\n", "print(\"h.D:\", h.D)\n", "\n", "print(\"\\nh.X iterated once:\", h.iterate_lstring(h.X))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Drawing Fractals\n", "\n", "The function `generate_path` will generate a list of XYZ-points for a fractal L-String as below,\n", "which can then be plotted in matplotlib" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"Points seperated by 1 unit, no intermediate points\")\n", "print(h.generate_path(\"F\", distance=1, n=1))\n", "print(\"-\")\n", "print(\"Points seperated by 1 unit, 2 intermediate points\")\n", "print(h.generate_path(\"F\", distance=1, n=2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x_curve = np.array(h.generate_path(h.X, distance=1, n=10))\n", "\n", "fig = plt.figure()\n", "ax = fig.add_subplot(111, projection=\"3d\")\n", "\n", "ax.plot(x_curve[:, 0], x_curve[:, 1], x_curve[:, 2])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x_iterated = h.iterate_lstring(h.X)\n", "x_curve2 = np.array(h.generate_path(x_iterated, distance=1, n=10))\n", "\n", "fig = plt.figure()\n", "ax = fig.add_subplot(111, projection=\"3d\")\n", "\n", "ax.plot(x_curve2[:, 0], x_curve2[:, 1], x_curve2[:, 2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Making voxelised representations.\n", "\n", "The `voxelisation` model can convert the path of this curve to a voxelised representation, of straight\n", "and curved boxes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "voxelised_fractal = v.VoxelisedFractal.fromLString(h.X)\n", "\n", "# This can be plotted\n", "voxelised_fractal.to_pretty_plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exporting large-scale structures to text." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# And this can be returned as a data frame, or as text\n", "voxelised_fractal.to_frame()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 2 }