Skip to content

Instantly share code, notes, and snippets.

@stla
Last active July 30, 2023 07:50
Show Gist options
  • Save stla/3b5681a09c949b3a717f82f3e38e37fd to your computer and use it in GitHub Desktop.
Save stla/3b5681a09c949b3a717f82f3e38e37fd to your computer and use it in GitHub Desktop.
Runcinated tesseract - tetrahedra only
// runcinated tesseract - tetrahedra only //
#version 3.7;
global_settings { assumed_gamma 1 }
#include "colors.inc"
#include "textures.inc"
#include "glass.inc"
// camera ----------------------------------------------------------------------
camera {
location <0, 0,-10>
look_at 0
angle 45
right x*image_width/image_height
}
// light -----------------------------------------------------------------------
light_source { <0, 0,-100> color White shadowless }
// space -----------------------------------------------------------------------
#declare D = .5;
sky_sphere {
pigment {
crackle
color_map {
[pow(0.5, D) color Black]
[pow(0.6, D) color White*10]
}
scale .005/D
}
}
// vertices --------------------------------------------------------------------
#declare nvertices = 64;
#declare vertices = array[nvertices]
{
<-1, -1, -1, -1 - sqrt(2)>,
<1, -1, -1, -1 - sqrt(2)>,
<-1, 1, -1, -1 - sqrt(2)>,
<1, 1, -1, -1 - sqrt(2)>,
<-1, -1, 1, -1 - sqrt(2)>,
<1, -1, 1, -1 - sqrt(2)>,
<-1, 1, 1, -1 - sqrt(2)>,
<1, 1, 1, -1 - sqrt(2)>,
<-1, -1, -1, 1 + sqrt(2)>,
<1, -1, -1, 1 + sqrt(2)>,
<-1, 1, -1, 1 + sqrt(2)>,
<1, 1, -1, 1 + sqrt(2)>,
<-1, -1, 1, 1 + sqrt(2)>,
<1, -1, 1, 1 + sqrt(2)>,
<-1, 1, 1, 1 + sqrt(2)>,
<1, 1, 1, 1 + sqrt(2)>,
<-1, -1, -1 - sqrt(2), -1>,
<1, -1, -1 - sqrt(2), -1>,
<-1, 1, -1 - sqrt(2), -1>,
<1, 1, -1 - sqrt(2), -1>,
<-1, -1, 1 + sqrt(2), -1>,
<1, -1, 1 + sqrt(2), -1>,
<-1, 1, 1 + sqrt(2), -1>,
<1, 1, 1 + sqrt(2), -1>,
<-1, -1, -1 - sqrt(2), 1>,
<1, -1, -1 - sqrt(2), 1>,
<-1, 1, -1 - sqrt(2), 1>,
<1, 1, -1 - sqrt(2), 1>,
<-1, -1, 1 + sqrt(2), 1>,
<1, -1, 1 + sqrt(2), 1>,
<-1, 1, 1 + sqrt(2), 1>,
<1, 1, 1 + sqrt(2), 1>,
<-1, -1 - sqrt(2), -1, -1>,
<1, -1 - sqrt(2), -1, -1>,
<-1, 1 + sqrt(2), -1, -1>,
<1, 1 + sqrt(2), -1, -1>,
<-1, -1 - sqrt(2), 1, -1>,
<1, -1 - sqrt(2), 1, -1>,
<-1, 1 + sqrt(2), 1, -1>,
<1, 1 + sqrt(2), 1, -1>,
<-1, -1 - sqrt(2), -1, 1>,
<1, -1 - sqrt(2), -1, 1>,
<-1, 1 + sqrt(2), -1, 1>,
<1, 1 + sqrt(2), -1, 1>,
<-1, -1 - sqrt(2), 1, 1>,
<1, -1 - sqrt(2), 1, 1>,
<-1, 1 + sqrt(2), 1, 1>,
<1, 1 + sqrt(2), 1, 1>,
<-1 - sqrt(2), -1, -1, -1>,
<1 + sqrt(2), -1, -1, -1>,
<-1 - sqrt(2), 1, -1, -1>,
<1 + sqrt(2), 1, -1, -1>,
<-1 - sqrt(2), -1, 1, -1>,
<1 + sqrt(2), -1, 1, -1>,
<-1 - sqrt(2), 1, 1, -1>,
<1 + sqrt(2), 1, 1, -1>,
<-1 - sqrt(2), -1, -1, 1>,
<1 + sqrt(2), -1, -1, 1>,
<-1 - sqrt(2), 1, -1, 1>,
<1 + sqrt(2), 1, -1, 1>,
<-1 - sqrt(2), -1, 1, 1>,
<1 + sqrt(2), -1, 1, 1>,
<-1 - sqrt(2), 1, 1, 1>,
<1 + sqrt(2), 1, 1, 1>
};
// rotated and projected vertices ----------------------------------------------
#macro rotate4d(theta,phi,xi,vec)
#local a = cos(xi);
#local b = sin(theta)*cos(phi)*sin(xi);
#local c = sin(theta)*sin(phi)*sin(xi);
#local d = cos(theta)*sin(xi);
#local p = vec.x;
#local q = vec.y;
#local r = vec.z;
#local s = vec.t;
< a*p - b*q - c*r - d*s
, a*q + b*p + c*s - d*r
, a*r - b*s + c*p + d*q
, a*s + b*r - c*q + d*p >
#end
#macro StereographicProjection(q)
#local h = 25.8;
acos(q.t/sqrt(h))/pi*<q.x,q.y,q.z>/sqrt(h-q.t*q.t)
#end
#macro Vertices3(theta,phi,xi)
#local out = array[nvertices];
#for(i,0,nvertices-1)
#local out[i] = StereographicProjection(
rotate4d(theta,phi,xi,vertices[i])
);
#end
out
#end
// macro draw Tetrahedron ------------------------------------------------------
#declare edgeTexture = texture {
Gold_Metal
finish {
phong 1
ambient .1
diffuse .9
reflection 0
specular .1
metallic
}
};
#macro edge(i,j)
cylinder {
rvs[i] rvs[j], 0.0035
texture {
edgeTexture
}
}
#end
#macro drawTetrahedron(i, j, k, l, Tex)
triangle { rvs[i], rvs[j], rvs[k]
texture { Tex finish{ reflection 0 } }
}
triangle { rvs[i], rvs[j], rvs[l]
texture { Tex finish{ reflection 0 } }
}
triangle { rvs[i], rvs[k], rvs[l]
texture { Tex finish{ reflection 0 } }
}
triangle { rvs[j], rvs[k], rvs[l]
texture { Tex finish{ reflection 0 } }
}
edge(i,j)
edge(i,k)
edge(i,l)
edge(j,k)
edge(j,l)
edge(k,l)
sphere {
rvs[i], 0.005
texture { edgeTexture }
}
sphere {
rvs[j], 0.005
texture { edgeTexture }
}
sphere {
rvs[k], 0.005
texture { edgeTexture }
}
sphere {
rvs[l], 0.005
texture { edgeTexture }
}
#end
// draw ------------------------------------------------------------------------
#declare rvs = Vertices3(pi/2, pi/2, 2*frame_number*pi/180);
object {
union {
drawTetrahedron(38, 22, 6, 54, texture{Ruby_Glass})
drawTetrahedron(30, 14, 46, 62, texture{Ruby_Glass})
drawTetrahedron(63, 31, 47, 15, texture{Ruby_Glass})
drawTetrahedron(39, 55, 7, 23, texture{Ruby_Glass})
drawTetrahedron(26, 10, 42, 58, texture{Ruby_Glass})
drawTetrahedron(32, 16, 0, 48, texture{Ruby_Glass})
drawTetrahedron(19, 35, 51, 3, texture{Ruby_Glass})
drawTetrahedron(44, 12, 28, 60, texture{Ruby_Glass})
drawTetrahedron(27, 59, 43, 11, texture{Ruby_Glass})
drawTetrahedron(18, 2, 50, 34, texture{Ruby_Glass})
drawTetrahedron(45, 29, 61, 13, texture{Ruby_Glass})
drawTetrahedron(33, 17, 1, 49, texture{Ruby_Glass})
drawTetrahedron(41, 25, 9, 57, texture{Ruby_Glass})
drawTetrahedron(37, 5, 53, 21, texture{Ruby_Glass})
drawTetrahedron(40, 24, 56, 8, texture{Ruby_Glass})
drawTetrahedron(36, 4, 52, 20, texture{Ruby_Glass})
}
scale 9
}
// stereographic runcinated tesseract - tetrahedra only //
#version 3.7;
global_settings { assumed_gamma 1 }
#include "colors.inc"
#include "textures.inc"
// camera ----------------------------------------------------------------------
camera {
location <0, 0,-10>
look_at 0
angle 45
right x*image_width/image_height
}
// light -----------------------------------------------------------------------
light_source { <0, 0, -1000> color White shadowless }
// space -----------------------------------------------------------------------
#declare D = .5;
sky_sphere {
pigment {
crackle
color_map {
[pow(0.5, D) color Black]
[pow(0.6, D) color White*10]
}
scale .005/D
}
}
// vertices --------------------------------------------------------------------
#declare nvertices = 64;
#declare vertices = array[nvertices]
{
<-1, -1, -1, -1 - sqrt(2)>,
<1, -1, -1, -1 - sqrt(2)>,
<-1, 1, -1, -1 - sqrt(2)>,
<1, 1, -1, -1 - sqrt(2)>,
<-1, -1, 1, -1 - sqrt(2)>,
<1, -1, 1, -1 - sqrt(2)>,
<-1, 1, 1, -1 - sqrt(2)>,
<1, 1, 1, -1 - sqrt(2)>,
<-1, -1, -1, 1 + sqrt(2)>,
<1, -1, -1, 1 + sqrt(2)>,
<-1, 1, -1, 1 + sqrt(2)>,
<1, 1, -1, 1 + sqrt(2)>,
<-1, -1, 1, 1 + sqrt(2)>,
<1, -1, 1, 1 + sqrt(2)>,
<-1, 1, 1, 1 + sqrt(2)>,
<1, 1, 1, 1 + sqrt(2)>,
<-1, -1, -1 - sqrt(2), -1>,
<1, -1, -1 - sqrt(2), -1>,
<-1, 1, -1 - sqrt(2), -1>,
<1, 1, -1 - sqrt(2), -1>,
<-1, -1, 1 + sqrt(2), -1>,
<1, -1, 1 + sqrt(2), -1>,
<-1, 1, 1 + sqrt(2), -1>,
<1, 1, 1 + sqrt(2), -1>,
<-1, -1, -1 - sqrt(2), 1>,
<1, -1, -1 - sqrt(2), 1>,
<-1, 1, -1 - sqrt(2), 1>,
<1, 1, -1 - sqrt(2), 1>,
<-1, -1, 1 + sqrt(2), 1>,
<1, -1, 1 + sqrt(2), 1>,
<-1, 1, 1 + sqrt(2), 1>,
<1, 1, 1 + sqrt(2), 1>,
<-1, -1 - sqrt(2), -1, -1>,
<1, -1 - sqrt(2), -1, -1>,
<-1, 1 + sqrt(2), -1, -1>,
<1, 1 + sqrt(2), -1, -1>,
<-1, -1 - sqrt(2), 1, -1>,
<1, -1 - sqrt(2), 1, -1>,
<-1, 1 + sqrt(2), 1, -1>,
<1, 1 + sqrt(2), 1, -1>,
<-1, -1 - sqrt(2), -1, 1>,
<1, -1 - sqrt(2), -1, 1>,
<-1, 1 + sqrt(2), -1, 1>,
<1, 1 + sqrt(2), -1, 1>,
<-1, -1 - sqrt(2), 1, 1>,
<1, -1 - sqrt(2), 1, 1>,
<-1, 1 + sqrt(2), 1, 1>,
<1, 1 + sqrt(2), 1, 1>,
<-1 - sqrt(2), -1, -1, -1>,
<1 + sqrt(2), -1, -1, -1>,
<-1 - sqrt(2), 1, -1, -1>,
<1 + sqrt(2), 1, -1, -1>,
<-1 - sqrt(2), -1, 1, -1>,
<1 + sqrt(2), -1, 1, -1>,
<-1 - sqrt(2), 1, 1, -1>,
<1 + sqrt(2), 1, 1, -1>,
<-1 - sqrt(2), -1, -1, 1>,
<1 + sqrt(2), -1, -1, 1>,
<-1 - sqrt(2), 1, -1, 1>,
<1 + sqrt(2), 1, -1, 1>,
<-1 - sqrt(2), -1, 1, 1>,
<1 + sqrt(2), -1, 1, 1>,
<-1 - sqrt(2), 1, 1, 1>,
<1 + sqrt(2), 1, 1, 1>
};
// tetrahedra ------------------------------------------------------------------
#declare tetrahedra = array[16][4]
{
{38, 22, 6, 54},
{30, 14, 46, 62},
{63, 31, 47, 15},
{39, 55, 7, 23},
{26, 10, 42, 58},
{32, 16, 0, 48},
{19, 35, 51, 3},
{44, 12, 28, 60},
{27, 59, 43, 11},
{18, 2, 50, 34},
{45, 29, 61, 13},
{33, 17, 1, 49},
{41, 25, 9, 57},
{37, 5, 53, 21},
{40, 24, 56, 8},
{36, 4, 52, 20}
};
// tetrahedra faces (triangles) ################################################
#declare faces = array[64][3];
#for(i, 0, 15)
#declare faces[4*i][0] = tetrahedra[i][0];
#declare faces[4*i][1] = tetrahedra[i][1];
#declare faces[4*i][2] = tetrahedra[i][2];
#declare faces[4*i+1][0] = tetrahedra[i][0];
#declare faces[4*i+1][1] = tetrahedra[i][1];
#declare faces[4*i+1][2] = tetrahedra[i][3];
#declare faces[4*i+2][0] = tetrahedra[i][0];
#declare faces[4*i+2][1] = tetrahedra[i][2];
#declare faces[4*i+2][2] = tetrahedra[i][3];
#declare faces[4*i+3][0] = tetrahedra[i][1];
#declare faces[4*i+3][1] = tetrahedra[i][2];
#declare faces[4*i+3][2] = tetrahedra[i][3];
#end
// edges -----------------------------------------------------------------------
#declare edges = array[96][2];
#for(i, 0, 15)
#declare edges[6*i][0] = tetrahedra[i][0];
#declare edges[6*i][1] = tetrahedra[i][1];
#declare edges[6*i+1][0] = tetrahedra[i][0];
#declare edges[6*i+1][1] = tetrahedra[i][2];
#declare edges[6*i+2][0] = tetrahedra[i][0];
#declare edges[6*i+2][1] = tetrahedra[i][3];
#declare edges[6*i+3][0] = tetrahedra[i][1];
#declare edges[6*i+3][1] = tetrahedra[i][2];
#declare edges[6*i+4][0] = tetrahedra[i][1];
#declare edges[6*i+4][1] = tetrahedra[i][3];
#declare edges[6*i+5][0] = tetrahedra[i][2];
#declare edges[6*i+5][1] = tetrahedra[i][3];
#end
// rotated and projected vertices ----------------------------------------------
#macro rotate4d(theta, phi, xi, vec)
#local a = cos(xi);
#local b = sin(theta)*cos(phi)*sin(xi);
#local c = sin(theta)*sin(phi)*sin(xi);
#local d = cos(theta)*sin(xi);
#local p = vec.x;
#local q = vec.y;
#local r = vec.z;
#local s = vec.t;
< a*p - b*q - c*r - d*s
, a*q + b*p + c*s - d*r
, a*r - b*s + c*p + d*q
, a*s + b*r - c*q + d*p >
#end
#macro StereographicProjection(q, r2)
acos(q.t/sqrt(r2))/pi/sqrt(r2-q.t*q.t) * <q.x,q.y,q.z>
#end
#macro Vertices3(theta, phi, xi, r2)
#local out = array[nvertices];
#for(i,0,nvertices-1)
#local out[i] = StereographicProjection(
rotate4d(theta,phi,xi,vertices[i]), r2
);
#end
out
#end
/* macro spherical segment */
#macro vlength4(P)
sqrt(P.x*P.x + P.y*P.y + P.z*P.z + P.t*P.t)
#end
#macro sphericalSegment(P, Q, r, n)
#local out = array[n+1];
#for(i, 0, n)
#local pt = P + (i/n)*(Q-P);
#local out[i] = r/vlength4(pt) * pt;
#end
out
#end
/* macro to draw an edge */
#macro Edge(verts, v1, v2, theta, phi, xi, r2, Tex)
#local P = verts[v1];
#local Q = verts[v2];
#local PQ = sphericalSegment(P, Q, sqrt(r2), 100);
sphere_sweep {
b_spline 101
#for(k,0,100)
#local O =
StereographicProjection(rotate4d(theta,phi,xi,PQ[k]), r2);
O log(1+vlength(O)/4)/5
#end
texture {
Tex
}
}
#end
/* stereographic subdivision (to fill the triangular faces) */
#macro midpoint4(A, B, r)
#local xmid = (A.x + B.x)/2;
#local ymid = (A.y + B.y)/2;
#local zmid = (A.z + B.z)/2;
#local tmid = (A.t + B.t)/2;
#local lg = sqrt(xmid*xmid + ymid*ymid + zmid*zmid + tmid*tmid) / r;
< xmid / lg, ymid / lg, zmid / lg, tmid / lg >
#end
#macro subdiv0(A, B, C, r)
#local mAB = midpoint4(A, B, r);
#local mAC = midpoint4(A, C, r);
#local mBC = midpoint4(B, C, r);
#local trgl1 = array[3] {A, mAB, mAC};
#local trgl2 = array[3] {B, mAB, mBC};
#local trgl3 = array[3] {C, mBC, mAC};
#local trgl4 = array[3] {mAB, mAC, mBC};
array[4] {trgl1, trgl2, trgl3, trgl4}
#end
#macro subdiv(A, B, C, r, depth)
#if(depth=1)
#local out = subdiv0(A, B, C, r);
#else
#local triangles = subdiv(A, B, C, r, depth-1);
#local out = array[pow(4,depth)];
#for(i, 0, pow(4,depth-1)-1)
#local trgl = triangles[i];
#local trgls = subdiv0(trgl[0], trgl[1], trgl[2], r);
#local out[4*i] = trgls[0];
#local out[4*i+1] = trgls[1];
#local out[4*i+2] = trgls[2];
#local out[4*i+3] = trgls[3];
#end
#end
out
#end
/*-------------------------------------------*/
/*----- draw the polychoron ------*/
/*-------------------------------------------*/
#declare theta = pi/2;
#declare phi = 0;
#declare xi = 2*frame_number*pi/180;
#declare r2 = 3 + pow(1+sqrt(2),2);
#declare r = sqrt(r2);
#declare depth = 6;
#declare vs = Vertices3(theta, phi, xi, r2);
#declare stereoTriangles = array[64];
#for(i, 0, 63)
#local triangles4 =
subdiv(
vertices[faces[i][0]],
vertices[faces[i][1]],
vertices[faces[i][2]], r, depth);
#declare stereoTriangles[i] = array[dimension_size(triangles4,1)][3];
#for(j, 0, dimension_size(triangles4,1)-1)
#local trgl4 = triangles4[j];
#declare stereoTriangles[i][j][0] =
StereographicProjection(rotate4d(theta, phi, xi, trgl4[0]), r2);
#declare stereoTriangles[i][j][1] =
StereographicProjection(rotate4d(theta, phi, xi, trgl4[1]), r2);
#declare stereoTriangles[i][j][2] =
StereographicProjection(rotate4d(theta, phi, xi, trgl4[2]), r2);
#end
#end
#declare edgeTexture = texture {
pigment { color DarkPurple }
finish {
ambient 0.1
brilliance 6
diffuse 0.7
metallic
specular 0.80
roughness 1/120
reflection 0
}
};
#declare meshTexture =
texture {
pigment { OrangeRed }
finish {
ambient 0.1
diffuse 8
brilliance 6
metallic
specular 0.80
roughness 1/120
reflection 0
}
};
object {
union {
/* draw edges */
#for(i, 0, 95)
Edge(vertices, edges[i][0], edges[i][1],
theta, phi, xi, r2, edgeTexture)
#end
/* draw vertices */
#for(i, 0, 63)
sphere {
vs[i], log(1+vlength(vs[i])/4)/4
texture { edgeTexture }
}
#end
/* fill triangles */
mesh {
#for(i, 0, 63)
#local trgl = stereoTriangles[i];
#for(j, 0, dimension_size(trgl,1)-1)
triangle { trgl[j][0], trgl[j][1], trgl[j][2] }
#end
#end
texture { meshTexture }
}
}
scale 3.5
}
@stla
Copy link
Author

stla commented Jul 30, 2023

runcinatedTesseract
runcinatedTesseract_stereo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment