{ "cells": [ { "cell_type": "markdown", "source": [ "A point light illuminates the grid points on the ground.\n", "You can buy the kit [via my Booth site](https://hyrodium.booth.pm/items/5046218)!" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "# Load packages" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "using Luxor\n", "using IntervalSets\n", "using BasicBSpline\n", "using BasicBSplineFitting\n", "using StaticArrays\n", "using ElasticSurfaceEmbedding" ], "metadata": {}, "execution_count": 1 }, { "cell_type": "markdown", "source": [ "# Compute the embedding shapes\n", "## Shape definition" ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "D (generic function with 1 method)" }, "metadata": {}, "execution_count": 2 } ], "cell_type": "code", "source": [ "ElasticSurfaceEmbedding.𝒑₍₀₎(u¹,u²) = SVector(2*u¹/(1+u¹^2+u²^2), 2*u²/(1+u¹^2+u²^2), (-1+u¹^2+u²^2)/(1+u¹^2+u²^2))\n", "n = 10\n", "D(i,n) = (-2.0..2.0, 2(i-1)/n..2i/n)" ], "metadata": {}, "execution_count": 2 }, { "cell_type": "markdown", "source": [ "## Strain estimation" ], "metadata": {} }, { "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "┌ Info: Strain - domain: [-2.0, 2.0]×[0.0, 0.2]\n", "└ Predicted: (min: -0.00653530699604614, max: 0.013070613992092282)\n" ] } ], "cell_type": "code", "source": [ "show_strain(D(1,n))" ], "metadata": {}, "execution_count": 3 }, { "cell_type": "markdown", "source": [ "## Main computation" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "steptree = StepTree()\n", "for i in 1:10\n", " initial_state!(steptree, D(i,n))\n", " newton_onestep!(steptree, fixingmethod=:fix3points)\n", " newton_onestep!(steptree)\n", " refinement!(steptree, p₊=(0,1), k₊=suggest_knotvector(steptree))\n", " newton_onestep!(steptree)\n", " newton_onestep!(steptree)\n", " pin!(steptree)\n", "end" ], "metadata": {}, "execution_count": 4 }, { "cell_type": "markdown", "source": [ "## Helper functions to export svg images" ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "svector2point (generic function with 1 method)" }, "metadata": {}, "execution_count": 5 } ], "cell_type": "code", "source": [ "function create_bezierpath(C::BSplineManifold{1,(3,),Point})\n", " P = bsplinespaces(C)[1]\n", " k = knotvector(P)\n", " k′ = 3*unique(k) + k[[1,end]]\n", " P′ = BSplineSpace{3}(k′)\n", " C′ = refinement(C,P′)\n", " a′ = controlpoints(C′)\n", " n′ = dim(P′)\n", " m = (n′-1) ÷ 3\n", " bezierpath = BezierPath([BezierPathSegment(a′[3i-2], a′[3i-1], a′[3i], a′[3i+1]) for i in 1:m])\n", " return bezierpath\n", "end\n", "function svector2point(M::BSplineManifold, unitlength)\n", " P = bsplinespaces(M)\n", " a = controlpoints(M)\n", " a′ = [Point(p[1]*unitlength[1], -p[2]*unitlength[1]) for p in a]\n", " M′ = BSplineManifold(a′, P)\n", " return M′\n", "end" ], "metadata": {}, "execution_count": 5 }, { "cell_type": "markdown", "source": [ "## Settings for export" ], "metadata": {} }, { "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "0.025" }, "metadata": {}, "execution_count": 6 } ], "cell_type": "code", "source": [ "xlims=(-3,3)\n", "ylims=(-1,1)\n", "unitlength = (200, \"mm\")\n", "r = 0.025" ], "metadata": {}, "execution_count": 6 }, { "cell_type": "markdown", "source": [ "## Export all embedded shapes with arcs" ], "metadata": {} }, { "outputs": [], "cell_type": "code", "source": [ "mkpath(\"stereographicprojection\")\n", "for i in 1:10\n", " M = svector2point(steptree.steps[6i].manifold, unitlength)\n", " D¹ = domain(bsplinespaces(M)[1])\n", " D² = domain(bsplinespaces(M)[2])\n", " u¹s = range(extrema(D¹)...,21)[2:end-1]\n", " u²₋ = minimum(D²)\n", " u²₊ = maximum(D²)\n", "\n", " width = (xlims[2] - xlims[1]) * unitlength[1]\n", " height = (ylims[2] - ylims[1]) * unitlength[1]\n", "\n", " filepath = joinpath(\"stereographicprojection\", \"embedding-$(i).svg\")\n", " Drawing(width, height, filepath)\n", " origin()\n", " background(\"white\")\n", " sethue(\"red\")\n", "\n", " C = M(:,u²₋)\n", " path = create_bezierpath(C)\n", " drawbezierpath(path, :stroke)\n", " C = M(:,u²₊)\n", " path = create_bezierpath(C)\n", " drawbezierpath(path, :stroke)\n", " C = M(2,:)\n", " path = create_bezierpath(C)\n", " drawbezierpath(path, :stroke)\n", " C = M(-2,:)\n", " path = create_bezierpath(C)\n", " drawbezierpath(path, :stroke)\n", "\n", " for u¹ in u¹s\n", " k = KnotVector([0,0,0,0,0.25,0.5,0.75,1,1,1,1])\n", " P = BSplineSpace{3}(k)\n", " dim(P)\n", "\n", " a = fittingcontrolpoints(t -> M(u¹+r*cospi(t), u²₋+r*sinpi(t)), P)\n", " C = BSplineManifold(a,P)\n", " path = create_bezierpath(C)\n", " drawbezierpath(path, :stroke)\n", "\n", " a = fittingcontrolpoints(t -> M(u¹+r*cospi(t), u²₊-r*sinpi(t)), P)\n", " C = BSplineManifold(a,P)\n", " path = create_bezierpath(C)\n", " drawbezierpath(path, :stroke)\n", " end\n", "\n", " finish()\n", " preview()\n", "\n", " script = read(filepath, String)\n", " lines = split(script, \"\\n\")\n", " lines[2] = replace(lines[2],\"pt\\\"\"=>\"mm\\\"\")\n", " write(filepath, join(lines,\"\\n\"))\n", "end" ], "metadata": {}, "execution_count": 7 }, { "cell_type": "markdown", "source": [ "The output files will be saved as `embedding-$(i).svg`.\n", "By modifying these files, we can place all of the shapes in yatsugiri-size (八ツ切, approximately 270×390 mm) paper like this:" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "Cutting and weaving these shape will result the sphere in the top image.\n", "Please check the following references for more information." ], "metadata": {} }, { "cell_type": "markdown", "source": [ "# References\n", "- [紙工作で立体射影をつくった話](https://note.com/hyrodium/n/n7b7cf03a7d91)\n", "- [立体射影製作キット](https://hackmd.io/@hyrodium/HJsIPNKqo)\n", "- [Stereographic projection weaving kit](https://hackmd.io/@hyrodium/H1epn1rRj)\n", "- [Further adventures in stereographic projection](https://www.youtube.com/watch?v=lbUOScpu0ws)" ], "metadata": {} }, { "cell_type": "markdown", "source": [ "---\n", "\n", "*This notebook was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*" ], "metadata": {} } ], "nbformat_minor": 3, "metadata": { "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.11.4" }, "kernelspec": { "name": "julia-1.11", "display_name": "Julia 1.11.4", "language": "julia" } }, "nbformat": 4 }