-- luadraw_polyedrons.lua -- date 2026/05/29 -- version 3.1 -- Copyright 2026 Patrick Fradin -- This work may be distributed and/or modified under the -- conditions of the LaTeX Project Public License. -- The latest version of this license is in -- https://www.ctan.org/license/lppl local ld = luadraw local pt3d = ld.pt3d local Origin, vecI, vecJ, M = pt3d.Origin, pt3d.vecI, pt3d.vecJ, pt3d.M local poly = {} -- fonctions internes local cbrt = function(x) -- cubic root if x>=0 then return x^(1/3) else return -(math.abs(x))^(1/3) end end local transf = function(L,O,A,C,S) -- L représente les sommets d'un polyèdre de centre O et dont A est un sommet -- on renvoie L transformé en les sommets d'un polyèdre de centre C et dont un sommet est S if (C == nil) or (S == nil) then return L end local OA, OS1 = A-O, S-C local theta = pt3d.angle3d(OA,OS1) --en radians local u = pt3d.prod(OA,OS1) if pt3d.N1(u) < 1e-12 then --u ==0 u = pt3d.prod(OA,C-O) if pt3d.N1(u) < 1e-12 then --u ==0 u = pt3d.prod(OA,vecI) if pt3d.N1(u) < 1e-12 then --u ==0 u = pt3d.prod(OA,vecJ) end end end if theta ~= 0 then L = ld.rotate3d(L,theta*ld.rad, {O,u}) end local k = pt3d.abs(OS1)/pt3d.abs(OA) if k ~= 1 then L = ld.scale3d(L,k,O) end if not pt3d.isNul(C-O) then L = ld.shift3d(L,C-O) end return L end local pstar = function(L) -- L est une liste de pentagrammes croisés : {a,b,c,d,e} (forme d'étoile) -- la fonction découpe les pentagrammes en facettes convexes et renvoie le résultat local res = {} for _, P in ipairs(L) do local a,b,c,d,e = table.unpack(P) -- un pentagramme local a1 = ld.interDD({a,b-a},{d,c-d}) local d1 = ld.interDD({d,e-d},{a,b-a}) local b1 = ld.interDD({b,c-b},{d,e-d}) local e1 = ld.interDD({e,a-e},{b,c-b}) local c1 = ld.interDD({a,e-a},{d,c-d}) ld.insert(res, {{a, a1, c1}, {a1, d, d1}, {d1, b, b1}, {b1, e, e1}, {e1, c, c1}, {c1, a1, d1, b1, e1}}) end if #res > 0 then return res end end -- construction de polyèdres ----- solides de Platon function poly.tetrahedron(C,S,all) -- centre, sommet -- construction d'un tétraèdre régulier de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local L = {M(-1,-1,1), M(1,1,1), M(-1,1,-1), M(1,-1,-1)} -- sommets d'un tétraèdre régulier de centre Origin L = transf(L, Origin, L[1], C, S) local T = { ["vertices"]=L, ["facets"]={{1,2,3},{1,3,4},{1,4,2},{2,4,3}} } if all then local F1 = ld.poly2facet(T) -- facettes avec points 3d local A = ld.facetedges(F1) -- arêtes (ligne polygonale) return T, T.vertices, A, F1 -- polyèdre, sommets, arêtes, faces else return T end end function poly.Tetraedre(C,A,all) --compatibilité ascendante return poly.tetrahedron(C,S,all) end function poly.octahedron(C,S,all) -- construction d'un octaèdre régulier de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local L = {M(0,0,1), M(-1,0,0), M(0,1,0), M(0,-1,0), M(1,0,0), M(0,0,-1)} L = transf(L, Origin, L[1], C, S) local T = { ["vertices"]=L, ["facets"]={{1,4,5},{1,5,3},{1,3,2},{1,2,4},{6,4,2},{6,5,4},{6,3,5},{6,2,3}} } if all then local F1 = ld.poly2facet(T) -- facettes avec points 3d local A = ld.facetedges(F1) -- arêtes (ligne polygonale) return T, T.vertices, A, F1 -- polyèdre, sommets, arêtes, faces else return T end end function poly.Octaedre(C,S,all) --compatibilité ascendante return poly.octahedron(C,S,all) end function poly.cube(C,S,all) -- construction d'un cube de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local L = {M(-1,1,1), M(-1,-1,1), M(1,1,1), M(1,-1,1), M(-1,1,-1), M(-1,-1,-1), M(1,1,-1), M(1,-1,-1)} L = transf(L, Origin, L[1], C, S) local T = { ["vertices"]=L, ["facets"]={{1,3,7,5},{3,4,8,7},{2,6,8,4},{2,1,5,6},{1,2,4,3},{5,7,8,6}} } if all then local F1 = ld.poly2facet(T) -- facettes avec points 3d local A = ld.facetedges(F1) -- arêtes (ligne polygonale) return T, T.vertices, A, F1 -- polyèdre, sommets, arêtes, faces else return T end end function poly.icosahedron(C,S,all) -- construction d'un octaèdre régulier de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local p = (1+math.sqrt(5))/2 local L = {M(-1,0,p), M(1,0,p), M(0,p,1), M(0,-p,1), M(-p,1,0), M(-p,-1,0), M(p,1,0), M(p,-1,0), M(0,p,-1), M(0,-p,-1), M(-1,0,-p), M(1,0,-p) } L = transf(L, Origin, L[1], C, S) local T = { ["vertices"]=L, ["facets"]={{1,2,3},{1,3,5},{1,5,6},{1,6,4},{1,4,2},{5,11,6},{6,11,10},{10,4,6},{4,10,8},{4,8,2},{2,8,7},{2,7,3},{3,7,9},{3,9,5},{5,9,11},{12,7,8},{12,8,10},{12,9,7},{12,10,11},{12,11,9}} } if all then local F1 = ld.poly2facet(T) -- facettes avec points 3d local A = ld.facetedges(F1) -- arêtes (ligne polygonale) return T, T.vertices, A, F1 -- polyèdre, sommets, arêtes, faces else return T end end function poly.dodecahedron(C,S,all) -- construction d'un dodecaèdre régulier de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local p, q = (1+math.sqrt(5))/2, (math.sqrt(5)-1)/2 local L = {M(-q,0,p), M(q,0,p), M(-1,1,1), M(-1,-1,1), M(1,1,1), M(1,-1,1), M(0,p,q), M(0,-p,q), M(-p,q,0), M(-p,-q,0), M(p,q,0), M(p,-q,0),M(0,p,-q),M(0,-p,-q),M(-1,1,-1),M(-1,-1,-1),M(1,1,-1),M(1,-1,-1),M(-q,0,-p),M(q,0,-p)} L = transf(L, Origin, L[1], C, S) local T = { ["vertices"]=L, ["facets"]={{1,2,5,7,3}, {1,3,9,10,4}, {1,4,8,6,2}, {2,6,12,11,5}, {15,13,17,20,19}, {16,10,9,15,19}, {20,18,14,16,19}, {17,11,12,18,20}, {16,14,8,4,10}, {12,6,8,14,18}, {9,3,7,13,15}, {17,13,7,5,11}} } if all then local F1 = ld.poly2facet(T) -- facettes avec points 3d local A = ld.facetedges(F1) -- arêtes (ligne polygonale) return T, T.vertices, A, F1 -- polyèdre, sommets, arêtes, faces else return T end end -- fin solides de Platon -- solides d'Archimède function poly.cuboctahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = math.sqrt(2) / 2 local T = {} local L = {M(C0,0.0,C0),M(C0,0.0,-C0),M(-C0,0.0,C0),M(-C0,0.0,-C0),M(C0,C0,0.0),M(C0,-C0,0.0),M(-C0,C0,0.0),M(-C0,-C0,0.0),M(0.0,C0,C0),M(0.0,C0,-C0),M(0.0,-C0,C0),M(0.0,-C0,-C0)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,6,2,5},{1,9,3,11},{8,3,7,4},{8,12,6,11},{10,2,12,4},{10,7,9,5},{1,5,9},{2,6,12},{3,8,11},{4,7,10},{5,2,10},{6,1,11},{7,3,9},{8,4,12}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T, ld.range(1,6)), ld.getfacet(T,ld.range(7,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.icosidodecahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = (1 + math.sqrt(5)) / 4 local C1 = (3 + math.sqrt(5)) / 4 local C2 = (1 + math.sqrt(5)) / 2 local T = {} local L = {M(0.0,0.0,C2),M(0.0,0.0,-C2),M(C2,0.0,0.0),M(-C2,0.0,0.0),M(0.0,C2,0.0),M(0.0,-C2,0.0),M(0.5,C0,C1),M(0.5,C0,-C1),M(0.5,-C0,C1),M(0.5,-C0,-C1),M(-0.5,C0,C1),M(-0.5,C0,-C1),M(-0.5,-C0,C1),M(-0.5,-C0,-C1),M(C1,0.5,C0),M(C1,0.5,-C0),M(C1,-0.5,C0),M(C1,-0.5,-C0),M(-C1,0.5,C0),M(-C1,0.5,-C0),M(-C1,-0.5,C0),M(-C1,-0.5,-C0),M(C0,C1,0.5),M(C0,C1,-0.5),M(C0,-C1,0.5),M(C0,-C1,-0.5),M(-C0,C1,0.5),M(-C0,C1,-0.5),M(-C0,-C1,0.5),M(-C0,-C1,-0.5)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,9,17,15,7},{1,11,19,21,13},{2,8,16,18,10},{2,14,22,20,12},{3,16,24,23,15},{3,17,25,26,18},{4,19,27,28,20},{4,22,30,29,21},{5,24,8,12,28},{5,27,11,7,23},{6,25,9,13,29},{6,30,14,10,26},{1,7,11},{1,13,9},{2,10,14},{2,12,8},{3,15,17},{3,18,16},{4,20,22},{4,21,19},{5,23,24},{5,28,27},{6,26,25},{6,29,30},{7,15,23},{8,24,16},{9,25,17},{10,18,26},{11,27,19},{12,20,28},{13,21,29},{14,30,22}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,12)), ld.getfacet(T,ld.range(13,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.lsnubcube(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = math.sqrt(3 * (4 - cbrt(17 + 3*math.sqrt(33)) - cbrt(17 - 3*math.sqrt(33)))) / 6 local C1 = math.sqrt(3 * (2 + cbrt(17 + 3*math.sqrt(33)) + cbrt(17 - 3*math.sqrt(33)))) / 6 local C2 = math.sqrt(3 * (4 + cbrt(199 + 3*math.sqrt(33)) + cbrt(199 - 3*math.sqrt(33)))) / 6 local T = {} local L = {M(C1,C0,C2),M(C1,-C0,-C2),M(-C1,-C0,C2),M(-C1,C0,-C2),M(C2,C1,C0),M(C2,-C1,-C0),M(-C2,-C1,C0),M(-C2,C1,-C0),M(C0,C2,C1),M(C0,-C2,-C1),M(-C0,-C2,C1),M(-C0,C2,-C1),M(C0,-C1,C2),M(C0,C1,-C2),M(-C0,C1,C2),M(-C0,-C1,-C2),M(C2,-C0,C1),M(C2,C0,-C1),M(-C2,C0,C1),M(-C2,-C0,-C1),M(C1,-C2,C0),M(C1,C2,-C0),M(-C1,C2,C0),M(-C1,-C2,-C0)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{3,13,1,15},{4,14,2,16},{5,17,6,18},{8,20,7,19},{9,22,12,23},{10,21,11,24},{1,9,15},{2,10,16},{3,11,13},{4,12,14},{5,1,17},{6,2,18},{7,3,19},{8,4,20},{9,5,22},{10,6,21},{11,7,24},{12,8,23},{13,17,1},{14,18,2},{15,19,3},{16,20,4},{17,21,6},{18,22,5},{19,23,8},{20,24,7},{21,13,11},{22,14,12},{23,15,9},{24,16,10},{9,1,5},{10,2,6},{11,3,7},{12,4,8},{13,21,17},{14,22,18},{15,23,19},{16,24,20}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,6)), ld.getfacet(T,ld.range(7,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.lsnubdodecahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = 0.192893711352359022108262546061 local C1 = 0.330921024729844230963655269187 local C2 = 0.374821658114562295266609516608 local C3 = 0.567715369466921317374872062669 local C4 = 0.643029605914072573107464141441 local C5 = 0.728335176957191477360671629838 local C6 = 0.847550046789060797396217956030 local C7 = 1.103156835071753772627281146446 local C8 = 1.24950378846302719500774109632 local C9 = 1.41526541625598211477109001870 local C10 = 1.45402422933801541929649491091 local C11 = 1.64691794069037444140475745697 local C12 = 1.74618644098582634573474528789 local C13 = 1.97783896542021867236841272616 local C14 = 2.097053835252087992403959052348 local phi = (1 + math.sqrt(5)) / 2 local x = cbrt((phi + math.sqrt(phi-5/27))/2) + cbrt((phi - math.sqrt(phi-5/27))/2) local C0 = phi * math.sqrt(3 - (x^2)) / 2 local C1 = x * phi * math.sqrt(3 - (x^2)) / 2 local C2 = phi * math.sqrt((x - 1 - (1/x)) * phi) / 2 local C3 = (x^2) * phi * math.sqrt(3 - (x^2)) / 2 local C4 = x * phi * math.sqrt((x - 1 - (1/x)) * phi) / 2 local C5 = phi * math.sqrt(1 - x + (1 + phi) / x) / 2 local C6 = phi * math.sqrt(x + 1 - phi) / 2 local C7 = (x^2) * phi * math.sqrt((x - 1 - (1/x)) * phi) / 2 local C8 = x * phi * math.sqrt(1 - x + (1 + phi) / x) / 2 local C9 = math.sqrt((x + 2) * phi + 2) / 2 local C10 = x * math.sqrt(x * (1 + phi) - phi) / 2 local C11 = math.sqrt((x^2) * (1 + 2 * phi) - phi) / 2 local C12 = phi * math.sqrt((x^2) + x) / 2 local C13 = (phi^2) * math.sqrt(x * (x + phi) + 1) / (2 * x) local C14 = phi * math.sqrt(x * (x + phi) + 1) / 2 local T = {} local L = {M(C2,-C1,C14),M(C2,C1,-C14),M(-C2,C1,C14),M(-C2,-C1,-C14),M(C14,-C2,C1),M(C14,C2,-C1),M(-C14,C2,C1),M(-C14,-C2,-C1),M(C1,-C14,C2),M(C1,C14,-C2),M(-C1,C14,C2),M(-C1,-C14,-C2),M(C3,C4,C13),M(C3,-C4,-C13),M(-C3,-C4,C13),M(-C3,C4,-C13),M(C13,C3,C4),M(C13,-C3,-C4),M(-C13,-C3,C4),M(-C13,C3,-C4),M(C4,C13,C3),M(C4,-C13,-C3),M(-C4,-C13,C3),M(-C4,C13,-C3),M(C0,-C8,C12),M(C0,C8,-C12),M(-C0,C8,C12),M(-C0,-C8,-C12),M(C12,-C0,C8),M(C12,C0,-C8),M(-C12,C0,C8),M(-C12,-C0,-C8),M(C8,-C12,C0),M(C8,C12,-C0),M(-C8,C12,C0),M(-C8,-C12,-C0),M(C7,-C6,C11),M(C7,C6,-C11),M(-C7,C6,C11),M(-C7,-C6,-C11),M(C11,-C7,C6),M(C11,C7,-C6),M(-C11,C7,C6),M(-C11,-C7,-C6),M(C6,-C11,C7),M(C6,C11,-C7),M(-C6,C11,C7),M(-C6,-C11,-C7),M(C9,C5,C10),M(C9,-C5,-C10),M(-C9,-C5,C10),M(-C9,C5,-C10),M(C10,C9,C5),M(C10,-C9,-C5),M(-C10,-C9,C5),M(-C10,C9,-C5),M(C5,C10,C9),M(C5,-C10,-C9),M(-C5,-C10,C9),M(-C5,C10,-C9)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,37,29,49,13},{2,38,30,50,14},{3,39,31,51,15},{4,40,32,52,16},{5,41,33,54,18},{6,42,34,53,17},{7,43,35,56,20},{8,44,36,55,19},{9,45,25,59,23},{10,46,26,60,24},{11,47,27,57,21},{12,48,28,58,22},{1,3,15},{2,4,16},{3,1,13},{4,2,14},{5,6,17},{6,5,18},{7,8,19},{8,7,20},{9,12,22},{10,11,21},{11,10,24},{12,9,23},{13,49,57},{14,50,58},{15,51,59},{16,52,60},{17,53,49},{18,54,50},{19,55,51},{20,56,52},{21,57,53},{22,58,54},{23,59,55},{24,60,56},{25,45,37},{26,46,38},{27,47,39},{28,48,40},{29,37,41},{30,38,42},{31,39,43},{32,40,44},{33,41,45},{34,42,46},{35,43,47},{36,44,48},{37,1,25},{38,2,26},{39,3,27},{40,4,28},{41,5,29},{42,6,30},{43,7,31},{44,8,32},{45,9,33},{46,10,34},{47,11,35},{48,12,36},{49,29,17},{50,30,18},{51,31,19},{52,32,20},{53,34,21},{54,33,22},{55,36,23},{56,35,24},{57,27,13},{58,28,14},{59,25,15},{60,26,16},{25,1,15},{26,2,16},{27,3,13},{28,4,14},{29,5,17},{30,6,18},{31,7,19},{32,8,20},{33,9,22},{34,10,21},{35,11,24},{36,12,23},{37,45,41},{38,46,42},{39,47,43},{40,48,44},{49,53,57},{50,54,58},{51,55,59},{52,56,60}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,12)), ld.getfacet(T,ld.range(13,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.rhombicosidodecahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = (1 + math.sqrt(5)) / 4 local C1 = (3 + math.sqrt(5)) / 4 local C2 = (1 + math.sqrt(5)) / 2 local C3 = (5 + math.sqrt(5)) / 4 local C4 = (2 + math.sqrt(5)) / 2 local T = {} local L = {M(0.5,0.5,C4),M(0.5,0.5,-C4),M(0.5,-0.5,C4),M(0.5,-0.5,-C4),M(-0.5,0.5,C4),M(-0.5,0.5,-C4),M(-0.5,-0.5,C4),M(-0.5,-0.5,-C4),M(C4,0.5,0.5),M(C4,0.5,-0.5),M(C4,-0.5,0.5),M(C4,-0.5,-0.5),M(-C4,0.5,0.5),M(-C4,0.5,-0.5),M(-C4,-0.5,0.5),M(-C4,-0.5,-0.5),M(0.5,C4,0.5),M(0.5,C4,-0.5),M(0.5,-C4,0.5),M(0.5,-C4,-0.5),M(-0.5,C4,0.5),M(-0.5,C4,-0.5),M(-0.5,-C4,0.5),M(-0.5,-C4,-0.5),M(0.0,C1,C3),M(0.0,C1,-C3),M(0.0,-C1,C3),M(0.0,-C1,-C3),M(C3,0.0,C1),M(C3,0.0,-C1),M(-C3,0.0,C1),M(-C3,0.0,-C1),M(C1,C3,0.0),M(C1,-C3,0.0),M(-C1,C3,0.0),M(-C1,-C3,0.0),M(C1,C0,C2),M(C1,C0,-C2),M(C1,-C0,C2),M(C1,-C0,-C2),M(-C1,C0,C2),M(-C1,C0,-C2),M(-C1,-C0,C2),M(-C1,-C0,-C2),M(C2,C1,C0),M(C2,C1,-C0),M(C2,-C1,C0),M(C2,-C1,-C0),M(-C2,C1,C0),M(-C2,C1,-C0),M(-C2,-C1,C0),M(-C2,-C1,-C0),M(C0,C2,C1),M(C0,C2,-C1),M(C0,-C2,C1),M(C0,-C2,-C1),M(-C0,C2,C1),M(-C0,C2,-C1),M(-C0,-C2,C1),M(-C0,-C2,-C1)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{25,53,17,21,57},{26,58,22,18,54},{27,59,23,19,55},{28,56,20,24,60},{29,37,1,3,39},{30,40,4,2,38},{31,43,7,5,41},{32,42,6,8,44},{33,45,9,10,46},{34,48,12,11,47},{35,50,14,13,49},{36,51,15,16,52},{1,37,53,25},{2,26,54,38},{3,27,55,39},{4,40,56,28},{5,25,57,41},{6,42,58,26},{7,43,59,27},{8,28,60,44},{9,45,37,29},{10,30,38,46},{11,29,39,47},{12,48,40,30},{13,31,41,49},{14,50,42,32},{15,51,43,31},{16,32,44,52},{17,53,45,33},{18,33,46,54},{19,34,47,55},{20,56,48,34},{21,35,49,57},{22,58,50,35},{23,59,51,36},{24,36,52,60},{1,5,7,3},{2,4,8,6},{9,11,12,10},{13,14,16,15},{17,18,22,21},{19,23,24,20},{25,5,1},{26,2,6},{27,3,7},{28,8,4},{29,11,9},{30,10,12},{31,13,15},{32,16,14},{33,18,17},{34,19,20},{35,21,22},{36,24,23},{37,45,53},{38,54,46},{39,55,47},{40,48,56},{41,57,49},{42,50,58},{43,51,59},{44,60,52}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,12)), ld.getfacet(T,ld.range(13,42)), ld.getfacet(T,ld.range(43,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.rhombicuboctahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = (1 + math.sqrt(2)) / 2 local T = {} local L = {M(0.5,0.5,C0),M(0.5,0.5,-C0),M(0.5,-0.5,C0),M(0.5,-0.5,-C0),M(-0.5,0.5,C0),M(-0.5,0.5,-C0),M(-0.5,-0.5,C0),M(-0.5,-0.5,-C0),M(C0,0.5,0.5),M(C0,0.5,-0.5),M(C0,-0.5,0.5),M(C0,-0.5,-0.5),M(-C0,0.5,0.5),M(-C0,0.5,-0.5),M(-C0,-0.5,0.5),M(-C0,-0.5,-0.5),M(0.5,C0,0.5),M(0.5,C0,-0.5),M(0.5,-C0,0.5),M(0.5,-C0,-0.5),M(-0.5,C0,0.5),M(-0.5,C0,-0.5),M(-0.5,-C0,0.5),M(-0.5,-C0,-0.5)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,5,7,3},{2,4,8,6},{9,11,12,10},{13,14,16,15},{17,18,22,21},{19,23,24,20},{1,3,11,9},{1,17,21,5},{8,4,20,24},{8,16,14,6},{12,4,2,10},{12,11,19,20},{13,15,7,5},{13,21,22,14},{18,2,6,22},{18,17,9,10},{23,15,16,24},{23,19,3,7},{1,9,17},{2,18,10},{3,19,11},{4,12,20},{5,21,13},{6,14,22},{7,15,23},{8,24,16}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,18)), ld.getfacet(T,ld.range(19,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.rsnubcube(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = math.sqrt(3 * (4 - cbrt(17 + 3*math.sqrt(33)) - cbrt(17 - 3*math.sqrt(33)))) / 6 local C1 = math.sqrt(3 * (2 + cbrt(17 + 3*math.sqrt(33)) + cbrt(17 - 3*math.sqrt(33)))) / 6 local C2 = math.sqrt(3 * (4 + cbrt(199 + 3*math.sqrt(33)) + cbrt(199 - 3*math.sqrt(33)))) / 6 local T = {} local L = {M(C1,-C0,C2),M(C1,C0,-C2),M(-C1,C0,C2),M(-C1,-C0,-C2),M(C2,-C1,C0),M(C2,C1,-C0),M(-C2,C1,C0),M(-C2,-C1,-C0),M(C0,-C2,C1),M(C0,C2,-C1),M(-C0,C2,C1),M(-C0,-C2,-C1),M(C0,C1,C2),M(C0,-C1,-C2),M(-C0,-C1,C2),M(-C0,C1,-C2),M(C2,C0,C1),M(C2,-C0,-C1),M(-C2,-C0,C1),M(-C2,C0,-C1),M(C1,C2,C0),M(C1,-C2,-C0),M(-C1,-C2,C0),M(-C1,C2,-C0)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{3,15,1,13},{4,16,2,14},{5,18,6,17},{8,19,7,20},{9,23,12,22},{10,24,11,21},{1,15,9},{2,16,10},{3,13,11},{4,14,12},{5,17,1},{6,18,2},{7,19,3},{8,20,4},{9,22,5},{10,21,6},{11,24,7},{12,23,8},{13,1,17},{14,2,18},{15,3,19},{16,4,20},{17,6,21},{18,5,22},{19,8,23},{20,7,24},{21,11,13},{22,12,14},{23,9,15},{24,10,16},{9,5,1},{10,6,2},{11,7,3},{12,8,4},{13,17,21},{14,18,22},{15,19,23},{16,20,24}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,6)), ld.getfacet(T,ld.range(7,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.rsnubdodecahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local phi = (1 + math.sqrt(5)) / 2 local x = cbrt((phi + math.sqrt(phi-5/27))/2) + cbrt((phi - math.sqrt(phi-5/27))/2) local C0 = phi * math.sqrt(3 - (x^2)) / 2 local C1 = x * phi * math.sqrt(3 - (x^2)) / 2 local C2 = phi * math.sqrt((x - 1 - (1/x)) * phi) / 2 local C3 = (x^2) * phi * math.sqrt(3 - (x^2)) / 2 local C4 = x * phi * math.sqrt((x - 1 - (1/x)) * phi) / 2 local C5 = phi * math.sqrt(1 - x + (1 + phi) / x) / 2 local C6 = phi * math.sqrt(x + 1 - phi) / 2 local C7 = (x^2) * phi * math.sqrt((x - 1 - (1/x)) * phi) / 2 local C8 = x * phi * math.sqrt(1 - x + (1 + phi) / x) / 2 local C9 = math.sqrt((x + 2) * phi + 2) / 2 local C10 = x * math.sqrt(x * (1 + phi) - phi) / 2 local C11 = math.sqrt((x^2) * (1 + 2 * phi) - phi) / 2 local C12 = phi * math.sqrt((x^2) + x) / 2 local C13 = (phi^2) * math.sqrt(x * (x + phi) + 1) / (2 * x) local C14 = phi * math.sqrt(x * (x + phi) + 1) / 2 local T = {} local L = {M(C2,C1,C14),M(C2,-C1,-C14),M(-C2,-C1,C14),M(-C2,C1,-C14),M(C14,C2,C1),M(C14,-C2,-C1),M(-C14,-C2,C1),M(-C14,C2,-C1),M(C1,C14,C2),M(C1,-C14,-C2),M(-C1,-C14,C2),M(-C1,C14,-C2),M(C3,-C4,C13),M(C3,C4,-C13),M(-C3,C4,C13),M(-C3,-C4,-C13),M(C13,-C3,C4),M(C13,C3,-C4),M(-C13,C3,C4),M(-C13,-C3,-C4),M(C4,-C13,C3),M(C4,C13,-C3),M(-C4,C13,C3),M(-C4,-C13,-C3),M(C0,C8,C12),M(C0,-C8,-C12),M(-C0,-C8,C12),M(-C0,C8,-C12),M(C12,C0,C8),M(C12,-C0,-C8),M(-C12,-C0,C8),M(-C12,C0,-C8),M(C8,C12,C0),M(C8,-C12,-C0),M(-C8,-C12,C0),M(-C8,C12,-C0),M(C7,C6,C11),M(C7,-C6,-C11),M(-C7,-C6,C11),M(-C7,C6,-C11),M(C11,C7,C6),M(C11,-C7,-C6),M(-C11,-C7,C6),M(-C11,C7,-C6),M(C6,C11,C7),M(C6,-C11,-C7),M(-C6,-C11,C7),M(-C6,C11,-C7),M(C9,-C5,C10),M(C9,C5,-C10),M(-C9,C5,C10),M(-C9,-C5,-C10),M(C10,-C9,C5),M(C10,C9,-C5),M(-C10,C9,C5),M(-C10,-C9,-C5),M(C5,-C10,C9),M(C5,C10,-C9),M(-C5,C10,C9),M(-C5,-C10,-C9)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,13,49,29,37},{2,14,50,30,38},{3,15,51,31,39},{4,16,52,32,40},{5,18,54,33,41},{6,17,53,34,42},{7,20,56,35,43},{8,19,55,36,44},{9,23,59,25,45},{10,24,60,26,46},{11,21,57,27,47},{12,22,58,28,48},{1,15,3},{2,16,4},{3,13,1},{4,14,2},{5,17,6},{6,18,5},{7,19,8},{8,20,7},{9,22,12},{10,21,11},{11,24,10},{12,23,9},{13,57,49},{14,58,50},{15,59,51},{16,60,52},{17,49,53},{18,50,54},{19,51,55},{20,52,56},{21,53,57},{22,54,58},{23,55,59},{24,56,60},{25,37,45},{26,38,46},{27,39,47},{28,40,48},{29,41,37},{30,42,38},{31,43,39},{32,44,40},{33,45,41},{34,46,42},{35,47,43},{36,48,44},{37,25,1},{38,26,2},{39,27,3},{40,28,4},{41,29,5},{42,30,6},{43,31,7},{44,32,8},{45,33,9},{46,34,10},{47,35,11},{48,36,12},{49,17,29},{50,18,30},{51,19,31},{52,20,32},{53,21,34},{54,22,33},{55,23,36},{56,24,35},{57,13,27},{58,14,28},{59,15,25},{60,16,26},{25,15,1},{26,16,2},{27,13,3},{28,14,4},{29,17,5},{30,18,6},{31,19,7},{32,20,8},{33,22,9},{34,21,10},{35,24,11},{36,23,12},{37,41,45},{38,42,46},{39,43,47},{40,44,48},{49,57,53},{50,58,54},{51,59,55},{52,60,56}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,12)), ld.getfacet(T,ld.range(13,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.truncatedcube(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = (1 + math.sqrt(2)) / 2 local T = {} local L = {M(C0,0.5,C0),M(C0,0.5,-C0),M(C0,-0.5,C0),M(C0,-0.5,-C0),M(-C0,0.5,C0),M(-C0,0.5,-C0),M(-C0,-0.5,C0),M(-C0,-0.5,-C0),M(C0,C0,0.5),M(C0,C0,-0.5),M(C0,-C0,0.5),M(C0,-C0,-0.5),M(-C0,C0,0.5),M(-C0,C0,-0.5),M(-C0,-C0,0.5),M(-C0,-C0,-0.5),M(0.5,C0,C0),M(0.5,C0,-C0),M(0.5,-C0,C0),M(0.5,-C0,-C0),M(-0.5,C0,C0),M(-0.5,C0,-C0),M(-0.5,-C0,C0),M(-0.5,-C0,-C0)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,3,11,12,4,2,10,9},{1,17,21,5,7,23,19,3},{13,14,6,8,16,15,7,5},{13,21,17,9,10,18,22,14},{20,24,8,6,22,18,2,4},{20,12,11,19,23,15,16,24},{1,9,17},{2,18,10},{3,19,11},{4,12,20},{5,21,13},{6,14,22},{7,15,23},{8,24,16}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,6)), ld.getfacet(T,ld.range(7,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.truncatedcuboctahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = (1 + math.sqrt(2)) / 2 local C1 = (1 + 2 * math.sqrt(2)) / 2 local T = {} local L = {M(C0,0.5,C1),M(C0,0.5,-C1),M(C0,-0.5,C1),M(C0,-0.5,-C1),M(-C0,0.5,C1),M(-C0,0.5,-C1),M(-C0,-0.5,C1),M(-C0,-0.5,-C1),M(C1,C0,0.5),M(C1,C0,-0.5),M(C1,-C0,0.5),M(C1,-C0,-0.5),M(-C1,C0,0.5),M(-C1,C0,-0.5),M(-C1,-C0,0.5),M(-C1,-C0,-0.5),M(0.5,C1,C0),M(0.5,C1,-C0),M(0.5,-C1,C0),M(0.5,-C1,-C0),M(-0.5,C1,C0),M(-0.5,C1,-C0),M(-0.5,-C1,C0),M(-0.5,-C1,-C0),M(0.5,C0,C1),M(0.5,C0,-C1),M(0.5,-C0,C1),M(0.5,-C0,-C1),M(-0.5,C0,C1),M(-0.5,C0,-C1),M(-0.5,-C0,C1),M(-0.5,-C0,-C1),M(C1,0.5,C0),M(C1,0.5,-C0),M(C1,-0.5,C0),M(C1,-0.5,-C0),M(-C1,0.5,C0),M(-C1,0.5,-C0),M(-C1,-0.5,C0),M(-C1,-0.5,-C0),M(C0,C1,0.5),M(C0,C1,-0.5),M(C0,-C1,0.5),M(C0,-C1,-0.5),M(-C0,C1,0.5),M(-C0,C1,-0.5),M(-C0,-C1,0.5),M(-C0,-C1,-0.5)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,25,29,5,7,31,27,3},{2,4,28,32,8,6,30,26},{9,33,35,11,12,36,34,10},{13,14,38,40,16,15,39,37},{17,41,42,18,22,46,45,21},{19,23,47,48,24,20,44,43},{1,33,9,41,17,25},{2,26,18,42,10,34},{3,27,19,43,11,35},{4,36,12,44,20,28},{5,29,21,45,13,37},{6,38,14,46,22,30},{7,39,15,47,23,31},{8,32,24,48,16,40},{1,3,35,33},{2,34,36,4},{5,37,39,7},{6,8,40,38},{9,10,42,41},{11,43,44,12},{13,45,46,14},{15,16,48,47},{17,21,29,25},{18,26,30,22},{19,27,31,23},{20,24,32,28}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,6)), ld.getfacet(T,ld.range(7,14)), ld.getfacet(T,ld.range(15,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.truncateddodecahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = (3 + math.sqrt(5)) / 4 local C1 = (1 + math.sqrt(5)) / 2 local C2 = (2 + math.sqrt(5)) / 2 local C3 = (3 + math.sqrt(5)) / 2 local C4 = (5 + 3 * math.sqrt(5)) / 4 local T = {} local L = {M(0.0,0.5,C4),M(0.0,0.5,-C4),M(0.0,-0.5,C4),M(0.0,-0.5,-C4),M(C4,0.0,0.5),M(C4,0.0,-0.5),M(-C4,0.0,0.5),M(-C4,0.0,-0.5),M(0.5,C4,0.0),M(0.5,-C4,0.0),M(-0.5,C4,0.0),M(-0.5,-C4,0.0),M(0.5,C0,C3),M(0.5,C0,-C3),M(0.5,-C0,C3),M(0.5,-C0,-C3),M(-0.5,C0,C3),M(-0.5,C0,-C3),M(-0.5,-C0,C3),M(-0.5,-C0,-C3),M(C3,0.5,C0),M(C3,0.5,-C0),M(C3,-0.5,C0),M(C3,-0.5,-C0),M(-C3,0.5,C0),M(-C3,0.5,-C0),M(-C3,-0.5,C0),M(-C3,-0.5,-C0),M(C0,C3,0.5),M(C0,C3,-0.5),M(C0,-C3,0.5),M(C0,-C3,-0.5),M(-C0,C3,0.5),M(-C0,C3,-0.5),M(-C0,-C3,0.5),M(-C0,-C3,-0.5),M(C0,C1,C2),M(C0,C1,-C2),M(C0,-C1,C2),M(C0,-C1,-C2),M(-C0,C1,C2),M(-C0,C1,-C2),M(-C0,-C1,C2),M(-C0,-C1,-C2),M(C2,C0,C1),M(C2,C0,-C1),M(C2,-C0,C1),M(C2,-C0,-C1),M(-C2,C0,C1),M(-C2,C0,-C1),M(-C2,-C0,C1),M(-C2,-C0,-C1),M(C1,C2,C0),M(C1,C2,-C0),M(C1,-C2,C0),M(C1,-C2,-C0),M(-C1,C2,C0),M(-C1,C2,-C0),M(-C1,-C2,C0),M(-C1,-C2,-C0)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,3,15,39,47,23,21,45,37,13},{2,4,20,44,52,28,26,50,42,18},{3,1,17,41,49,25,27,51,43,19},{4,2,14,38,46,22,24,48,40,16},{5,6,22,46,54,30,29,53,45,21},{6,5,23,47,55,31,32,56,48,24},{7,8,28,52,60,36,35,59,51,27},{8,7,25,49,57,33,34,58,50,26},{9,11,33,57,41,17,13,37,53,29},{10,12,36,60,44,20,16,40,56,32},{11,9,30,54,38,14,18,42,58,34},{12,10,31,55,39,15,19,43,59,35},{1,13,17},{2,18,14},{3,19,15},{4,16,20},{5,21,23},{6,24,22},{7,27,25},{8,26,28},{9,29,30},{10,32,31},{11,34,33},{12,35,36},{37,45,53},{38,54,46},{39,55,47},{40,48,56},{41,57,49},{42,50,58},{43,51,59},{44,60,52}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,12)), ld.getfacet(T,ld.range(13,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.truncatedicosahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = (1 + math.sqrt(5)) / 4 local C1 = (1 + math.sqrt(5)) / 2 local C2 = (5 + math.sqrt(5)) / 4 local C3 = (2 + math.sqrt(5)) / 2 local C4 = 3 * (1 + math.sqrt(5)) / 4 local T = {} local L = {M(0.5,0.0,C4),M(0.5,0.0,-C4),M(-0.5,0.0,C4),M(-0.5,0.0,-C4),M(C4,0.5,0.0),M(C4,-0.5,0.0),M(-C4,0.5,0.0),M(-C4,-0.5,0.0),M(0.0,C4,0.5),M(0.0,C4,-0.5),M(0.0,-C4,0.5),M(0.0,-C4,-0.5),M(1.0,C0,C3),M(1.0,C0,-C3),M(1.0,-C0,C3),M(1.0,-C0,-C3),M(-1.0,C0,C3),M(-1.0,C0,-C3),M(-1.0,-C0,C3),M(-1.0,-C0,-C3),M(C3,1.0,C0),M(C3,1.0,-C0),M(C3,-1.0,C0),M(C3,-1.0,-C0),M(-C3,1.0,C0),M(-C3,1.0,-C0),M(-C3,-1.0,C0),M(-C3,-1.0,-C0),M(C0,C3,1.0),M(C0,C3,-1.0),M(C0,-C3,1.0),M(C0,-C3,-1.0),M(-C0,C3,1.0),M(-C0,C3,-1.0),M(-C0,-C3,1.0),M(-C0,-C3,-1.0),M(0.5,C1,C2),M(0.5,C1,-C2),M(0.5,-C1,C2),M(0.5,-C1,-C2),M(-0.5,C1,C2),M(-0.5,C1,-C2),M(-0.5,-C1,C2),M(-0.5,-C1,-C2),M(C2,0.5,C1),M(C2,0.5,-C1),M(C2,-0.5,C1),M(C2,-0.5,-C1),M(-C2,0.5,C1),M(-C2,0.5,-C1),M(-C2,-0.5,C1),M(-C2,-0.5,-C1),M(C1,C2,0.5),M(C1,C2,-0.5),M(C1,-C2,0.5),M(C1,-C2,-0.5),M(-C1,C2,0.5),M(-C1,C2,-0.5),M(-C1,-C2,0.5),M(-C1,-C2,-0.5)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,3,19,43,39,15},{2,4,18,42,38,14},{3,1,13,37,41,17},{4,2,16,40,44,20},{5,6,24,48,46,22},{6,5,21,45,47,23},{7,8,27,51,49,25},{8,7,26,50,52,28},{9,10,34,58,57,33},{10,9,29,53,54,30},{11,12,32,56,55,31},{12,11,35,59,60,36},{13,45,21,53,29,37},{14,38,30,54,22,46},{15,39,31,55,23,47},{16,48,24,56,32,40},{17,41,33,57,25,49},{18,50,26,58,34,42},{19,51,27,59,35,43},{20,44,36,60,28,52},{1,15,47,45,13},{2,14,46,48,16},{3,17,49,51,19},{4,20,52,50,18},{5,22,54,53,21},{6,23,55,56,24},{7,25,57,58,26},{8,28,60,59,27},{9,33,41,37,29},{10,30,38,42,34},{11,31,39,43,35},{12,36,44,40,32}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,20)), ld.getfacet(T,ld.range(21,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.truncatedicosidodecahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = (3 + math.sqrt(5)) / 4 local C1 = (1 + math.sqrt(5)) / 2 local C2 = (5 + math.sqrt(5)) / 4 local C3 = (2 + math.sqrt(5)) / 2 local C4 = 3 * (1 + math.sqrt(5)) / 4 local C5 = (3 + math.sqrt(5)) / 2 local C6 = (5 + 3 * math.sqrt(5)) / 4 local C7 = (4 + math.sqrt(5)) / 2 local C8 = (7 + 3 * math.sqrt(5)) / 4 local C9 = (3 + 2 * math.sqrt(5)) / 2 local T = {} local L = {M(0.5,0.5,C9),M(0.5,0.5,-C9),M(0.5,-0.5,C9),M(0.5,-0.5,-C9),M(-0.5,0.5,C9),M(-0.5,0.5,-C9),M(-0.5,-0.5,C9),M(-0.5,-0.5,-C9),M(C9,0.5,0.5),M(C9,0.5,-0.5),M(C9,-0.5,0.5),M(C9,-0.5,-0.5),M(-C9,0.5,0.5),M(-C9,0.5,-0.5),M(-C9,-0.5,0.5),M(-C9,-0.5,-0.5),M(0.5,C9,0.5),M(0.5,C9,-0.5),M(0.5,-C9,0.5),M(0.5,-C9,-0.5),M(-0.5,C9,0.5),M(-0.5,C9,-0.5),M(-0.5,-C9,0.5),M(-0.5,-C9,-0.5),M(1.0,C0,C8),M(1.0,C0,-C8),M(1.0,-C0,C8),M(1.0,-C0,-C8),M(-1.0,C0,C8),M(-1.0,C0,-C8),M(-1.0,-C0,C8),M(-1.0,-C0,-C8),M(C8,1.0,C0),M(C8,1.0,-C0),M(C8,-1.0,C0),M(C8,-1.0,-C0),M(-C8,1.0,C0),M(-C8,1.0,-C0),M(-C8,-1.0,C0),M(-C8,-1.0,-C0),M(C0,C8,1.0),M(C0,C8,-1.0),M(C0,-C8,1.0),M(C0,-C8,-1.0),M(-C0,C8,1.0),M(-C0,C8,-1.0),M(-C0,-C8,1.0),M(-C0,-C8,-1.0),M(0.5,C3,C7),M(0.5,C3,-C7),M(0.5,-C3,C7),M(0.5,-C3,-C7),M(-0.5,C3,C7),M(-0.5,C3,-C7),M(-0.5,-C3,C7),M(-0.5,-C3,-C7),M(C7,0.5,C3),M(C7,0.5,-C3),M(C7,-0.5,C3),M(C7,-0.5,-C3),M(-C7,0.5,C3),M(-C7,0.5,-C3),M(-C7,-0.5,C3),M(-C7,-0.5,-C3),M(C3,C7,0.5),M(C3,C7,-0.5),M(C3,-C7,0.5),M(C3,-C7,-0.5),M(-C3,C7,0.5),M(-C3,C7,-0.5),M(-C3,-C7,0.5),M(-C3,-C7,-0.5),M(C2,C1,C6),M(C2,C1,-C6),M(C2,-C1,C6),M(C2,-C1,-C6),M(-C2,C1,C6),M(-C2,C1,-C6),M(-C2,-C1,C6),M(-C2,-C1,-C6),M(C6,C2,C1),M(C6,C2,-C1),M(C6,-C2,C1),M(C6,-C2,-C1),M(-C6,C2,C1),M(-C6,C2,-C1),M(-C6,-C2,C1),M(-C6,-C2,-C1),M(C1,C6,C2),M(C1,C6,-C2),M(C1,-C6,C2),M(C1,-C6,-C2),M(-C1,C6,C2),M(-C1,C6,-C2),M(-C1,-C6,C2),M(-C1,-C6,-C2),M(C0,C4,C5),M(C0,C4,-C5),M(C0,-C4,C5),M(C0,-C4,-C5),M(-C0,C4,C5),M(-C0,C4,-C5),M(-C0,-C4,C5),M(-C0,-C4,-C5),M(C5,C0,C4),M(C5,C0,-C4),M(C5,-C0,C4),M(C5,-C0,-C4),M(-C5,C0,C4),M(-C5,C0,-C4),M(-C5,-C0,C4),M(-C5,-C0,-C4),M(C4,C5,C0),M(C4,C5,-C0),M(C4,-C5,C0),M(C4,-C5,-C0),M(-C4,C5,C0),M(-C4,C5,-C0),M(-C4,-C5,C0),M(-C4,-C5,-C0)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,3,27,75,107,59,57,105,73,25},{2,26,74,106,58,60,108,76,28,4},{5,29,77,109,61,63,111,79,31,7},{6,8,32,80,112,64,62,110,78,30},{9,10,34,82,114,66,65,113,81,33},{11,35,83,115,67,68,116,84,36,12},{13,37,85,117,69,70,118,86,38,14},{15,16,40,88,120,72,71,119,87,39},{17,21,45,93,101,53,49,97,89,41},{18,42,90,98,50,54,102,94,46,22},{19,43,91,99,51,55,103,95,47,23},{20,24,48,96,104,56,52,100,92,44},{1,25,49,53,29,5},{2,6,30,54,50,26},{3,7,31,55,51,27},{4,28,52,56,32,8},{9,33,57,59,35,11},{10,12,36,60,58,34},{13,15,39,63,61,37},{14,38,62,64,40,16},{17,41,65,66,42,18},{19,20,44,68,67,43},{21,22,46,70,69,45},{23,47,71,72,48,24},{73,105,81,113,89,97},{74,98,90,114,82,106},{75,99,91,115,83,107},{76,108,84,116,92,100},{77,101,93,117,85,109},{78,110,86,118,94,102},{79,111,87,119,95,103},{80,104,96,120,88,112},{1,5,7,3},{2,4,8,6},{9,11,12,10},{13,14,16,15},{17,18,22,21},{19,23,24,20},{25,73,97,49},{26,50,98,74},{27,51,99,75},{28,76,100,52},{29,53,101,77},{30,78,102,54},{31,79,103,55},{32,56,104,80},{33,81,105,57},{34,58,106,82},{35,59,107,83},{36,84,108,60},{37,61,109,85},{38,86,110,62},{39,87,111,63},{40,64,112,88},{41,89,113,65},{42,66,114,90},{43,67,115,91},{44,92,116,68},{45,69,117,93},{46,94,118,70},{47,95,119,71},{48,72,120,96}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,12)), ld.getfacet(T,ld.range(13,32)), ld.getfacet(T,ld.range(33,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.truncatedoctahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = math.sqrt(2) / 2 local C1 = math.sqrt(2) local T = {} local L = {M(C0,0.0,C1),M(C0,0.0,-C1),M(-C0,0.0,C1),M(-C0,0.0,-C1),M(C1,C0,0.0),M(C1,-C0,0.0),M(-C1,C0,0.0),M(-C1,-C0,0.0),M(0.0,C1,C0),M(0.0,C1,-C0),M(0.0,-C1,C0),M(0.0,-C1,-C0),M(0.0,C0,C1),M(0.0,C0,-C1),M(0.0,-C0,C1),M(0.0,-C0,-C1),M(C1,0.0,C0),M(C1,0.0,-C0),M(-C1,0.0,C0),M(-C1,0.0,-C0),M(C0,C1,0.0),M(C0,-C1,0.0),M(-C0,C1,0.0),M(-C0,-C1,0.0)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,15,11,22,6,17},{2,14,10,21,5,18},{3,13,9,23,7,19},{4,16,12,24,8,20},{5,21,9,13,1,17},{6,22,12,16,2,18},{8,24,11,15,3,19},{7,23,10,14,4,20},{1,13,3,15},{2,16,4,14},{5,17,6,18},{7,20,8,19},{9,21,10,23},{11,24,12,22}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,8)), ld.getfacet(T,ld.range(9,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.truncatedtetrahedron(C,S,all) -- de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes (liste) avec points 3d -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local C0 = math.sqrt(2) / 4 local C1 = 3 * math.sqrt(2) / 4 local T = {} local L = {M(C0,-C0,C1),M(C0,C0,-C1),M(-C0,C0,C1),M(-C0,-C0,-C1),M(C1,-C0,C0),M(C1,C0,-C0),M(-C1,C0,C0),M(-C1,-C0,-C0),M(C0,-C1,C0),M(C0,C1,-C0),M(-C0,C1,C0),M(-C0,-C1,-C0)} L = transf(L, Origin, L[1], C, S) T.vertices = L T.facets = {{1,5,6,10,11,3},{2,6,5,9,12,4},{3,7,8,12,9,1},{4,8,7,11,10,2},{1,9,5},{2,10,6},{3,11,7},{4,12,8}} if all then local A = ld.facetedges( ld.poly2facet(T) ) local n = #T.facets return T, T.vertices, A, ld.getfacet(T,ld.range(1,4)), ld.getfacet(T,ld.range(5,n)) -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end -- fin solides d'Archimède function poly.octahemioctahedron(C,S,all) -- construction d'un Octahémioctaèdre de centre C de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes de type 1, les facettes de type 2 -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local L = {M(1,1,0),M(1,-1,0),M(-1,1,0),M(-1,-1,0),M(1,0,1),M(1,0,-1),M(-1,0,1),M(-1,0,-1),M(0,1,1),M(0,1,-1),M(0,-1,1),M(0,-1,-1)} L = transf(L, Origin, L[1], C, S) local T, F1, F2 = {}, {{1,9,5},{1,6,10},{2,5,11},{2,12,6},{3,7,9},{3,10,8},{4,8,12},{4,11,7}}, {{1,5,11,4,8,10},{1,9,7,4,12,6},{2,5,9,3,8,12},{2,6,10,3,7,11}} T.vertices = L T.facets = concat(F1,F2) if all then F1 = ld.poly2facet( {["vertices"]=L, ["facets"]=F1} ) F2 = ld.poly2facet( {["vertices"]=L, ["facets"]=F2} ) A = ld.facetedges( ld.poly2facet(T) ) return T, T.vertices, A, F1, F2 -- polyèdre, sommets, arêtes, faces type 1, faces type 2 else return T end end function poly.Octahemioctaedre(C,S,all) --compatibilité ascendante return poly.octahemioctahedron(C,S,all) end function poly.small_stellated_dodecahedron(Cter,S,all) -- construction d'un Petit dodécaèdre étoilé de centre Cter de sommet S -- si all vaut true, on renvoie dans cet ordre : -- le polyèdre, les sommets, les arêtes (ligne polygonale), les facettes -- si all vaut false (valeur par défaut) on renvoie seulement le polyèdre all = all or false local sqrt = math.sqrt local A1 = sqrt((5+sqrt(5))/10) local A2 = sqrt((5-sqrt(5))/10) local B1 = A1^2 local B2 = A2^2 local C = sqrt(5)/5 local M1 = M(0,1,0) local M2 = M(A2,C,-B1) local M3 = M(-A2,C,-B1) local M4 = M(-A1,C,B2) local M5 = M(0,C,2*C) local M6 = M(A1,C,B2) local M7, M8, M9, M10, M11, M12 = -M3, -M2, -M6, -M5, -M4, -M1 local L = {M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12} L = transf(L, Origin, L[2], Cter, S) local T = {} T.vertices = L T.facets ={{2,4,6,3,5}, {1,9,5,3,8}, {1,7,2,5,11}, {7,9,11,8,10}, {2,7,10,6,12}, {3,12,4,10,8}, {2,12,3,11,9}, {1,10,4,2,9}, {1,11,3,6,10}, {4,12,5,9,7}, {5,12,6,8,11}, {1,8,6,4,7}} if all then local F = pstar(ld.poly2facet(T)) -- facettes avec points 3d local A = ld.facetedges(T) -- arêtes (ligne polygonale) return T, T.vertices, A, F -- polyèdre, sommets, arêtes, faces else return T end end function poly.PtDodecaedreEt(Cter,S,all) --compatibilité ascendante return poly.small_stellated_dodecahedron(Cter,S,all) end return poly