[PYTHON] Créer des données de polyèdre régulières

Je veux des données de polyèdre régulières. Cela semble facile à faire, mais vu comment le faire, cela ne semble pas facile. J'ai essayé de créer un programme, mais cela ressemble à une corde boueuse.

Méthode de génération

Créez des données pour un polyèdre régulier sur une sphère avec des sommets de rayon 1.

Les seuls tableaux pour les polyèdres réguliers ($ M ) sont "le nombre de coins d'une face ( N )" et "le nombre de faces touchant les sommets ( F $)".

Trouvez la normale de la surface

Soit le premier sommet $ \ left (0,0,1 \ right) $ et visons à générer les arêtes des faces tangentes.

Trouvez le prochain sommet $ \ left (sin \ \ theta, \ theta, cos \ \ theta \ right) $ et faites pivoter le plan x-y pour le diviser en "le nombre de faces tangentes".

Ensuite, le troisième est $ \ left (sin \ \ theta \ cos \ \ phi, \ sin \ \ theta \ cos \ \ phi, \ cos \ \ theta \ right) $.

$ \ phi $ peut être obtenu à partir du "nombre de faces en contact ($ F $)".

$ \ Theta $ peut être calculé à partir de 3 sommets, mais il doit être calculé avant de créer les sommets.


\begin{eqnarray}
\phi & = & \frac{2\pi}{F} \\
P_1 & = & (0, 0, 1) \\
P_2 & = & (sin \theta, 0, cos \theta) \\
P_3 & = & (sin \theta\ cos \phi, sin \theta\ sin \phi, cos \theta) \\
L_1 & = & P_2 - P_1 \\
L_2 & = & P_3 - P_1 \\
\frac{L_1 \cdot L_2}{|L_1||L_2|} & = & cos \frac{ \pi \left( N-2 \right) }{N} \\
cos \theta & = & \left( cos^2 \frac{\pi}{F} - cos \frac{ \pi \left( N-2 \right) }{N} \right)\ csc^2 \frac{\pi}{F} \\
\end{eqnarray}

Comme, trouvez $ cos \ \ theta $ à partir de $ N, F $. Si vous trouvez les trois sommets, la première "face normale" est le produit extérieur


N_1 = \frac{L_1 \times L_2}{ \left| L_1 \times L_2 \right|}

Par conséquent, si cette ligne normale est tournée autour du plan x-y d'un angle de $ \ phi $, $ F $ de "lignes normales de face" peut être obtenue.

Puisque la distance entre le centre du polyèdre régulier et la face est le produit intérieur du premier sommet $ P_1 $ et de la normale de la première face $ N_1 $.


\begin{eqnarray}
P_1 & = & \left( 0, 0, 1 \right) \\
N_1 & = & \left( n_x\ , n_y\ , n_z \right) \\
n_z & = & P_1 \cdot N_1 = D \\
\end{eqnarray}

Demandez comme. Vous pouvez utiliser la valeur de $ \ left (n_z = D \ right) $ pour la normale pour créer une expression de visage.

Trouvez les normales de tous les visages

Puisque trois normales ou plus ont été obtenues, la relation entre deux normales adjacentes $ N_1, N_2 $ et la normale adjacente $ N_3 $ est


\begin{eqnarray}
n_x & = & N_1 \\
n_y & = & \frac{ n_x \times N_2 }{ \left| n_x \times N_2 \right| } \\
n_z & = & \frac{ n_x \times n_y }{ \left| n_x \times n_y \right| } \\
X_{cos} & = & n_x \cdot N_3 \\
Y_{cos} & = & n_y \cdot N_3 \\
Z_{cos} & = & n_z \cdot N_3 \\
\end{eqnarray}

Peut être. Maintenant, à partir des deux normales adjacentes $ N_1, N_2 $, une nouvelle normale $ N_3 $ est créée.


\begin{eqnarray}
n_x & = & N_1 \\
n_y & = & \frac{ n_x \times N_2 }{ \left| n_x \times N_2 \right| } \\
n_z & = & \frac{ n_y \times n_y }{ \left| n_x \times n_y \right| } \\
N_3 & = & X_{cos}\ n_x + Y_{cos}\ n_y + Z_{cos}\ n_z \\
\end{eqnarray}

Est requis à.

En arrondissant les deux normales, recherchez une nouvelle normale, éliminez la duplication, et si elle n'augmente pas, le but est atteint.

