{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Computing and inspheres and circumspheres\n", "\n", "Under different conditions, various types of spheres containing or contained within a shape can be useful.\n", "For example, for spheres contained in a shape we may be interested in the largest sphere contained by a shape, or the largest *concentric* sphere contained within the shape.\n", "For a polyhedron, we may instead want to find the sphere that touches all the faces, if it exists." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import fresnel\n", "import numpy as np\n", "from matplotlib import pyplot as plt\n", "\n", "import coxeter" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def plot_polyhedron_with_sphere(shape, insphere=True):\n", " \"\"\"Image a polyhedron along with a sphere contained within it.\"\"\"\n", " device = fresnel.Device()\n", " scene = fresnel.Scene(device)\n", "\n", " transparent_material = fresnel.material.Material(\n", " color=fresnel.color.linear([1, 1, 1]),\n", " spec_trans=0.95,\n", " roughness=0.2,\n", " primitive_color_mix=0.0,\n", " )\n", " colored_material = fresnel.material.Material(\n", " color=fresnel.color.linear([0.9, 0.714, 0.169]),\n", " roughness=0.8,\n", " )\n", "\n", " # First make the shape and set up its properties.\n", " primitive = fresnel.geometry.ConvexPolyhedron(\n", " scene,\n", " fresnel.util.convex_polyhedron_from_vertices(shape.vertices),\n", " N=1,\n", " outline_width=0.01,\n", " material=transparent_material if insphere else colored_material,\n", " )\n", " primitive.color_by_face = 0.0\n", "\n", " # Now draw the insphere within the shape.\n", " sphere = fresnel.geometry.Sphere(\n", " scene,\n", " N=1,\n", " material=colored_material if insphere else transparent_material,\n", " )\n", "\n", " # Make the sphere a little bit smaller than it really is,\n", " # otherwise you get artifacts near the intersection of the\n", " # polyhedron and the insphere.\n", " sphere.radius[:] = [\n", " shape.insphere.radius * 0.99 if insphere else shape.circumsphere.radius * 1.01\n", " ]\n", "\n", " scene.camera = fresnel.camera.Orthographic.fit(scene, view=\"front\")\n", " tracer = fresnel.tracer.Path(device=device, w=300, h=300)\n", " return tracer.sample(scene, samples=24, light_samples=40)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The [Platonic solids](https://en.wikipedia.org/wiki/Platonic_solid) are a canonical set of shapes we can use for our analysis.\n", "Conveniently, they can easily be generated using coxeter.\n", "A good example is the dodecahedron." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dodecahedron = coxeter.families.PlatonicFamily.get_shape(\"Dodecahedron\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can query different types of spheres from this shape now:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# The sphere tangent to all the faces of the polyhedron.\n", "print(dodecahedron.insphere)\n", "\n", "# The largest concentric sphere contained in the shape.\n", "print(dodecahedron.maximal_centered_bounded_sphere)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's visualize what these shapes look like:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot_polyhedron_with_sphere(dodecahedron)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we instead want to look at spheres _containing_ a shape, we can get those as well." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# The sphere tangent to all the faces of the polyhedron.\n", "print(dodecahedron.circumsphere)\n", "\n", "# The largest concentric sphere contained in the shape.\n", "print(dodecahedron.minimal_centered_bounding_sphere)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot_polyhedron_with_sphere(dodecahedron, False)" ] } ], "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", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }