श्लाफली कॉनवेक्स रेगुलर पोलिटोप इंटरप्रेटर


15

पृष्ठभूमि

Schläfli प्रतीक फ़ॉर्म {पी, क्यू, आर, ...} कि नियमित रूप से polytopes और tessellations परिभाषित करता है की एक अंकन है।

Schläfli प्रतीक एक पुनरावर्ती विवरण है, जो {p} के रूप में एक पक्षीय नियमित बहुभुज के साथ शुरू होता है। उदाहरण के लिए, {3} एक समबाहु त्रिभुज है, {4} एक वर्ग वगैरह है।

एक नियमित पॉलीहेड्रॉन जिसमें प्रत्येक नियमित शीर्ष के चारों ओर q नियमित पी-साइड बहुभुज होते हैं, {p, q} द्वारा दर्शाया जाता है। उदाहरण के लिए, घन में प्रत्येक शीर्ष पर 3 वर्ग होते हैं और {4,3} द्वारा दर्शाया जाता है।

आर {पी, क्यू} के साथ एक नियमित 4-आयामी पॉलीटॉप, प्रत्येक किनारे के आसपास नियमित पॉलीहेड्रल कोशिकाओं को {पी, क्यू, आर} द्वारा दर्शाया गया है। उदाहरण के लिए, एक टीज़र, {4,3,3}, एक किनारे के आसपास 3 क्यूब्स, {4,3} है।

सामान्य तौर पर एक नियमित पॉलीटॉप {p, q, r, ..., y, z} में z {p, q, r, ..., y} प्रत्येक चोटी के चारों ओर पहलू होते हैं, जहां एक चोटी एक पॉलीहेड्रॉन में एक शीर्ष होती है, 4-पॉलीटोप में एक किनारे, 5-पॉलीटोप में एक चेहरा, 6-पॉलीटोप में एक सेल, और एक एन-पॉलीटोप में (n-3) -फेस।

एक नियमित पॉलीटॉप में एक नियमित रूप से शीर्ष आंकड़ा होता है। एक नियमित पॉलीटॉप {पी, क्यू, आर, ... वाई, जेड} का वर्टेक्स आंकड़ा {क्यू, आर, ... वाई, जेड} है।

नियमित पॉलीटॉप में स्टार बहुभुज तत्व हो सकते हैं, जैसे पेंटाग्राम, प्रतीक {5/2} के साथ, एक पेंटागन के कोने द्वारा दर्शाया जाता है लेकिन वैकल्पिक रूप से जुड़ा हुआ है।

Schläfli प्रतीक निर्माण के कोण दोष के आधार पर एक परिमित उत्तल पॉलीहेडरन, यूक्लिडियन अंतरिक्ष का एक अनंत टेस्यूलेशन, या हाइपरबोलिक अंतरिक्ष का एक अनंत टेस्यूलेशन का प्रतिनिधित्व कर सकता है। एक सकारात्मक कोण दोष एक शीर्ष आयाम में गुना आंकड़ा को मोड़ने और एक पॉलीटोप के रूप में खुद को वापस करने की अनुमति देता है। एक शून्य कोण दोषों के समान आयाम के स्थान को कम करता है। एक नकारात्मक कोण दोष साधारण स्थान में मौजूद नहीं हो सकता है, लेकिन इसका निर्माण हाइपरबोलिक स्थान में किया जा सकता है।

मुकाबला

आपका लक्ष्य एक ऐसा कार्यक्रम बनाना है, जब एक स्लैफ़ली प्रतीक पारित होने पर एक उत्तल पॉलीटोप का पूरा विवरण वापस आ जाएगा। यह केवल श्लाफली प्रतीकों का एक सबसेट है, लेकिन यह सबसे सरल है, मेरा मानना ​​है कि अन्य संभावनाओं के बिना भी यह एक बहुत ही मुश्किल काम होगा, और पॉलीस्टोप्स tessellations के लिए शुरुआती बिंदु हैं। इस प्रश्न के नियम इस परिणाम के विचार के साथ डिज़ाइन किए गए थे एक एपीआई, और मैं इंटरनेट पर इस तरह के किसी भी कार्यक्रम का पता लगाने में सक्षम नहीं हूं।

आपके कार्यक्रम को निम्नलिखित सभी को पूरा करना चाहिए।

  • कार्यक्रम किसी भी परिमित आयामी नियमित उत्तल पोलीटोप उत्पन्न करने में सक्षम होना चाहिए। 2 आयामों में इसमें n-gons शामिल हैं। 3 आयामों में ये प्लेटोनिक सॉलिड हैं, 4 आयामों में इसमें टेसरैक्ट, ऑर्थोप्लेक्स और कुछ अन्य शामिल हैं)
  • कार्यक्रम को या तो (ए) मूल पर एक बिंदु रखना चाहिए, या (बी) यह सुनिश्चित करना चाहिए कि सभी बिंदुओं का औसत मूल है। ओरिएंटेशन कोई मायने नहीं रखता। कुल मिलाकर आकार कोई मायने नहीं रखता।
  • कार्यक्रम को एक पूर्ण विवरण प्रदान करना होगा जिसका अर्थ है कि 4-आयामी ऑब्जेक्ट के लिए, प्रोग्राम कोने, किनारों, चेहरे और पॉलीहेड्रा को वापस करेगा / प्रिंट करेगा। इन आदेशों की सूचना से कोई फर्क नहीं पड़ता। पॉलीहेड्रा के लिए, यह वह जानकारी है जो आपको ऑब्जेक्ट रेंडर करने के लिए चाहिए होगी।

आपको संभालने की आवश्यकता नहीं है:

  • tesselations
  • हाइपरबोलिक ज्यामिति
  • आंशिक Schläfli प्रतीक (गैर उत्तल)
  • एंबेडेड श्लाफली प्रतीक (गैर-समान झुकाव)

अगर इनमें से कोई भी काम करने के लिए कहा जाए तो आप एक त्रुटि वापस कर सकते हैं।

उदाहरण: घन

इनपुट:

4 3

आउटपुट:

Vertices
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1    

Edges (These are the vertex pairs that make up the edges)
0 1
0 2
0 4
1 3
1 5
2 3
2 6
3 7
4 5
4 6
5 7
6 7

Faces (These are the squares which are the faces of the cube)
0 1 3 2
0 1 5 4
0 2 6 4
6 7 5 4
7 6 2 3
7 5 1 3

मेरे पास कुछ विचार थे कि यह एल्गोरिदम कैसे काम कर सकता है और बहुत पुनरावर्ती हो सकता है, लेकिन इस प्रकार मैं अभी तक विफल रहा हूं, लेकिन अगर आप प्रेरणा की तलाश कर रहे हैं: https://en.wikipedia.org/wiki/Euler_characteristic

कार्यक्षेत्र, किनारों और चेहरों की संख्या के उदाहरण के रूप में, उस क्यूब पर विचार करें जो {4,3} है। यदि हम प्रारंभिक 4 को देखते हैं, तो इसके 4 किनारे और 4 कोने हैं। अब यदि हम अगले 3 को देखते हैं, तो हम जानते हैं कि प्रत्येक किनारे पर 3 किनारे मिलते हैं, प्रत्येक किनारे 2 कोने से जुड़ते हैं, प्रत्येक किनारे पर 2 चेहरे मिलते हैं, प्रत्येक चेहरा 4 किनारों (वर्ग पक्षों के कारण) से जुड़ता है, और हमारे पास है यूलर विशेषता सूत्र।

ई = 3/2 वी

ई = 4/2 एफ

वी - ई + एफ = 2

जो E = 12, V = 8, F = 6 देता है।

स्कोरिंग

प्रश्न को विषय पर रखने के लिए, इसे संशोधित कर कोड गोल्फ कर दिया गया है। सबसे छोटा कोड जीतता है।

इस प्रश्न के लिए एक ग्रथब बनाया गया है


1
Googling से पता चलता है कि 4 आयामों से परे फैले हुए नियमित पॉलीटॉप के केवल 3 परिवार हैं: घन, अष्टकाहार और टेट्राहेड्रोन के अनुरूप। ऐसा लगता है कि इन परिवारों के लिए लिखना और बाकी के दो हार्डकोड (तीन डी पोलिटोप्स, तीन 4 डी पॉलिटोप्स, और अनंत परिवार 2 डी पॉलिटोप्स के लिए) सरल होगा। जहां तक ​​मैं देख सकता हूं कि यह कल्पना से मिलता है लेकिन सामान्य नहीं होगा। क्या यह एक मान्य उत्तर होगा? यह युक्ति के दायरे से परे सामयिक रेखांकन उत्पन्न करने के लिए एक पुनरावर्ती एल्गोरिदम लिखने के लिए संभव है, लेकिन कल्पना के भीतर भी उस दृष्टिकोण वाला हत्यारा निर्देशांक की गणना कर रहा है।
लेवल रिवर सेंट

हम वास्तविक कोने को कैसे जानते हैं, केवल यह जानकर कि वे समबाहु हैं?
मैथ्यू रोह

@SIGSEGV केवल निर्दिष्ट आवश्यकता है कि मूल केंद्र या किसी एक बिंदु के अनुरूप होना चाहिए। यह आकार को घुमाने के लिए बहुत गुंजाइश देता है जैसे आप कृपया। en.wikipedia.org/wiki/Simplex हाइपरटेट्राहेड्रोन के निर्देशांक की गणना के लिए एक एल्गोरिथ्म देता है (जिसे शायद icosahedron और उसके 4d एनालॉग तक बढ़ाया जा सकता है, लेकिन ऐसा करना मेरे लिए बहुत अधिक है, इसलिए मेरा सवाल है।) हाइपरक्यूब्स और हाइपरओक्टाहेड्रॉन। अच्छा पूर्णांक निर्देशांक (और हाइपरटेट्रैड्रॉन भी वास्तव में, लेकिन अक्सर केवल आकार की तुलना में अधिक आयामों में होता है, जो कि अनुपयोगी है।)
लेवल रिवर सेंट

@LevelRiverSt, हाँ एकमात्र नियमित पॉलीओपॉप्स के बाद से जो आपके सुझावों के भीतर मौजूद हैं, तो हाँ आप उन्हें हार्डकोड कर सकते हैं।
टोनी रूथ

मैंने इस प्रश्न पर समापन वोट डाला है क्योंकि यह सबसे तेज़-बंदूक-इन-द-वेस्ट शैली की चुनौती है, जहां पहला वैध उत्तर जीतता है। यह आमतौर पर एक वैध जीत मानदंड नहीं माना जाता है। मैं नहीं जानता कि यह इतने लंबे समय से कैसे खुला है, इसे बंद कर दिया जाना चाहिए था।
पोस्ट रॉक गार्फ हंटर

जवाबों:


2

अजगर

यहाँ किसी भी विशेष मामलों के बिना एक पुनरावर्ती कार्यक्रम है। रिक्त लाइनों और टिप्पणियों को अनदेखा करना, यह 100 से कम 90 लाइनें हैं, जिसमें अंत में यूलर के सूत्र की एक गंभीर जांच शामिल है। तदर्थ गणित कार्यों (जो शायद एक पुस्तकालय द्वारा प्रदान किया जा सकता है) और i / o की परिभाषाओं को छोड़कर, पॉलीटॉप पीढ़ी कोड की 50 लाइनें हैं। और यह स्टार पॉलीटॉप भी करता है!

आउटपुट पॉलीटोप में किनारे की लंबाई 1 होगी और यह निम्न स्थिति में विहित स्थिति और अभिविन्यास में होगा:

  • पहला शीर्ष मूल है,
  • पहला किनारा + एक्स अक्ष के साथ स्थित है,
  • पहला चेहरा x विमान के + y आधे तल में है,
  • पहला 3-सेल xyz स्थान के + z आधे स्थान में है, आदि।

इसके अलावा, आउटपुट सूचियाँ किसी विशेष क्रम में नहीं हैं। (ठीक है, वास्तव में, यह पूरी तरह से सच नहीं है - वे वास्तव में पहले तत्व से शुरू होने और बाहर की तरफ विस्तार करने के क्रम में बाहर आ जाएंगे।)

अमान्य स्कलाफ़ली प्रतीक के लिए कोई जाँच नहीं है; यदि आप इसे एक देते हैं, तो कार्यक्रम संभवतः रेल (अंतहीन लूप, स्टैक ओवरफ्लो, या बस कचरा बाहर) जाएगा।

यदि आप एक अनंत प्लानेर टाइलिंग जैसे कि {4,4} या {3,6} या {6,3} पूछते हैं, तो प्रोग्राम वास्तव में टाइलिंग उत्पन्न करना शुरू कर देगा, लेकिन यह हमेशा के लिए चलेगा जब तक यह अंतरिक्ष से बाहर नहीं निकल जाता है, कभी नहीं परिष्करण और न ही उत्पादन। इसे ठीक करना बहुत कठिन नहीं होगा (बस उत्पन्न करने के लिए तत्वों की संख्या पर एक सीमा लगाई जाए; परिणाम अनंत चित्र का एक सुसंगत क्षेत्र होना चाहिए, क्योंकि तत्व मोटे तौर पर चौड़ाई-पहले-खोज क्रम में उत्पन्न होते हैं)।

कोड

#!/usr/bin/python3
# (works with python2 or python3)

#
# schlafli_interpreter.py
# Author: Don Hatch
# For: /codegolf/114280/schl%C3%A4fli-convex-regular-polytope-interpreter
#
# Print the vertex coords and per-element (edges, faces, etc.) vertex index
# lists of a regular polytope, given by its schlafli symbol {p,q,r,...}.
# The output polytope will have edge length 1 and will be in canonical position
# and orientation, in the following sense:
#  - the first vertex is the origin,
#  - the first edge lies along the +x axis,
#  - the first face is in the +y half-plane of the xy plane,
#  - the first 3-cell is in the +z half-space of the xyz space, etc.
# Other than that, the output lists are in no particular order.
#

import sys
from math import *

# vector minus vector.
def vmv(a,b): return [x-y for x,y in zip(a,b)]
# matrix minus matrix.
def mmm(m0,m1): return [vmv(row0,row1) for row0,row1 in zip(m0,m1)]
# scalar times vector.
def sxv(s,v): return [s*x for x in v]
# scalar times matrix.
def sxm(s,m): return [sxv(s,row) for row in m]
# vector dot product.
def dot(a,b): return sum(x*y for x,y in zip(a,b))
# matrix outer product of two vectors; that is, if a,b are column vectors: a*b^T
def outer(a,b): return [sxv(x,b) for x in a]
# vector length squared.
def length2(v): return dot(v,v)
# distance between two vectors, squared.
def dist2(a,b): return length2(vmv(a,b))
# matrix times vector, homogeneous (i.e. input vector ends with an implicit 1).
def mxvhomo(m,v): return [dot(row,v+[1]) for row in m]
# Pad a square matrix (rotation/reflection) with an extra column of 0's on the
# right (translation).
def makehomo(m): return [row+[0] for row in m]
# Expand dimensionality of homogeneous transform matrix by 1.
def expandhomo(m): return ([row[:-1]+[0,row[-1]] for row in m]
                         + [[0]*len(m)+[1,0]])