Trouvez le sommet

L'intersection de deux normales adjacentes $ N_1, N_2 $ et le plan formé par la distance $ D $ du centre (origine) du polyèdre régulier au plan passe par les "côtés du polyèdre régulier". L'intersection de cette intersection et d'une sphère d'un rayon de $ 1 $ est le sommet souhaité.

La direction de l'intersection est le produit extérieur des deux normales


L_V = \frac{ N_1 \times N_2 }{ \left| N_1 \times N_2 \right| }

Il peut être trouvé par. Puisque nous voulons que le point de base de l'intersection soit le "centre du côté", nous voulons la droite $ L_C $ qui passe entre les deux normales et l'intersection $ L_P $ de la surface


\begin{eqnarray}
L_C & = & \frac{ N_1 + N_2 }{ \left| N_1 + N_2 \right| } \\
cos\ \theta_{L} & = & L_C \cdot N_1 = L_C \cdot N_2 \\
L_P & = & \frac{D}{cos\ \theta_{L}} L_C
\end{eqnarray}

Je vais le demander.\left| L_P \right|Est la distance de l'origine au sommet1Contre


cos\ \theta_P = \left| L_P \right|

Donc, la distance de $ L_P $ au sommet est


L_D = sin\ \theta_P = \sqrt{1 - cos^2\theta_P} = \sqrt{1 - \left( L_P \cdot L_P \right) }

Ce sera. C'est dans "Trouver la normale de la surface"\left| L_1 \right|Parce que c'est la moitié de


L_D = \frac{ \left| L_1 \right| }{2}

Vous pouvez également. (Le programme reste l'ancien)

Étant donné que les sommets souhaités sont régulièrement espacés du centre du côté


V = L_P \pm L_D L_V

Sera.

Comme pour "toutes les normales", trouvez les côtés et les sommets en arrondissant les deux normales.

Après cela, les données sont préparées et terminées.

Programme et résultat de sortie

Programme Python de génération de données de polyèdre régulier

import math

flag_debug = False
flag_verbose = False
flag_rotate = False

paren_c = ('{', '}')
paren_vec = ('(', ')')
paren_out = ('(', ')')
paren_list = ('(', ')')

#Données de polyèdre régulier
#Nombre de faces: (Nombre d'angles de face,Nombre de points de contact des sommets)
RP_TAB = {
    +4: (3, 3),
    +6: (4, 3),
    +8: (3, 4),
    12: (5, 3),
    20: (3, 5),
}

FP_THR = 1.0 / 1024  #Plage d'erreur de calcul admissible au moment du jugement

def cos_sin(r): return (math.cos(r), math.sin(r))

def vec_dump(v): return (paren_vec[0] + (' %+8.6f, %+8.6f, %+8.6f ' % tuple(v)) + paren_vec[1])
def vec_add(a, b): return (a[0] + b[0], a[1] + b[1], a[2] + b[2])
def vec_sub(a, b): return (a[0] - b[0], a[1] - b[1], a[2] - b[2])
def vec_mul(a, b): return (a[0] * b,    a[1] * b,    a[2] * b)

def vec_inner(a, b): #produit intérieur
    return (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])

def vec_cross(a, b): #Produit extérieur
    c1 = a[1] * b[2] - a[2] * b[1]
    c2 = a[2] * b[0] - a[0] * b[2]
    c3 = a[0] * b[1] - a[1] * b[0]
    return (c1, c2, c3)

def vec_cross_normalize(a, b): #Produit extérieur et normalisation
    return vec_normalize(vec_cross(a, b))

def vec_normalize(a): #Normalisation
    return vec_mul(a, 1.0 / math.sqrt(vec_inner(a, a)))

# X-Rotation dans le plan Y
def vec_rot_xy(v, r):
    c, s = cos_sin(r)
    x = v[0] * c - v[1] * s
    y = v[0] * s + v[1] * c
    return (x, y, v[2])

#Ajouter des données vectorielles(Élimine la duplication)
def vec_append(l, v):
    r = len(l)
    for n in range(r):
        c = vec_inner(v, l[n])
        if c >= (1.0 - FP_THR):
            return n
        continue
    l.append(v)
    return r

#Création de données polyèdres régulières
def make(F):          # F =Nombre de faces
    P = RP_TAB[F][0]  # P =Nombre d'angles de face
    K = RP_TAB[F][1]  # K =Nombre de points de contact des sommets
    E = F * P / 2     # E =Nombre de côtés
    V = E - F + 2     # V =Nombre de sommets

    if flag_verbose:
        print('Nombre de faces: %d' % F)
        print('Nombre de côtés: %d' % E)
        print('Nombre de sommets: %d' % V)
        pass

    #Un tour avec le nombre de surfaces de contact des sommets
    rK1 = math.pi     / K   # rK1 =  π / K
    rK2 = math.pi * 2 / K   # rK2 = 2π / K
    cK1, sK1 = cos_sin(rK1)
    cK2, sK2 = cos_sin(rK2)

    #Éléments liés aux polygones
    rP = math.pi * (P - 2) / P  # rP = π(P-2) / P
    cP, sP = cos_sin(rP)

    #Éléments liés aux côtés et aux angles centraux
    cR = (cK1 * cK1 - cP) / (sK1 * sK1)
    sR = math.sqrt(1 - cR * cR)

    #Trouvez les normales des trois faces
    p1 = (0, 0, 1)
    p2 = (sR, 0, cR)
    p3 = (sR * cK2, sR * sK2, cR)
    l1 = vec_sub(p2, p1)
    l2 = vec_sub(p3, p1)
    n0 = vec_cross_normalize(l1, l2)
    n1 = vec_rot_xy(n0, rK2 * 1)
    n2 = vec_rot_xy(n0, rK2 * 2)

    cD = n0[2]  # cD =Distance du centre au plan
    sD = math.sqrt(1 - cD * cD)

    #Trouver l'élément d'angle des faces adjacentes
    ny = vec_cross_normalize(n0, n1)
    nz = vec_cross_normalize(n0, ny)
    N_cos = vec_inner(n0, n1)
    X_cos = vec_inner(n0, n2)
    Y_cos = vec_inner(ny, n2)
    Z_cos = vec_inner(nz, n2)

    #Corriger l'orientation du polyèdre régulier
    if P != 3 and flag_rotate:
        n0 = (0, 0, 1)
        ny = (cP, -sP, 0)
        nz = (sP,  cP, 0)
        ax = vec_mul(n0, X_cos)
        ay = vec_mul(ny, Y_cos)
        az = vec_mul(nz, Z_cos)
        n1 = vec_add(vec_add(ax, ay), az)
        pass

    #Trouvez les normales de tous les visages
    nl = [n0, n1]
    loop = True
    while loop:
        CF = len(nl)
        for s in range(CF-1):
            for e in range(s+1,CF):
                n0 = nl[s]
                n1 = nl[e]

                #Les faces n0 et n1 sont-elles adjacentes??
                nc = vec_inner(n0, n1)
                if abs(N_cos - nc) >= FP_THR:
                    continue

                #Ajout de faces adjacentes de n0 à n1
                ny = vec_cross_normalize(n0, n1)
                nz = vec_cross_normalize(n0, ny)
                ax = vec_mul(n0, X_cos)
                ay = vec_mul(ny, Y_cos)
                az = vec_mul(nz, Z_cos)
                na = vec_add(vec_add(ax, ay), az)
                vec_append(nl, na)
                continue
            continue
        loop = (CF != len(nl)) #C'est fini quand ça n'augmente pas
        continue

    #Trouver tous les côtés et sommets
    CF = len(nl)
    vl = []
    fl = {}
    for n in range(CF): fl[n] = []
    for s in range(CF):
        for e in range(s+1, CF):
            n0 = nl[s]
            n1 = nl[e]

            #Les faces n0 et n1 sont-elles adjacentes??
            nc = vec_inner(n0, n1)
            if abs(N_cos - nc) >= FP_THR: continue

            #Trouvez l'intersection de n0 et n1(Passer par le centre du côté)
            lc = vec_normalize(vec_add(n0, n1))
            lv = vec_cross_normalize(n0, n1)
            lp = vec_mul(lc, cD / vec_inner(n0, lc))

            #Trouvez l'intersection de l'intersection et une sphère avec un rayon de 1
            t0 = math.sqrt(1 - vec_inner(lp, lp))
            q1 = vec_add(vec_mul(lv, -t0), lp)
            q2 = vec_add(vec_mul(lv, +t0), lp)

            #Ajouter des données de sommet et d'arête
            i1 = vec_append(vl, q1)
            i2 = vec_append(vl, q2)
            fl[s].append((i1, i2))
            fl[e].append((i1, i2))
            continue
        continue

    #Organiser les données
    rl = []
    el = {}
    for f in range(len(fl)):
        vd = fl[f]

        #Données latérales pour le fil de fer
        for e in vd: el[e] = None

        #Rendre les données latérales disjointes continues(Polygonisation)
        vm = {}
        s, e = vd[0]
        vm[s] = e
        il = vd[1:]
        while len(il):
            for n in range(len(il)):
                p, q = il[n]
                if e == p:
                    vm[e] = q
                    e = q
                elif e == q:
                    vm[e] = p
                    e = p
                else:
                    continue
                del il[n]
                break
            continue

        s, e = vd[0]
        il = [s]
        while s != e:
            il.append(e)
            e = vm[e]
            continue

        #Polygone fixe normal
        nv = nl[f]
        p0 = vl[il[0]]
        p1 = vl[il[1]]
        p2 = vl[il[2]]
        v1 = vec_sub(p1, p0)
        v2 = vec_sub(p2, p1)
        pn = vec_cross(v1, v2)
        if vec_inner(nv, pn) < 0: il.reverse()

        rl.append((nv, il))
        continue

    return (vl, rl, el.keys())

#Fonction principale
def main(F):
    vl, fl, el = make(F)

    #Sortie des données de sommet
    m = ('VERTEX[%d] = ' % len(vl)) + paren_out[0] + '\n'
    for n in range(len(vl)):
        m = m + ('  %s,' % vec_dump(vl[n]))
        if not args.uncomment: m = m + ('  #%d' % n)
        m = m + '\n'
        continue
    m = m + paren_out[1]
    print(m)

    #Sortie des données normales
    if args.normal:
        m = ('NORMAL[%d] = ' % len(fl)) + paren_out[0] + '\n'
        for n in range(len(fl)):
            m = m + ('  %s,' % vec_dump(fl[n][0]))
            if not args.uncomment: m = m + ('  #%d' % n)
            m = m + '\n'
            continue
        m = m + paren_out[1]
        print(m)
        pass

    #Sortie des données de surface(Ordinaire,Liste des sommets)
    m = ('FACET[%d] = ' % len(fl)) + paren_out[0] + '\n'
    for n in range(len(fl)):
        if args.normal: m = m + ' '
        else: m = m + '  ' + vec_dump(fl[n][0]) + ','
        m = m + ' ' + paren_list[0]
        s = ''
        for i in fl[n][1]:
            m = m + ('%s %2d' % (s, i))
            s = ','
            continue
        m = m + ' ' + paren_list[1] + ','
        if not args.uncomment: m = m + ('  #%d' % n)
        m = m + '\n'
        continue
    m = m + paren_out[1]
    print(m)

    #Sortie des données de bord
    el = sorted(el)
    m = ('EDGE[%d] = ' % len(el)) + paren_out[0]
    for n in range(len(el)):
        if ((n & 3) == 0): m = m + '\n '
        m = m + (' %s %2d, %2d %s,' % (paren_list[0], el[n][0], el[n][1], paren_list[1]))
        continue
    m = m + '\n' + paren_out[1]
    print(m)

    return

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument('N', nargs='+', type=int, help='Nombre de faces={4|6|8|12|20}')
    parser.add_argument('-d', '--debug', action='store_true', help='Pour le débogage')
    parser.add_argument('-v', '--verbose', action='store_true', help='Sortie redondante')
    parser.add_argument('-r', '--rotate', action='store_true', help='6,Correction de l'orientation de la dodéca')
    parser.add_argument('-c', '--cparen', action='store_true', help='Changer les caractères entre parenthèses')
    parser.add_argument('-n', '--normal', action='store_true', help='Séparer les données normales')
    parser.add_argument('-u', '--uncomment', action='store_true', help='Éliminer l'index')
    args = parser.parse_args()

    flag_debug = args.debug
    flag_verbose = args.verbose
    flag_rotate = args.rotate

    if args.cparen:
        paren_vec = paren_c
        paren_out = paren_c
        paren_list = paren_c
        pass

    s = '-' * 72
    sep = (len(args.N) > 1)
    for N in args.N:
        if sep: print(s)
        if N in RP_TAB:
            main(N)
        else:
            print('N=%d :Nombre de pages non valide' % N)
            parser.print_help()
            pass
        continue
    if sep: print(s)
    pass

#Passe inutile, continue,le retour est la protection contre les indentations d'Emacs

Sortie: tétraèdre régulier

Nombre de faces: 4
Nombre de côtés: 6
Nombre de sommets: 4
VERTEX[4] = (
  ( +0.000000, +0.000000, +1.000000 ),  #0
  ( +0.942809, +0.000000, -0.333333 ),  #1
  ( -0.471405, +0.816497, -0.333333 ),  #2
  ( -0.471405, -0.816497, -0.333333 ),  #3
)
FACET[4] = (
  ( +0.471405, +0.816497, +0.333333 ), (  2,  0,  1 ),  #0
  ( -0.942809, +0.000000, +0.333333 ), (  3,  0,  2 ),  #1
  ( +0.471405, -0.816497, +0.333333 ), (  3,  1,  0 ),  #2
  ( +0.000000, -0.000000, -1.000000 ), (  3,  2,  1 ),  #3
)
EDGE[6] = (
  (  0,  1 ), (  1,  2 ), (  2,  0 ), (  2,  3 ),
  (  3,  0 ), (  3,  1 ),
)

Résultat de sortie: hexaèdre régulier

Nombre de faces: 6
Nombre de côtés: 12
Nombre de sommets: 8
VERTEX[8] = (
  ( +0.000000, +0.000000, +1.000000 ),  #0
  ( +0.942809, +0.000000, +0.333333 ),  #1
  ( -0.471405, +0.816497, +0.333333 ),  #2
  ( +0.471405, +0.816497, -0.333333 ),  #3
  ( -0.471405, -0.816497, +0.333333 ),  #4
  ( -0.942809, +0.000000, -0.333333 ),  #5
  ( +0.471405, -0.816497, -0.333333 ),  #6
  ( +0.000000, +0.000000, -1.000000 ),  #7
)
FACET[6] = (
  ( +0.408248, +0.707107, +0.577350 ), (  2,  0,  1,  3 ),  #0
  ( -0.816497, +0.000000, +0.577350 ), (  5,  4,  0,  2 ),  #1
  ( +0.408248, -0.707107, +0.577350 ), (  4,  6,  1,  0 ),  #2
  ( +0.816497, -0.000000, -0.577350 ), (  6,  7,  3,  1 ),  #3
  ( -0.408248, +0.707107, -0.577350 ), (  7,  5,  2,  3 ),  #4
  ( -0.408248, -0.707107, -0.577350 ), (  7,  6,  4,  5 ),  #5
)
EDGE[12] = (
  (  0,  1 ), (  1,  3 ), (  2,  0 ), (  2,  5 ),
  (  3,  2 ), (  4,  0 ), (  4,  6 ), (  5,  4 ),
  (  6,  1 ), (  6,  7 ), (  7,  3 ), (  7,  5 ),
)

*********Ce qui suit a la même orientation que l'axe spatial

Nombre de faces: 6
Nombre de côtés: 12
Nombre de sommets: 8
VERTEX[8] = (
  ( -0.577350, -0.577350, +0.577350 ),  #0
  ( +0.577350, -0.577350, +0.577350 ),  #1
  ( +0.577350, +0.577350, +0.577350 ),  #2
  ( -0.577350, +0.577350, +0.577350 ),  #3
  ( +0.577350, -0.577350, -0.577350 ),  #4
  ( -0.577350, -0.577350, -0.577350 ),  #5
  ( +0.577350, +0.577350, -0.577350 ),  #6
  ( -0.577350, +0.577350, -0.577350 ),  #7
)
FACET[6] = (
  ( +0.000000, +0.000000, +1.000000 ), (  0,  1,  2,  3 ),  #0
  ( -0.000000, -1.000000, +0.000000 ), (  5,  4,  1,  0 ),  #1
  ( +1.000000, -0.000000, +0.000000 ), (  4,  6,  2,  1 ),  #2
  ( +0.000000, +1.000000, +0.000000 ), (  6,  7,  3,  2 ),  #3
  ( -1.000000, +0.000000, +0.000000 ), (  7,  5,  0,  3 ),  #4
  ( -0.000000, -0.000000, -1.000000 ), (  7,  6,  4,  5 ),  #5
)
EDGE[12] = (
  (  0,  1 ), (  0,  5 ), (  1,  2 ), (  2,  3 ),
  (  3,  0 ), (  4,  1 ), (  4,  6 ), (  5,  4 ),
  (  6,  2 ), (  6,  7 ), (  7,  3 ), (  7,  5 ),
)

Résultat de sortie: Octaèdre régulier

Nombre de faces: 8
Nombre de côtés: 12
Nombre de sommets: 6
VERTEX[6] = (
  ( +0.000000, +0.000000, +1.000000 ),  #0
  ( +1.000000, +0.000000, +0.000000 ),  #1
  ( +0.000000, +1.000000, +0.000000 ),  #2
  ( -1.000000, +0.000000, +0.000000 ),  #3
  ( -0.000000, -1.000000, +0.000000 ),  #4
  ( +0.000000, -0.000000, -1.000000 ),  #5
)
FACET[8] = (
  ( +0.577350, +0.577350, +0.577350 ), (  2,  0,  1 ),  #0
  ( -0.577350, +0.577350, +0.577350 ), (  3,  0,  2 ),  #1
  ( -0.577350, -0.577350, +0.577350 ), (  4,  0,  3 ),  #2
  ( +0.577350, -0.577350, +0.577350 ), (  4,  1,  0 ),  #3
  ( +0.577350, -0.577350, -0.577350 ), (  5,  1,  4 ),  #4
  ( +0.577350, +0.577350, -0.577350 ), (  5,  2,  1 ),  #5
  ( -0.577350, +0.577350, -0.577350 ), (  5,  3,  2 ),  #6
  ( -0.577350, -0.577350, -0.577350 ), (  5,  4,  3 ),  #7
)
EDGE[12] = (
  (  0,  1 ), (  1,  2 ), (  2,  0 ), (  2,  3 ),
  (  3,  0 ), (  3,  4 ), (  4,  0 ), (  4,  1 ),
  (  4,  5 ), (  5,  1 ), (  5,  2 ), (  5,  3 ),
)

Sortie: Douze régulier

Nombre de faces: 12
Nombre de côtés: 30
Nombre de sommets: 20
VERTEX[20] = (
  ( +0.000000, +0.000000, +1.000000 ),  #0
  ( +0.666667, +0.000000, +0.745356 ),  #1
  ( -0.333333, +0.577350, +0.745356 ),  #2
  ( +0.745356, +0.577350, +0.333333 ),  #3
  ( +0.127322, +0.934172, +0.333333 ),  #4
  ( -0.333333, -0.577350, +0.745356 ),  #5
  ( -0.872678, +0.356822, +0.333333 ),  #6
  ( -0.872678, -0.356822, +0.333333 ),  #7
  ( +0.745356, -0.577350, +0.333333 ),  #8
  ( +0.127322, -0.934172, +0.333333 ),  #9
  ( +0.872678, +0.356822, -0.333333 ),  #10
  ( +0.872678, -0.356822, -0.333333 ),  #11
  ( -0.127322, +0.934172, -0.333333 ),  #12
  ( +0.333333, +0.577350, -0.745356 ),  #13
  ( -0.745356, +0.577350, -0.333333 ),  #14
  ( -0.745356, -0.577350, -0.333333 ),  #15
  ( -0.666667, +0.000000, -0.745356 ),  #16
  ( -0.127322, -0.934172, -0.333333 ),  #17
  ( +0.333333, -0.577350, -0.745356 ),  #18
  ( +0.000000, -0.000000, -1.000000 ),  #19
)
FACET[12] = (
  ( +0.303531, +0.525731, +0.794654 ), (  2,  0,  1,  3,  4 ),  #0
  ( -0.607062, +0.000000, +0.794654 ), (  6,  7,  5,  0,  2 ),  #1
  ( +0.303531, -0.525731, +0.794654 ), (  5,  9,  8,  1,  0 ),  #2
  ( +0.982247, -0.000000, +0.187592 ), (  8, 11, 10,  3,  1 ),  #3
  ( +0.491123, +0.850651, -0.187592 ), ( 10, 13, 12,  4,  3 ),  #4
  ( -0.491123, +0.850651, +0.187592 ), ( 12, 14,  6,  2,  4 ),  #5
  ( -0.982247, +0.000000, -0.187592 ), ( 14, 16, 15,  7,  6 ),  #6
  ( -0.491123, -0.850651, +0.187592 ), ( 15, 17,  9,  5,  7 ),  #7
  ( +0.491123, -0.850651, -0.187592 ), ( 17, 18, 11,  8,  9 ),  #8
  ( +0.607062, -0.000000, -0.794654 ), ( 18, 19, 13, 10, 11 ),  #9
  ( -0.303531, +0.525731, -0.794654 ), ( 19, 16, 14, 12, 13 ),  #10
  ( -0.303531, -0.525731, -0.794654 ), ( 19, 18, 17, 15, 16 ),  #11
)
EDGE[30] = (
  (  0,  1 ), (  1,  3 ), (  2,  0 ), (  2,  6 ),
  (  3,  4 ), (  4,  2 ), (  5,  0 ), (  5,  9 ),
  (  6,  7 ), (  7,  5 ), (  8,  1 ), (  8, 11 ),
  (  9,  8 ), ( 10,  3 ), ( 10, 13 ), ( 11, 10 ),
  ( 12,  4 ), ( 12, 14 ), ( 13, 12 ), ( 14,  6 ),
  ( 14, 16 ), ( 15,  7 ), ( 15, 17 ), ( 16, 15 ),
  ( 17,  9 ), ( 17, 18 ), ( 18, 11 ), ( 18, 19 ),
  ( 19, 13 ), ( 19, 16 ),
)

*********Ce qui suit a le même plan que l'orientation de l'axe Z

Nombre de faces: 12
Nombre de côtés: 30
Nombre de sommets: 20
VERTEX[20] = (
  ( -0.577350, -0.187592, +0.794654 ),  #0
  ( -0.000000, -0.607062, +0.794654 ),  #1
  ( +0.577350, -0.187592, +0.794654 ),  #2
  ( +0.356822, +0.491123, +0.794654 ),  #3
  ( -0.356822, +0.491123, +0.794654 ),  #4
  ( -0.000000, -0.982247, +0.187592 ),  #5
  ( -0.934172, -0.303531, +0.187592 ),  #6
  ( -0.577350, -0.794654, -0.187592 ),  #7
  ( +0.934172, -0.303531, +0.187592 ),  #8
  ( +0.577350, -0.794654, -0.187592 ),  #9
  ( +0.577350, +0.794654, +0.187592 ),  #10
  ( +0.934172, +0.303531, -0.187592 ),  #11
  ( -0.577350, +0.794654, +0.187592 ),  #12
  ( +0.000000, +0.982247, -0.187592 ),  #13
  ( -0.934172, +0.303531, -0.187592 ),  #14
  ( -0.356822, -0.491123, -0.794654 ),  #15
  ( -0.577350, +0.187592, -0.794654 ),  #16
  ( +0.356822, -0.491123, -0.794654 ),  #17
  ( +0.577350, +0.187592, -0.794654 ),  #18
  ( +0.000000, +0.607062, -0.794654 ),  #19
)
FACET[12] = (
  ( +0.000000, +0.000000, +1.000000 ), (  0,  1,  2,  3,  4 ),  #0
  ( -0.525731, -0.723607, +0.447214 ), (  6,  7,  5,  1,  0 ),  #1
  ( +0.525731, -0.723607, +0.447214 ), (  5,  9,  8,  2,  1 ),  #2
  ( +0.850651, +0.276393, +0.447214 ), (  8, 11, 10,  3,  2 ),  #3
  ( +0.000000, +0.894427, +0.447214 ), ( 10, 13, 12,  4,  3 ),  #4
  ( -0.850651, +0.276393, +0.447214 ), ( 12, 14,  6,  0,  4 ),  #5
  ( -0.850651, -0.276393, -0.447214 ), ( 14, 16, 15,  7,  6 ),  #6
  ( -0.000000, -0.894427, -0.447214 ), ( 15, 17,  9,  5,  7 ),  #7
  ( +0.850651, -0.276393, -0.447214 ), ( 17, 18, 11,  8,  9 ),  #8
  ( +0.525731, +0.723607, -0.447214 ), ( 18, 19, 13, 10, 11 ),  #9
  ( -0.525731, +0.723607, -0.447214 ), ( 19, 16, 14, 12, 13 ),  #10
  ( -0.000000, -0.000000, -1.000000 ), ( 19, 18, 17, 15, 16 ),  #11
)
EDGE[30] = (
  (  0,  1 ), (  0,  6 ), (  1,  2 ), (  2,  3 ),
  (  3,  4 ), (  4,  0 ), (  5,  1 ), (  5,  9 ),
  (  6,  7 ), (  7,  5 ), (  8,  2 ), (  8, 11 ),
  (  9,  8 ), ( 10,  3 ), ( 10, 13 ), ( 11, 10 ),
  ( 12,  4 ), ( 12, 14 ), ( 13, 12 ), ( 14,  6 ),
  ( 14, 16 ), ( 15,  7 ), ( 15, 17 ), ( 16, 15 ),
  ( 17,  9 ), ( 17, 18 ), ( 18, 11 ), ( 18, 19 ),
  ( 19, 13 ), ( 19, 16 ),
)

Résultat de sortie: hexaèdre régulier

Nombre de faces: 20
Nombre de côtés: 30
Nombre de sommets: 12
VERTEX[12] = (
  ( +0.000000, +0.000000, +1.000000 ),  #0
  ( +0.894427, +0.000000, +0.447214 ),  #1
  ( +0.276393, +0.850651, +0.447214 ),  #2
  ( -0.723607, +0.525731, +0.447214 ),  #3
  ( -0.723607, -0.525731, +0.447214 ),  #4
  ( +0.276393, -0.850651, +0.447214 ),  #5
  ( +0.723607, -0.525731, -0.447214 ),  #6
  ( +0.723607, +0.525731, -0.447214 ),  #7
  ( -0.276393, +0.850651, -0.447214 ),  #8
  ( -0.894427, -0.000000, -0.447214 ),  #9
  ( -0.276393, -0.850651, -0.447214 ),  #10
  ( -0.000000, +0.000000, -1.000000 ),  #11
)
FACET[20] = (
  ( +0.491123, +0.356822, +0.794654 ), (  2,  0,  1 ),  #0
  ( -0.187592, +0.577350, +0.794654 ), (  3,  0,  2 ),  #1
  ( -0.607062, +0.000000, +0.794654 ), (  4,  0,  3 ),  #2
  ( -0.187592, -0.577350, +0.794654 ), (  5,  0,  4 ),  #3
  ( +0.491123, -0.356822, +0.794654 ), (  5,  1,  0 ),  #4
  ( +0.794654, -0.577350, +0.187592 ), (  6,  1,  5 ),  #5
  ( +0.982247, -0.000000, -0.187592 ), (  7,  1,  6 ),  #6
  ( +0.794654, +0.577350, +0.187592 ), (  7,  2,  1 ),  #7
  ( +0.303531, +0.934172, -0.187592 ), (  8,  2,  7 ),  #8
  ( -0.303531, +0.934172, +0.187592 ), (  8,  3,  2 ),  #9
  ( -0.794654, +0.577350, -0.187592 ), (  9,  3,  8 ),  #10
  ( -0.982247, -0.000000, +0.187592 ), (  9,  4,  3 ),  #11
  ( -0.794654, -0.577350, -0.187592 ), ( 10,  4,  9 ),  #12
  ( -0.303531, -0.934172, +0.187592 ), ( 10,  5,  4 ),  #13
  ( +0.303531, -0.934172, -0.187592 ), ( 10,  6,  5 ),  #14
  ( +0.187592, -0.577350, -0.794654 ), ( 11,  6, 10 ),  #15
  ( +0.607062, +0.000000, -0.794654 ), ( 11,  7,  6 ),  #16
  ( +0.187592, +0.577350, -0.794654 ), ( 11,  8,  7 ),  #17
  ( -0.491123, +0.356822, -0.794654 ), ( 11,  9,  8 ),  #18
  ( -0.491123, -0.356822, -0.794654 ), ( 11, 10,  9 ),  #19
)
EDGE[30] = (
  (  0,  1 ), (  1,  2 ), (  2,  0 ), (  2,  3 ),
  (  3,  0 ), (  3,  4 ), (  4,  0 ), (  4,  5 ),
  (  5,  0 ), (  5,  1 ), (  5,  6 ), (  6,  1 ),
  (  6,  7 ), (  7,  1 ), (  7,  2 ), (  7,  8 ),
  (  8,  2 ), (  8,  3 ), (  8,  9 ), (  9,  3 ),
  (  9,  4 ), (  9, 10 ), ( 10,  4 ), ( 10,  5 ),
  ( 10,  6 ), ( 10, 11 ), ( 11,  6 ), ( 11,  7 ),
  ( 11,  8 ), ( 11,  9 ),
)