# Can the two sides of a mesh have a different color (e.g., origami paper)? # fold.jl # MWE of moving mesh
#
# All the paper test sheet's vertices and faces are defined
# according to the wavefront 3D object file format by the
# following six lines of text:
#=
v -2.0 0  2.0
v -2.0 0 -2.0
v  2.0 0 -2.0
v  2.0 0  2.0
f 1 2 4
f 3 4 2
=#
using GLMakie, GLMakie.FileIO
using GeometryBasics
include("ripga3d.jl")

# convert coordinate Point{3, Float32} to/from PGA point
function point(A::Point{3, Float32})::Vector{Float32}
return A*e032 + A*e013 + A*e021 + e123
end
function toPoint(A::Vector{Float32})
return Point{3, Float32}(A,A,A)
end

function fold()
# initialize data
SC,SF = coordinates(S),faces(S)
S_obs = Observable(S)

# initialize figure
fig = Figure(resolution = (600, 650))
ax3d = Axis3(fig[1,1],
elevation = pi/16,
azimuth = -pi/4,
limits = (-2,2, -2,2, -2,2),
aspect = (1,1,1))
mesh!(ax3d, S_obs)
fig

# generate video of folding
nFrame = 200
PL = point(SC) & point(SC) # Pivot Line
SP = point(SC) # Starting Point
record(fig, "fold.mp4", 1:nFrame) do iFrame
angle = pi*(1-abs(2*(iFrame-1)/nFrame-1))
R = rotor(angle, PL)
MP = R >>> SP # Moving Point
SC = toPoint(MP)
S_obs[] = GeometryBasics.Mesh(SC, SF)
end # for each video frame
end # origami()

# quick and dirty ffmpeg conversion from fold.mp4 to fold.gif:
# /tool/ffmpeg-2022-07/bin/ffmpeg.exe -i fold.mp4 -r 24 -s 480x520 -loop 0 fold.gif
# /tool/ffmpeg-2022-07/bin/ffmpeg.exe -i fold.mp4 -r 24 -s 600x650 -loop 0 fold.gif


After porting several bivector.net ganja.js Projective Geometric Algebra application examples to Julia and GLMakie, I’d like to port the ganja.js origami application example which has more complex graphics than the other application examples I’ve ported. So I have a few questions:

• Can a mesh be like origami paper with a different color on the two sides of the paper?
• What is the simplest way to plot both the wireframe and the colored faces?
• Is a GLMakie mesh the best approach to animating the many folds of origami or would a GLMakie surface (or something else) be better?
1 Like

I don’t think the normal GLMakie shaders support different colors for each side, but in principle it’s possible. I’m not sure how easy it is nowadays to use a custom glsl shader, though. And a mesh should be good, a surface is still a mesh, it’s just a convenient parameterization of one over a grid.

1 Like

Could an appropriate light position help a bit here?

I haven’t experimented with lighting, but changing from mesh!() to poly!() and changing the color and alpha channel helped.

	poly!(ax3d, S_obs,
color = RGBA(1, 1, 0.9, 0.9),
strokewidth = 1)
fig I plotted the moving triangle as a surface defined by a convex combination of
its vertices:

using GeometryBasics
#g(u,v);[0,1]x[0,1]->R^3 is the triangle, ABC, parameterization
g(u,v; A=Point3(0, -2.0, 2.0), B=Point3(0, 2.0, 2.0), C=Point3(0, -2.0, -2.0))=v*(1-u) *A+(1-v)*B+u*v*C
function triangle_surf(A::Point3, B::Point3, C::Point3; n=30)
ul = range(0,1, length=n)
vl = range(0,1, length=n)
u = ul' .*ones(n)
v= ones(n)'.* vl
P = g.(u, v; A=A, B=B, C=C)
end


Each frame displays two triangles, with two fixed points (B, and C) and the third point at a small distance (0.025) from each other, on the normal direction to one of the triangles.
The two triangles are colored by two distinct colors.

The moving point, A’ runs over an arc of a circle, namely:
c(t)=2\sqrt{2}\cos(t)w_1 + 2\sqrt{2}\sin(t)w_2, where
w_1=[-\sqrt{2}/2, 0.5, -0.5], w_2 =[-\sqrt{2}/2, -0.5, 0.5], and t\in[3\pi/4, 7\pi/4].
The triangle A’BC is filled with the burgundy color in my animation.
Get the unit vector of the normal direction to A’BC:
dn=cross(\vec{A'B}, \vec{A'C})
dn=dn/norm(dn)
The points A’‘=A’+0.025*dn, B, C are vertices of the white/gray triangle.

1 Like

Nice! The origami example I am porting from JavaScript to Julia folds a kabuto (Samurai helmet) that in some places is more than 10 layers thick. Because some of those folds are toward the camera and some are away from the camera, it seems there would need to be quite a bit of bookkeeping to keep track of the different depths of the different colored faces.