# identity matrix
def identity(dim): return [[(1 if i==j else 0) for j in range(dim)]
                                               for i in range(dim)]
# https://en.wikipedia.org/wiki/Householder_transformation. v must be unit.
# Not homogeneous (makehomo the result if you want that).
def householderReflection(v): return mmm(identity(len(v)), sxm(2, outer(v,v)))

def sinAndCosHalfDihedralAngle(schlafli):
  # note, cos(pi/q)**2 generally has a nicer expression with no trig and often
  # no radicals, see http://www.maths.manchester.ac.uk/~cds/articles/trig.pdf
  ss = 0
  for q in schlafli: ss = cos(pi/q)**2 / (1 - ss)
  if abs(1-ss) < 1e-9: ss = 1  # prevent glitch in planar tiling cases
  return sqrt(ss), sqrt(1 - ss)

# Calculate a set of generators of the symmetry group of a {p,q,r,...} with
# edge length 1.
# Each generator is a dim x (dim+1) matrix where the square part is the initial
# orthogonal rotation/reflection and the final column is the final translation.
def calcSymmetryGenerators(schlafli):
  dim = len(schlafli) + 1
  if dim == 1: return [[[-1,1]]]  # one generator: reflect about x=.5
  facetGenerators = calcSymmetryGenerators(schlafli[:-1])
  # Start with facet generators, expanding each homogeneous matrix to full
  # dimensionality (i.e. from its previous size dim-1 x dim to dim x dim+1).
  generators = [expandhomo(gen) for gen in facetGenerators]
  # Final generator will reflect the first facet across the hyperplane
  # spanned by the first ridge and the entire polytope's center,
  # taking the first facet to a second facet also containing that ridge.
  # v = unit vector normal to that bisecting hyperplane
  #   = [0,...,0,-sin(dihedralAngle/2),cos(dihedralAngle/2)]
  s,c = sinAndCosHalfDihedralAngle(schlafli)
  v = [0]*(dim-2) + [-s,c]
  generators.append(makehomo(householderReflection(v)))
  return generators

# Key for comparing coords with roundoff error.  Makes sure the formatted
# numbers are not very close to 0, to avoid them coming out as "-0" or "1e-16".
# This isn't reliable in general, but it suffices for this application
# (except for very large {p}, no doubt).
def vert2key(vert): return ' '.join(['%.9g'%(x+.123) for x in vert])

# Returns a pair verts,edgesEtc where edgesEtc is [edges,faces,...]
def regular_polytope(schlafli):
  dim = len(schlafli) + 1
  if dim == 1: return [[0],[1]],[]

  gens = calcSymmetryGenerators(schlafli)

  facetVerts,facetEdgesEtc = regular_polytope(schlafli[:-1])

  # First get all the verts, and make a multiplication table.
  # Start with the verts of the first facet (padded to full dimensionality),
  # so indices will match up.
  verts = [facetVert+[0] for facetVert in facetVerts]
  vert2index = dict([[vert2key(vert),i] for i,vert in enumerate(verts)])
  multiplicationTable = []
  iVert = 0
  while iVert < len(verts):  # while verts is growing
    multiplicationTable.append([None] * len(gens))
    for iGen in range(len(gens)):
      newVert = mxvhomo(gens[iGen], verts[iVert])
      newVertKey = vert2key(newVert)
      if newVertKey not in vert2index:
        vert2index[newVertKey] = len(verts)
        verts.append(newVert)
      multiplicationTable[iVert][iGen] = vert2index[newVertKey]
    iVert += 1

  # The higher-level elements of each dimension are found by transforming
  # the facet's elements of that dimension.  Start by augmenting facetEdgesEtc
  # by adding one more list representing the entire facet.
  facetEdgesEtc.append([tuple(range(len(facetVerts)))])
  edgesEtc = []
  for facetElementsOfSomeDimension in facetEdgesEtc:
    elts = facetElementsOfSomeDimension[:]
    elt2index = dict([[elt,i] for i,elt in enumerate(elts)])
    iElt = 0
    while iElt < len(elts):  # while elts is growing
      for iGen in range(len(gens)):
        newElt = tuple(sorted([multiplicationTable[iVert][iGen]
                               for iVert in elts[iElt]]))
        if newElt not in elt2index:
          elt2index[newElt] = len(elts)
          elts.append(newElt)
      iElt += 1
    edgesEtc.append(elts)

  return verts,edgesEtc

# So input numbers can be like any of "8", "2.5", "7/3"
def parseNumberOrFraction(s):
  tokens = s.split('/')
  return float(tokens[0])/float(tokens[1]) if len(tokens)==2 else float(s)

if sys.stdin.isatty():
  sys.stderr.write("Enter schlafli symbol (space-separated numbers or fractions): ")
  sys.stderr.flush()
schlafli = [parseNumberOrFraction(token) for token in sys.stdin.readline().split()]
verts,edgesEtc = regular_polytope(schlafli)

# Hacky polishing of any integers or half-integers give or take rounding error.
def fudge(x): return round(2*x)/2 if abs(2*x-round(2*x))<1e-9 else x

print(repr(len(verts))+' Vertices:')
for v in verts: print(' '.join([repr(fudge(x)) for x in v]))
for eltDim in range(1,len(edgesEtc)+1):
  print("")
  elts = edgesEtc[eltDim-1]
  print(repr(len(elts))+' '+('Edges' if eltDim==1
                        else 'Faces' if eltDim==2
                        else repr(eltDim)+'-cells')+" ("+repr(len(elts[0]))+" vertices each):")
  for elt in elts: print(' '.join([repr(i) for i in elt]))

# Assert the generalization of Euler's formula: N0-N1+N2-... = 1+(-1)**(dim-1).
N = [len(elts) for elts in [verts]+edgesEtc]
eulerCharacteristic = sum((-1)**i * N[i] for i in range(len(N)))
print("Euler characteristic: "+repr(eulerCharacteristic))
if 2.5 not in schlafli: assert eulerCharacteristic == 1 + (-1)**len(schlafli)

कुछ मामलों पर इसे आजमा रहे हैं

इनपुट ( घन ):

4 3

आउटपुट:

8 Vertices:
0.0 0.0 0.0
1.0 0.0 0.0
0.0 1.0 0.0
1.0 1.0 0.0
0.0 0.0 1.0
1.0 0.0 1.0
0.0 1.0 1.0
1.0 1.0 1.0

12 Edges (2 vertices each):
0 1
0 2
1 3
2 3
0 4
1 5
4 5
2 6
4 6
3 7
5 7
6 7

6 Faces (4 vertices each):
0 1 2 3
0 1 4 5
0 2 4 6
1 3 5 7
2 3 6 7
4 5 6 7

यूनिक्स कमांड शेल से इनपुट ( 120-सेल पॉलीकोरोन ):

$ echo "5 3 3" | ./schlafli_interpreter.py | grep ":"

आउटपुट:

600 Vertices:
1200 Edges (2 vertices each):
720 Faces (5 vertices each):
120 3-cells (20 vertices each):

इनपुट (10-आयामी क्रॉस पॉलीटॉप ):

$ echo "3 3 3 3 3 3 3 3 4" | ./schlafli_interpreter.py | grep ":"

आउटपुट:

20 Vertices:
180 Edges (2 vertices each):
960 Faces (3 vertices each):
3360 3-cells (4 vertices each):
8064 4-cells (5 vertices each):
13440 5-cells (6 vertices each):
15360 6-cells (7 vertices each):
11520 7-cells (8 vertices each):
5120 8-cells (9 vertices each):
1024 9-cells (10 vertices each):

इनपुट (15-आयामी सिम्प्लेक्स ):

$ echo "3 3 3 3 3 3 3 3 3 3 3 3 3 3" | ./schlafli_interpreter.py | grep ":"

16 Vertices:
120 Edges (2 vertices each):
560 Faces (3 vertices each):
1820 3-cells (4 vertices each):
4368 4-cells (5 vertices each):
8008 5-cells (6 vertices each):
11440 6-cells (7 vertices each):
12870 7-cells (8 vertices each):
11440 8-cells (9 vertices each):
8008 9-cells (10 vertices each):
4368 10-cells (11 vertices each):
1820 11-cells (12 vertices each):
560 12-cells (13 vertices each):
120 13-cells (14 vertices each):
16 14-cells (15 vertices each):

सितारा बहुवचन

हा, और यह स्वाभाविक रूप से स्टार पॉलीटोप्स भी करता है! मुझे भी प्रयास करने की आवश्यकता नहीं थी :-) सिवाय इसके कि अंत में यूलर के फार्मूले के बारे में थोड़ा विफल रहता है, क्योंकि वह सूत्र स्टार पॉलीटॉप्स के लिए मान्य नहीं है।

इनपुट ( छोटा स्टेल्टेड डोडेकैड्रन ):

5/2 5

आउटपुट:

12 Vertices:
0.0 0.0 0.0
1.0 0.0 0.0
0.8090169943749473 0.5877852522924732 0.0
0.19098300562505266 0.5877852522924732 0.0
0.5 -0.36327126400268034 0.0
0.8090169943749473 -0.2628655560595667 0.5257311121191336
0.19098300562505266 -0.2628655560595667 0.5257311121191336
0.5 0.162459848116453 -0.3249196962329062
0.5 0.6881909602355867 0.5257311121191336
0.0 0.32491969623290623 0.5257311121191336
0.5 0.1624598481164533 0.8506508083520398
1.0 0.32491969623290623 0.5257311121191336

30 Edges (2 vertices each):
0 1
0 2
1 3
2 4
3 4
0 5
1 6
5 7
6 7
0 8
2 9
7 8
7 9
1 8
0 10
3 11
5 9
4 10
7 11
4 9
2 5
1 10
4 11
6 11
6 8
3 10
3 6
2 10
9 11
5 8

12 Faces (5 vertices each):
0 1 2 3 4
0 1 5 6 7
0 2 7 8 9
1 3 7 8 11
0 4 5 9 10
2 4 5 7 11
1 4 6 10 11
0 3 6 8 10
3 4 6 7 9
2 3 9 10 11
1 2 5 8 10
5 6 8 9 11
Traceback (most recent call last):
  File "./schlafli_interpreter.py", line 185, in <module>
    assert sum((-1)**i * N[i] for i in range(len(N))) == 1 + (-1)**len(schlafli)
AssertionError

इनपुट ( महान उल्लिखित 120-सेल ):

$ echo "5/2 3 5" | ./schlafli_interpreter.py | grep ":"

आउटपुट:

120 Vertices:
720 Edges (2 vertices each):
720 Faces (5 vertices each):
120 3-cells (20 vertices each):

इस प्रश्न को पुनर्जीवित करने के लिए धन्यवाद, और आपका उत्तर बहुत प्रभावशाली लगता है। मुझे पुनरावर्ती प्रकृति और स्टार के आंकड़े पसंद हैं। मैंने आपके कोड को ड्राइंग पॉलिथोप्स के लिए कुछ opengl से जोड़ा है (ऊपर गीथब लिंक देखें)।
टोनी रूथ

14

माणिक

पृष्ठभूमि

अनंत आयामों में फैले हुए नियमित पॉलीटोप के तीन परिवार हैं:

  • सिम्प्लेक्स, जिनमें से टेट्राहेड्रॉन एक सदस्य है (मैं अक्सर उन्हें यहां हाइपरटेट्रैड्रा के रूप में संदर्भित करूंगा, हालांकि सिम्प्लेक्स शब्द अधिक सही है।) उनके स्कोलाफ़ी प्रतीक रूप के हैं। {3,3,...,3,3}

  • n- क्यूब्स, जिनमें से क्यूब एक सदस्य है। उनके शल्लिी प्रतीक रूप के हैं{4,3,...,3,3}

  • ऑर्थोप्लेक्स, जिनमें से ऑक्टाहेड्रोन एक सदस्य है (मैं अक्सर उन्हें हाइपरक्टाएक्ट्रा के रूप में यहां संदर्भित करूंगा) उनके स्कोलाफ़ी प्रतीक रूप के हैं {3,3,...,3,4}

नियमित रूप से पॉलीटॉप का एक और अनंत परिवार है, प्रतीक {m}, 2 आयामी बहुभुज, जिसमें किसी भी संख्या में किनारों एम हो सकते हैं।

इसके अलावा, नियमित पॉलीटोप के सिर्फ पांच अन्य विशेष मामले हैं: 3-आयामी आइकोसैहेड्रोन {3,5} और डोडेकाहेड्रोन {5,3}; उनके 4-आयामी एनालॉग्स 600-सेल {3,3,5}और 120-सेल {5,3,3}; और एक अन्य 4 आयामी पॉलीटोप, 24-सेल {3,4,3}(जिसके 3 आयामों में सबसे निकटतम एनालॉग क्यूबक्टाहेड्रोन हैं और इसके डूमोम्बिक डोडेकेर्रॉन हैं)।

मुख्य कार्य

नीचे मुख्य है polytope कार्य है जो स्कलाफी प्रतीक की व्याख्या करता है। यह संख्या की एक सरणी की उम्मीद करता है, और एक सरणी देता है जिसमें निम्नानुसार सरणियों का एक गुच्छा होता है:

  • सभी कोने की एक सरणी, प्रत्येक को निर्देशांक के n- तत्व सरणी के रूप में व्यक्त किया जाता है (जहां n आयामों की संख्या है)

  • सभी किनारों की एक सरणी, प्रत्येक को वर्टेक्स इंडेक्स के 2-तत्व के रूप में व्यक्त किया गया है

  • सभी चेहरों की एक सरणी, प्रत्येक को वर्टेक्स इंडेक्स के एक एम-तत्व के रूप में व्यक्त किया गया है (जहां एम चेहरे पर वर्टिकल की संख्या है)

और इसलिए आयामों की संख्या के लिए उपयुक्त है।

यह स्वयं 2d पॉलीटॉप्स की गणना करता है, 3 अनंत आयामी परिवारों के लिए फ़ंक्शन कॉल करता है, और पांच विशेष मामलों के लिए लुकअप तालिकाओं का उपयोग करता है। यह इसके ऊपर घोषित कार्यों और तालिकाओं को खोजने की अपेक्षा करता है।

include Math

#code in subsequent sections of this answer should be inserted here 

polytope=->schl{
  if schl.size==1                                #if a single digit calculate and return a polygon
    return [(1..schl[0]).map{|i|[sin(PI*2*i/schl[0]),cos(PI*2*i/schl[0])]},(1..schl[0]).map{|i|[i%schl[0],(i+1)%schl[0]]}]  
  elsif  i=[[3,5],[5,3]].index(schl)             #if a 3d special, lookup from tables
    return [[vv,ee,ff],[uu,aa,bb]][i]
  elsif i=[[3,3,5],[5,3,3],[3,4,3]].index(schl)  #if a 4d special. lookup fromm tables
    return [[v,e,f,g],[u,x,y,z],[o,p,q,r]][i]
  elsif schl.size==schl.count(3)                 #if all threes, call tetr for a hypertetrahedron
    return tetr[schl.size+1]
  elsif schl.size-1==schl.count(3)               #if all except one number 3
    return cube[schl.size+1] if schl[0]==4       #and the 1st digit is 4, call cube for a hypercube
    return octa[schl.size+1] if schl[-1]==4      #and the last digit is 4, call octa for a hyperoctahedron
  end
  return "error"                                 #in any other case return an error
}

टेट्राहेड्रोन, क्यूब और ऑक्टाहेड्रॉन परिवारों के लिए कार्य

https://en.wikipedia.org/wiki/Simplex

https://en.wikipedia.org/wiki/5-cell (4d सिंप्लेक्स)

http://mathworld.wolfram.com/Simplex.html

टेट्राहेड्रोन परिवार स्पष्टीकरण - निर्देशांक

एन-डायमेंशनल सिम्प्लेक्स / हाइपरटेट्राहेड्रोन में n + 1 अंक हैं। N + 1 आयाम में n- आयामी सिम्प्लेक्स के कोने देना बहुत आसान है।

इस प्रकार (1,0,0),(0,1,0),(0,0,1)3 आयामों में एम्बेडेड 2d त्रिकोण का (1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)वर्णन करता है और 4 आयामों में एम्बेडेड 3 डी टेट्राहेड्रोन का वर्णन करता है। यह पुष्टि करके आसानी से सत्यापित किया जाता है कि कोने के बीच की सभी दूरी sqrt (2) हैं।

एन-डायमेंशनल स्पेस में एन-डायमेंशनल सिम्प्लेक्स के लिए वर्टिकल खोजने के लिए विभिन्न जटिल एल्गोरिदम इंटरनेट पर दिए गए हैं। मुझे इस जवाब /mathpro//a/38725 पर विल जागी की टिप्पणियों में एक सरल रूप से सरल मिला । अंतिम बिंदु p=q=...=x=y=zदूसरों से sqrt (2) की दूरी पर लाइन पर स्थित है। इस प्रकार ऊपर दिए गए त्रिकोण को बिंदु पर जोड़कर (-1/3,-1/3,-1/3)या तो टेट्राहेड्रॉन में परिवर्तित किया जा सकता है (1,1,1)। अंतिम बिंदु के लिए निर्देशांक के ये 2 संभावित मूल्य (1-(1+n)**0.5)/nऔर द्वारा दिए गए हैं(1+(1+n)**0.5)/n

सवाल कहते हैं एन-टोपे के आकार बात नहीं है, मैं n द्वारा के माध्यम से गुणा करना पसंद करते हैं और निर्देशांक का उपयोग (n,0,0..0)करने के लिए (0..0,0,n)पर अंतिम बिंदु के साथ (t,t,..,t,t)जहां टी = 1-(1+n)**0.5सादगी के लिए।

जैसा कि इस टेट्राहेड्रोन का केंद्र मूल में नहीं है, सभी निर्देशांक में सुधार लाइन द्वारा किया जाना चाहिए s.map!{|j|j-((1-(1+n)**0.5)+n)/(1+n)}जो पाता है कि केंद्र मूल से कितना दूर है और इसे घटाता है। मैंने इसे एक अलग ऑपरेशन के रूप में रखा है। हालांकि मैं का इस्तेमाल किया है s[i]+=n, जहां s[i]=nइस तथ्य का उल्लेख करने के लिए है कि जब सरणी द्वारा initialised है, क्या करना होगा s=[0]*nहम सही यहाँ में ऑफसेट के बजाय शुरू में नहीं बल्कि अंत की तुलना में डाल दिया और केंद्रित सुधार कर सकता है।

टेट्राहेड्रोन परिवार स्पष्टीकरण - ग्राफ टोपोलॉजी

सिम्प्लेक्स का ग्राफ पूरा ग्राफ है: हर वर्टेक्स एक बार हर दूसरे वर्टेक्स से जुड़ा होता है। यदि हमारे पास एक एन सिम्प्लेक्स है, तो हम उस बिंदु पर नीचे n-1 सिम्प्लेक्स देने के लिए किसी भी शीर्ष को हटा सकते हैं, जहां हमारे पास एक त्रिकोण या यहां तक ​​कि एक किनारे है।

इसलिए हमारे पास कैटलॉग में कुल 2 ** (n + 1) आइटम हैं, प्रत्येक बाइनरी नंबर द्वारा दर्शाया गया है। यह 0कुछ भी नहीं के 1लिए है, एक शीर्ष के लिए एक और 1एक किनारे के लिए दो एस के माध्यम से होता है , 1पूरे पॉलीटोप के लिए सभी एस तक।

हम प्रत्येक आकार के तत्वों को संग्रहीत करने के लिए खाली सरणियों की एक सरणी सेट करते हैं। तब हम शून्य से लेकर (2 ** n + 1) तक लूप बनाते हैं, ताकि प्रत्येक उपसमुच्चय के उपसमुच्चय को उत्पन्न किया जा सके और प्रत्येक उपसमूह के आकार के अनुसार उन्हें स्टोर किया जा सके।

हम एक किनारे (एक शीर्ष या एक शून्य) से छोटे किसी भी चीज में दिलचस्पी नहीं रखते हैं और न ही पूर्ण पॉलीटोप में (जैसा कि प्रश्न में उदाहरण में पूर्ण घन नहीं दिया गया है), इसलिए हम tg[2..n]इन अवांछित तत्वों को हटाने के लिए लौटते हैं। लौटने से पहले, हम शुरुआत से पहले निर्देशांक निर्देशांक वाले [टीवी] से निपटते हैं।

कोड

tetr=->n{

  #Tetrahedron Family Vertices
  tv=(0..n).map{|i|
    s=[0]*n
    if i==n
      s.map!{(1-(1+n)**0.5)}
    else
      s[i]+=n
    end
    s.map!{|j|j-((1-(1+n)**0.5)+n)/(1+n)}
  s}

  #Tetrahedron Family Graph
  tg=(0..n+1).map{[]}
  (2**(n+1)).times{|i|
    s=[]
    (n+1).times{|j|s<<j if i>>j&1==1}
    tg[s.size]<<s
  }

return [tv]+tg[2..n]}

cube=->n{

  #Cube Family Vertices
  cv=(0..2**n-1).map{|i|s=[];n.times{|j|s<<(i>>j&1)*2-1};s}

  #Cube Family Graph
  cg=(0..n+1).map{[]}
  (3**n).times{|i|                         #for each point
    s=[]
    cv.size.times{|j|                      #and each vertex
      t=true                               #assume vertex goes with point
      n.times{|k|                          #and each pair of opposite sides
        t&&= (i/(3**k)%3-1)*cv[j][k]!=-1   #if the vertex has kingsmove distance >1 from point it does not belong      
      }
      s<<j if t                            #add the vertex if it belongs
    }
    cg[log2(s.size)+1]<<s if s.size > 0
  } 

return [cv]+cg[2..n]}

octa=->n{

  #Octahedron Family Vertices
  ov=(0..n*2-1).map{|i|s=[0]*n;s[i/2]=(-1)**i;s}

  #Octahedron Family Graph
  og=(0..n).map{[]}
  (3**n).times{|i|                         #for each point
    s=[]
    ov.size.times{|j|                      #and each vertex
      n.times{|k|                          #and each pair of opposite sides
        s<<j if (i/(3**k)%3-1)*ov[j][k]==1 #if the vertex is located in the side corresponding to the point, add the vertex to the list      
      }    
    }
    og[s.size]<<s
  } 

return [ov]+og[2..n]}

क्यूब और ऑक्टाहेड्रोन परिवारों की व्याख्या - निर्देशांक

एन-घन है 2**nकोने, प्रत्येक एन की एक सरणी का प्रतिनिधित्व करती 1है और -1(सभी संभावनाओं की अनुमति है।) हम पुनरावृति अनुक्रमित के माध्यम से रों 0को 2**n-1सभी कोने की सूची के लिए, और के टुकड़े के माध्यम से बार-बार दोहराना द्वारा प्रत्येक शिखर के लिए एक सरणी का निर्माण सूचकांक और जोड़ -1या 1सरणी में (सबसे महत्वपूर्ण बिट के लिए कम से कम महत्वपूर्ण बिट।) इस प्रकार बाइनरी 11014 डी बिंदु बन जाता है [1,-1,1,1]

N-octahedron या n-orthoplex में 2nकोने होते हैं, जिसमें एक को छोड़कर सभी निर्देशांक शून्य होते हैं, जो एक 1या होता है -1। उत्पन्न सरणी में कोने का क्रम है [[1,0,0..],[-1,0,0..],[0,1,0..],[0,-1,0..],[0,0,1..],[0,0,-1..]...]। ध्यान दें कि जैसे कि ऑक्टाहेड्रन क्यूब का दोहरी है, ऑक्टाहेड्रोन के शीर्ष को क्यूब के चेहरों के केंद्र द्वारा परिभाषित किया गया है जो इसे घेरता है।

क्यूब और ऑक्टाहेड्रोन परिवारों की व्याख्या - ग्राफ टोपोलॉजी

कुछ प्रेरणा हाइपरक्यूब पक्षों से ली गई थी और यह तथ्य कि हाइपरओक्टाहेड्रोन हाइपरक्यूब का दोहरी है।

एन-क्यूब के लिए, 3**nकैटलॉग के लिए आइटम हैं । उदाहरण के लिए, 3 घन में है3**3 27 तत्व हैं। यह एक रूबिक क्यूब का अध्ययन करके देखा जा सकता है, जिसमें 27 के कुल के लिए 1 केंद्र, 6 चेहरे, 12 किनारों और 8 कोने हैं। हम सभी आयामों में -1,0 और -1 से पुनरावृत्ति करते हैं, जो कि साइड-स्पीड 2xxx2 के एन-क्यूब को परिभाषित करता है। .. और सभी कोने लौटें जो घन के विपरीत दिशा में नहीं हैं। इस प्रकार घन का केंद्र बिंदु सभी 2 ** n कोने को वापस कर देता है, और किसी भी अक्ष के साथ केंद्र से एक इकाई दूर जाने पर कोने की संख्या आधे से कम हो जाती है।

टेट्राहेड्रॉन परिवार के साथ, हम एरे की एक खाली सरणी उत्पन्न करके शुरू करते हैं और इसे अपने तत्व के संख्या के अनुसार आबाद करते हैं। ध्यान दें कि क्योंकि कोने की संख्या 2 ** n के रूप में बदलती है क्योंकि हम किनारों, चेहरों, क्यूब्स आदि के माध्यम से ऊपर जाते हैं, हम log2(s.size)+1बस के बजाय उपयोग करते हैं s.size। फिर, हमें फ़ंक्शन से लौटने से पहले हाइपरक्यूब को और 2 तत्वों से कम के सभी तत्वों को निकालना होगा।

ऑक्टाहेड्रोन / ऑर्थोप्लेक्स परिवार क्यूब परिवार के दोहरे हैं, इसलिए फिर 3**nसे कैटलॉग करने के लिए आइटम हैं । यहां हम -1,0,1सभी आयामों के लिए पुनरावृति करते हैं और यदि नॉनस्टेरो किसी वर्टेक्स का समन्वय बिंदु के संबंधित समन्वय के बराबर है, तो उस बिंदु के अनुरूप सूची में वर्टेक्स जोड़ा जाता है। इस प्रकार एक बढ़त दो नॉनज़ेरो निर्देशांक के साथ एक बिंदु से मेल खाती है, 3 नॉनज़ेरो निर्देशांक के साथ एक बिंदु के लिए एक त्रिकोण और 4 नॉनज़ेरो संपर्कों के साथ एक बिंदु पर एक टेट्राहेड्रोन (4 डी अंतरिक्ष में)।

प्रत्येक बिंदु के लिए शीर्ष के परिणामी सरणियों को अन्य मामलों की तरह बड़े सरणी में संग्रहीत किया जाता है, और हमें लौटने से पहले 2 तत्वों से कम किसी भी तत्व को निकालना होगा। लेकिन इस मामले में हमें पूर्ण मूल n-tope को निकालने की आवश्यकता नहीं है क्योंकि एल्गोरिथ्म इसे रिकॉर्ड नहीं करता है।

क्यूब के लिए कोड के कार्यान्वयन को यथासंभव समान रूप से डिजाइन किया गया था। हालांकि इसमें एक निश्चित लालित्य है, यह संभावना है कि समान सिद्धांतों के आधार पर अधिक कुशल एल्गोरिदम को तैयार किया जा सकता है।

https://en.wikipedia.org/wiki/Hypercube

http://mathworld.wolfram.com/Hypercube.html

https://en.wikipedia.org/wiki/Cross-polytope

http://mathworld.wolfram.com/CrossPolytope.html

3 डी विशेष मामलों के लिए तालिकाओं को बनाने के लिए कोड

पिछले आयाम के समानांतर पांच गुना समरूपता अक्ष के साथ उन्मुख icosahedron / dodecahedron के साथ एक अभिविन्यास का उपयोग किया गया था, क्योंकि यह भागों के सबसे सुसंगत लेबलिंग के लिए बनाया गया था। ऑक्सोसहेड्रोन के लिए वर्टिस और चेहरों की संख्या कोड टिप्पणियों में आरेख के अनुसार है, और डोडेकेहेड्रॉन के लिए उलट है।

Https://en.wikipedia.org/wiki/Regular_icosahedron के अनुसार icosahedron के 10 गैर-ध्रुवीय कोने का अक्षांश +/- arctan (1/2) है। icosahedron के पहले ऊपरी सिरे के निर्देशांक की गणना की जाती है। यह, xy समतल से दूरी +/- 2 पर त्रिज्या 2 के दो वृत्तों पर है। यह परिधि के वर्गमीटर (5) का कुल त्रिज्या बनाता है, इसलिए अंतिम 2 कोने (0,0, + / - sqrt (2)) पर हैं।

डोडेकाहेड्रोन के कोने के निर्देशांक की गणना तीन आईसीओसहेड्रोन कोने के निर्देशांक द्वारा की जाती है जो उन्हें घेरते हैं।

=begin
TABLE NAMES      vertices     edges      faces
icosahedron      vv           ee         ff
dodecahedron     uu           aa         bb 

    10
    / \   / \   / \   / \   / \
   /10 \ /12 \ /14 \ /16 \ /18 \
   -----1-----3-----5-----7-----9
   \ 0 / \ 2 / \ 4 / \ 6 / \ 8 / \
    \ / 1 \ / 3 \ / 5 \ / 7 \ / 9 \
     0-----2-----4-----6-----8-----
      \11 / \13 / \15 / \17 / \19 /
       \ /   \ /   \ /   \ /   \ / 
       11
=end

vv=[];ee=[];ff=[]
10.times{|i|
  vv[i]=[2*sin(PI/5*i),2*cos(PI/5*i),(-1)**i]
  ee[i]=[i,(i+1)%10];ee[i+10]=[i,(i+2)%10];ee[i+20]=[i,11-i%2]
  ff[i]=[(i-1)%10,i,(i+1)%10];ff[i+10]=[(i-1)%10,10+i%2,(i+1)%10]

}
vv+=[[0,0,-5**0.5],[0,0,5**0.5]]

uu=[];aa=[];bb=[]
10.times{|i|
  uu[i]=(0..2).map{|j|vv[ff[i][0]][j]+vv[ff[i][1]][j]+vv[ff[i][2]][j]}
  uu[i+10]=(0..2).map{|j|vv[ff[i+10][0]][j]+vv[ff[i+10][1]][j]+vv[ff[i+10][2]][j]}
  aa[i]=[i,(i+1)%10];aa[i+10]=[i,(i+10)%10];aa[i+20]=[(i-1)%10+10,(i+1)%10+10]
  bb[i]=[(i-1)%10+10,(i-1)%10,i,(i+1)%10,(i+1)%10+10] 
}
bb+=[[10,12,14,16,18],[11,13,15,17,19]]

4 डी विशेष मामलों के लिए तालिकाओं को बनाने के लिए कोड

यह थोड़ा हैक है। इस कोड को चलने में कुछ सेकंड लगते हैं। बेहतर होगा कि आउटपुट को किसी फाइल में स्टोर करें और उसे आवश्यकतानुसार लोड करें।

600 कोश के लिए 120 शीर्ष निर्देशांक की सूची http://mathworld.wolfram.com/600-Cell.html से है । 24 शीर्ष निर्देशांक जो एक सुनहरे अनुपात की सुविधा नहीं देते हैं, एक 24-सेल के कोने बनाते हैं। विकिपीडिया की एक ही योजना है लेकिन इन 24 निर्देशांक और अन्य 96 के सापेक्ष पैमाने में एक त्रुटि है।

#TABLE NAMES                           vertices     edges      faces   cells
#600 cell (analogue of icosahedron)    v            e          f       g
#120 cell (analogue of dodecahedron)   u            x          y       z 
#24 cell                               o            p          q       r

#600-CELL

# 120 vertices of 600cell. First 24 are also vertices of 24-cell

v=[[2,0,0,0],[0,2,0,0],[0,0,2,0],[0,0,0,2],[-2,0,0,0],[0,-2,0,0],[0,0,-2,0],[0,0,0,-2]]+

(0..15).map{|j|[(-1)**(j/8),(-1)**(j/4),(-1)**(j/2),(-1)**j]}+

(0..95).map{|i|j=i/12
   a,b,c,d=1.618*(-1)**(j/4),(-1)**(j/2),0.618*(-1)**j,0
   h=[[a,b,c,d],[b,a,d,c],[c,d,a,b],[d,c,b,a]][i%12/3]
   (i%3).times{h[0],h[1],h[2]=h[1],h[2],h[0]}
h}

#720 edges of 600cell. Identified by minimum distance of 2/phi between them

e=[]
120.times{|i|120.times{|j|
  e<<[i,j]  if i<j && ((v[i][0]-v[j][0])**2+(v[i][1]-v[j][1])**2+(v[i][2]-v[j][2])**2+(v[i][3]-v[j][3])**2)**0.5<1.3  
}}

#1200 faces of 600cell. 
#If 2 edges share a common vertex and the other 2 vertices form an edge in the list, it is a valid triangle.

f=[]
720.times{|i|720.times{|j|
  f<< [e[i][0],e[i][1],e[j][1]] if i<j && e[i][0]==e[j][0] && e.index([e[i][1],e[j][1]])
}}

#600 cells of 600cell.
#If 2 triangles share a common edge and the other 2 vertices form an edge in the list, it is a valid tetrahedron.

g=[]
1200.times{|i|1200.times{|j|
  g<< [f[i][0],f[i][1],f[i][2],f[j][2]] if i<j && f[i][0]==f[j][0] && f[i][1]==f[j][1] && e.index([f[i][2],f[j][2]])

}}

#120 CELL (dual of 600 cell)

#600 vertices of 120cell, correspond to the centres of the cells of the 600cell
u=g.map{|i|s=[0,0,0,0];i.each{|j|4.times{|k|s[k]+=v[j][k]/4.0}};s}

#1200 edges of 120cell at centres of faces of 600-cell. Search for pairs of tetrahedra with common face
x=f.map{|i|s=[];600.times{|j|s<<j if i==(i & g[j])};s}

#720 pentagonal faces, surrounding edges of 600-cell. Search for sets of 5 tetrahedra with common edge
y=e.map{|i|s=[];600.times{|j|s<<j if i==(i & g[j])};s}

#120 dodecahedral cells surrounding vertices of 600-cell. Search for sets of 20 tetrahedra with common vertex
z=(0..119).map{|i|s=[];600.times{|j|s<<j if [i]==([i] & g[j])};s}


#24-CELL
#24 vertices, a subset of the 600cell
o=v[0..23]

#96 edges, length 2, found by minimum distances between vertices
p=[]
24.times{|i|24.times{|j|
  p<<[i,j]  if i<j && ((v[i][0]-v[j][0])**2+(v[i][1]-v[j][1])**2+(v[i][2]-v[j][2])**2+(v[i][3]-v[j][3])**2)**0.5<2.1  
}}

#96 triangles
#If 2 edges share a common vertex and the other 2 vertices form an edge in the list, it is a valid triangle.
q=[]
96.times{|i|96.times{|j|
  q<< [p[i][0],p[i][1],p[j][1]] if i<j && p[i][0]==p[j][0] && p.index([p[i][1],p[j][1]])
}}


#24 cells. Calculates the centre of the cell and the 6 vertices nearest it
r=(0..23).map{|i|a,b=(-1)**i,(-1)**(i/2)
    c=[[a,b,0,0],[a,0,b,0],[a,0,0,b],[0,a,b,0],[0,a,0,b],[0,0,a,b]][i/4]
    s=[]
    24.times{|j|t=v[j]
    s<<j if (c[0]-t[0])**2+(c[1]-t[1])**2+(c[2]-t[2])**2+(c[3]-t[3])**2<=2 
    }
s}

https://en.wikipedia.org/wiki/600-cell

http://mathworld.wolfram.com/600-Cell.html

https://en.wikipedia.org/wiki/120-cell

http://mathworld.wolfram.com/120-Cell.html

https://en.wikipedia.org/wiki/24-cell

http://mathworld.wolfram.com/24-Cell.html

उपयोग और आउटपुट का उदाहरण

cell24 = polytope[[3,4,3]]

puts "vertices"
cell24[0].each{|i|p i}
puts "edges"
cell24[1].each{|i|p i}
puts "faces"
cell24[2].each{|i|p i}
puts "cells"
cell24[3].each{|i|p i}

vertices
[2, 0, 0, 0]
[0, 2, 0, 0]
[0, 0, 2, 0]
[0, 0, 0, 2]
[-2, 0, 0, 0]
[0, -2, 0, 0]
[0, 0, -2, 0]
[0, 0, 0, -2]
[1, 1, 1, 1]
[1, 1, 1, -1]
[1, 1, -1, 1]
[1, 1, -1, -1]
[1, -1, 1, 1]
[1, -1, 1, -1]
[1, -1, -1, 1]
[1, -1, -1, -1]
[-1, 1, 1, 1]
[-1, 1, 1, -1]
[-1, 1, -1, 1]
[-1, 1, -1, -1]
[-1, -1, 1, 1]
[-1, -1, 1, -1]
[-1, -1, -1, 1]
[-1, -1, -1, -1]
edges
[0, 8]
[0, 9]
[0, 10]
[0, 11]
[0, 12]
[0, 13]
[0, 14]
[0, 15]
[1, 8]
[1, 9]
[1, 10]
[1, 11]
[1, 16]
[1, 17]
[1, 18]
[1, 19]
[2, 8]
[2, 9]
[2, 12]
[2, 13]
[2, 16]
[2, 17]
[2, 20]
[2, 21]
[3, 8]
[3, 10]
[3, 12]
[3, 14]
[3, 16]
[3, 18]
[3, 20]
[3, 22]
[4, 16]
[4, 17]
[4, 18]
[4, 19]
[4, 20]
[4, 21]
[4, 22]
[4, 23]
[5, 12]
[5, 13]
[5, 14]
[5, 15]
[5, 20]
[5, 21]
[5, 22]
[5, 23]
[6, 10]
[6, 11]
[6, 14]
[6, 15]
[6, 18]
[6, 19]
[6, 22]
[6, 23]
[7, 9]
[7, 11]
[7, 13]
[7, 15]
[7, 17]
[7, 19]
[7, 21]
[7, 23]
[8, 9]
[8, 10]
[8, 12]
[8, 16]
[9, 11]
[9, 13]
[9, 17]
[10, 11]
[10, 14]
[10, 18]
[11, 15]
[11, 19]
[12, 13]
[12, 14]
[12, 20]
[13, 15]
[13, 21]
[14, 15]
[14, 22]
[15, 23]
[16, 17]
[16, 18]
[16, 20]
[17, 19]
[17, 21]
[18, 19]
[18, 22]
[19, 23]
[20, 21]
[20, 22]
[21, 23]
[22, 23]
faces
[0, 8, 9]
[0, 8, 10]
[0, 8, 12]
[0, 9, 11]
[0, 9, 13]
[0, 10, 11]
[0, 10, 14]
[0, 11, 15]
[0, 12, 13]
[0, 12, 14]
[0, 13, 15]
[0, 14, 15]
[1, 8, 9]
[1, 8, 10]
[1, 8, 16]
[1, 9, 11]
[1, 9, 17]
[1, 10, 11]
[1, 10, 18]
[1, 11, 19]
[1, 16, 17]
[1, 16, 18]
[1, 17, 19]
[1, 18, 19]
[2, 8, 9]
[2, 8, 12]
[2, 8, 16]
[2, 9, 13]
[2, 9, 17]
[2, 12, 13]
[2, 12, 20]
[2, 13, 21]
[2, 16, 17]
[2, 16, 20]
[2, 17, 21]
[2, 20, 21]
[3, 8, 10]
[3, 8, 12]
[3, 8, 16]
[3, 10, 14]
[3, 10, 18]
[3, 12, 14]
[3, 12, 20]
[3, 14, 22]
[3, 16, 18]
[3, 16, 20]
[3, 18, 22]
[3, 20, 22]
[4, 16, 17]
[4, 16, 18]
[4, 16, 20]
[4, 17, 19]
[4, 17, 21]
[4, 18, 19]
[4, 18, 22]
[4, 19, 23]
[4, 20, 21]
[4, 20, 22]
[4, 21, 23]
[4, 22, 23]
[5, 12, 13]
[5, 12, 14]
[5, 12, 20]
[5, 13, 15]
[5, 13, 21]
[5, 14, 15]
[5, 14, 22]
[5, 15, 23]
[5, 20, 21]
[5, 20, 22]
[5, 21, 23]
[5, 22, 23]
[6, 10, 11]
[6, 10, 14]
[6, 10, 18]
[6, 11, 15]
[6, 11, 19]
[6, 14, 15]
[6, 14, 22]
[6, 15, 23]
[6, 18, 19]
[6, 18, 22]
[6, 19, 23]
[6, 22, 23]
[7, 9, 11]
[7, 9, 13]
[7, 9, 17]
[7, 11, 15]
[7, 11, 19]
[7, 13, 15]
[7, 13, 21]
[7, 15, 23]
[7, 17, 19]
[7, 17, 21]
[7, 19, 23]
[7, 21, 23]
cells
[0, 1, 8, 9, 10, 11]
[1, 4, 16, 17, 18, 19]
[0, 5, 12, 13, 14, 15]
[4, 5, 20, 21, 22, 23]
[0, 2, 8, 9, 12, 13]
[2, 4, 16, 17, 20, 21]
[0, 6, 10, 11, 14, 15]
[4, 6, 18, 19, 22, 23]
[0, 3, 8, 10, 12, 14]
[3, 4, 16, 18, 20, 22]
[0, 7, 9, 11, 13, 15]
[4, 7, 17, 19, 21, 23]
[1, 2, 8, 9, 16, 17]
[2, 5, 12, 13, 20, 21]
[1, 6, 10, 11, 18, 19]
[5, 6, 14, 15, 22, 23]
[1, 3, 8, 10, 16, 18]
[3, 5, 12, 14, 20, 22]
[1, 7, 9, 11, 17, 19]
[5, 7, 13, 15, 21, 23]
[2, 3, 8, 12, 16, 20]
[3, 6, 10, 14, 18, 22]
[2, 7, 9, 13, 17, 21]
[6, 7, 11, 15, 19, 23]

1
वाह ये तो कमाल का जवाब है !! मुझे बहुत आश्चर्य है कि आप ऐसा करने में सक्षम थे ~ 200 लाइनों में। मैंने क्यूब, टेट्राहेड्रॉन, 600-सेल और कुछ अन्य लोगों को चलाया, और वे अच्छे दिखे। उत्पादन को सत्यापित करना कठिन है क्योंकि इसमें बहुत कुछ है; आउटपुट के लिए प्रोग्राम की तुलना में लंबा होना बहुत आसान है, लेकिन मैं इसके लिए आपका शब्द ले लूंगा। मैं इसे ओपनजीएल में लोड करने की कोशिश करने जा रहा हूं और प्लेटोनिक सॉलिड्स को देख सकता हूं जो सभी चेहरों के सूचीबद्ध होने के बाद सीधा होना चाहिए। मुझे लगता है कि समतल जगह में टेस्यूलेशन जोड़ना आसान होगा, और मैं कोशिश कर सकता हूं।
टोनी रुथ

@TonyRuth कुंजी सबसे अच्छा एल्गोरिथ्म ढूंढ रही थी। कम लाइनें = त्रुटि के लिए कम जगह। पहली चीज़ जो मैंने की थी वह यह थी कि 3 अनंत आयामी परिवारों के अलावा क्या मौजूद था और जब मैंने जवाब देने का फैसला किया। क्या जग्गी की टिप्पणी एक भगवान थी (मैं उस प्रकार के समाधान के बारे में सोच रहा था क्योंकि विकिपीडिया की विधि कठिन लग रही थी) इसलिए गैर-पूर्णांक निर्देशांक न्यूनतम रखे जाते हैं। मैं चाहता था कि बाउंटी की समय सीमा समाप्त होने से पहले इसे पूरा कर लिया जाए ताकि जाँच पूरी तरह से पूरी तरह से न हो और मैंने उन्हें प्लॉट नहीं किया। मुझे किसी भी त्रुटि के बारे में बताएं - मैंने कुछ घंटों पहले 24सेल को सही किया था।
लेवल रिवर सेंट

@TonyRuth चेहरे के कोने किसी विशेष क्रम में नहीं हैं (वे घड़ी की सूई या किसी भी चीज़ में चेहरे को गोल नहीं करते हैं)। उच्च आयामों के लिए, कोई मानक क्रम नहीं है। हाइपरक्यूब्स के संख्यात्मक क्रम में सूचीबद्ध चेहरे हैं, इसलिए 2 और 3 के कोने तिरछे विपरीत हैं (आपको 1 या 2 या 3 या 4 और शीर्ष को स्वैप करने की आवश्यकता होगी यदि आप उन्हें एक दक्षिणावर्त / एंटीक्लॉकवाइज अर्थ में चाहते हैं। डोडेकेहेड्रोन में चेहरे होने चाहिए। दक्षिणावर्त / एंटीक्लॉकवाइज ऑर्डर लेकिन 120 एसएल में किसी भी और सभी आदेशों में चेहरा लंबवत होगा।
लेवल रिवर सेंट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.