Last active
July 30, 2023 07:50
-
-
Save stla/3b5681a09c949b3a717f82f3e38e37fd to your computer and use it in GitHub Desktop.
Runcinated tesseract - tetrahedra only
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
} |
Author
stla
commented
Jul 30, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment