Stereographic projection
A point light illuminates the grid points on the ground. You can buy the kit via my Booth site!
Load packages
using Luxor
using IntervalSets
using BasicBSpline
using BasicBSplineFitting
using StaticArrays
using ElasticSurfaceEmbedding
Compute the embedding shapes
Shape definition
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 = 10
D(i,n) = (-2.0..2.0, 2(i-1)/n..2i/n)
D (generic function with 1 method)
Strain estimation
show_strain(D(1,n))
┌ Info: Strain - domain: [-2.0, 2.0]×[0.0, 0.2]
└ Predicted: (min: -0.00653530699604614, max: 0.013070613992092282)
Main computation
steptree = StepTree()
for i in 1:10
initial_state!(steptree, D(i,n))
newton_onestep!(steptree, fixingmethod=:fix3points)
newton_onestep!(steptree)
refinement!(steptree, p₊=(0,1), k₊=suggest_knotvector(steptree))
newton_onestep!(steptree)
newton_onestep!(steptree)
pin!(steptree)
end
Helper functions to export svg images
function create_bezierpath(C::BSplineManifold{1,(3,),Point})
P = bsplinespaces(C)[1]
k = knotvector(P)
k′ = 3*unique(k) + k[[1,end]]
P′ = BSplineSpace{3}(k′)
C′ = refinement(C,P′)
a′ = controlpoints(C′)
n′ = dim(P′)
m = (n′-1) ÷ 3
bezierpath = BezierPath([BezierPathSegment(a′[3i-2], a′[3i-1], a′[3i], a′[3i+1]) for i in 1:m])
return bezierpath
end
function svector2point(M::BSplineManifold, unitlength)
P = bsplinespaces(M)
a = controlpoints(M)
a′ = [Point(p[1]*unitlength[1], -p[2]*unitlength[1]) for p in a]
M′ = BSplineManifold(a′, P)
return M′
end
svector2point (generic function with 1 method)
Settings for export
xlims=(-3,3)
ylims=(-1,1)
unitlength = (200, "mm")
r = 0.025
0.025
Export all embedded shapes with arcs
mkpath("stereographicprojection")
for i in 1:10
M = svector2point(steptree.steps[6i].manifold, unitlength)
D¹ = domain(bsplinespaces(M)[1])
D² = domain(bsplinespaces(M)[2])
u¹s = range(extrema(D¹)...,21)[2:end-1]
u²₋ = minimum(D²)
u²₊ = maximum(D²)
width = (xlims[2] - xlims[1]) * unitlength[1]
height = (ylims[2] - ylims[1]) * unitlength[1]
filepath = joinpath("stereographicprojection", "embedding-$(i).svg")
Drawing(width, height, filepath)
origin()
background("white")
sethue("red")
C = M(:,u²₋)
path = create_bezierpath(C)
drawbezierpath(path, :stroke)
C = M(:,u²₊)
path = create_bezierpath(C)
drawbezierpath(path, :stroke)
C = M(2,:)
path = create_bezierpath(C)
drawbezierpath(path, :stroke)
C = M(-2,:)
path = create_bezierpath(C)
drawbezierpath(path, :stroke)
for u¹ in u¹s
k = KnotVector([0,0,0,0,0.25,0.5,0.75,1,1,1,1])
P = BSplineSpace{3}(k)
dim(P)
a = fittingcontrolpoints(t -> M(u¹+r*cospi(t), u²₋+r*sinpi(t)), P)
C = BSplineManifold(a,P)
path = create_bezierpath(C)
drawbezierpath(path, :stroke)
a = fittingcontrolpoints(t -> M(u¹+r*cospi(t), u²₊-r*sinpi(t)), P)
C = BSplineManifold(a,P)
path = create_bezierpath(C)
drawbezierpath(path, :stroke)
end
finish()
preview()
script = read(filepath, String)
lines = split(script, "\n")
lines[2] = replace(lines[2],"pt\""=>"mm\"")
write(filepath, join(lines,"\n"))
end
The output files will be saved as embedding-$(i).svg
. By modifying these files, we can place all of the shapes in yatsugiri-size (八ツ切, approximately 270×390 mm) paper like this:
Cutting and weaving these shape will result the sphere in the top image. Please check the following references for more information.
References
- 紙工作で立体射影をつくった話
- 立体射影製作キット
- Stereographic projection weaving kit
- Further adventures in stereographic projection
This page was generated using DemoCards.jl and Literate.jl.