Phiên dịch đa ngôn ngữ thường xuyên lồi lõm


15

Lý lịch

Các Schläfli Symbol là một ký hiệu có dạng {p, q, r, ...} định nghĩa polytopes và tessellations thường xuyên.

Biểu tượng Schläfli là một mô tả đệ quy, bắt đầu bằng một đa giác đều có mặt p là {p}. Ví dụ: {3} là một tam giác đều, {4} là một hình vuông và cứ thế.

Một khối đa diện đều có q các mặt đa giác mặt p thông thường xung quanh mỗi đỉnh được biểu thị bằng {p, q}. Ví dụ: khối lập phương có 3 hình vuông xung quanh mỗi đỉnh và được biểu thị bằng {4,3}.

Một đa giác 4 ​​chiều thông thường, với r {p, q} các ô đa diện đều đặn xung quanh mỗi cạnh được biểu thị bằng {p, q, r}. Ví dụ: một tesseract, {4,3,3}, có 3 hình khối, {4,3}, xung quanh một cạnh.

Nói chung, một đa giác thông thường {p, q, r, ..., y, z} có các mặt z {p, q, r, ..., y} xung quanh mỗi đỉnh, trong đó một đỉnh là một đỉnh trong khối đa diện, một cạnh trong 4 đa giác, một mặt trong 5 đa giác, một ô trong 6 đa giác và một mặt (n-3) trong một đa giác.

Một polytope thông thường có một hình đỉnh thông thường. Hình đỉnh của một đa giác thông thường {p, q, r, ... y, z} là {q, r, ... y, z}.

Các đa giác thông thường có thể có các phần tử đa giác sao, như hình ngũ giác, với ký hiệu {5/2}, được biểu thị bằng các đỉnh của hình ngũ giác nhưng được kết nối xen kẽ.

Biểu tượng Schläfli có thể đại diện cho một khối đa diện lồi hữu hạn, một phần tử vô hạn của không gian Euclide hoặc một phần tử vô hạn của không gian hyperbol, tùy thuộc vào khuyết tật góc của công trình. Khiếm khuyết góc dương cho phép hình vẽ đỉnh gấp lại thành một chiều cao hơn và lặp lại thành chính nó như một đa giác. Một khuyết điểm góc bằng không cho thấy không gian có cùng chiều với các khía cạnh. Một khiếm khuyết góc âm không thể tồn tại trong không gian thông thường, nhưng có thể được xây dựng trong không gian hyperbol.

Cuộc thi

Mục tiêu của bạn là tạo ra một chương trình mà khi được thông qua Biểu tượng Schläfli sẽ trả về một mô tả đầy đủ về một đa giác lồi. Đây chỉ là một tập hợp con của các Biểu tượng Schläfli, nhưng nó là đơn giản nhất, tôi tin ngay cả khi không có các khả năng khác thì đây sẽ là một nhiệm vụ rất khó khăn và các đa giác là điểm khởi đầu cho các điều kiện. Các quy tắc của câu hỏi này được thiết kế với ý tưởng kết quả này là một API và tôi không thể tìm thấy bất kỳ chương trình nào như vậy trên internet.

Chương trình của bạn phải thực hiện tất cả những điều sau đây.

  • Chương trình phải có khả năng tạo ra bất kỳ đa giác lồi thông thường có chiều hữu hạn. Trong 2 chiều, điều này bao gồm n-gons. Trong 3 chiều, đây là các chất rắn, trong 4 chiều, bao gồm tesseract, orthoplex và một vài thứ khác)
  • Chương trình phải (a) đặt một điểm trên điểm gốc hoặc (b) đảm bảo rằng trung bình của tất cả các điểm là điểm gốc. Định hướng không quan trọng. Kích thước tổng thể không quan trọng.
  • Chương trình phải cung cấp một mô tả đầy đủ có nghĩa là đối với một đối tượng 4 chiều, chương trình sẽ trả về / in các đỉnh, cạnh, mặt và khối đa diện. Thứ tự này được báo cáo không quan trọng. Đối với khối đa diện, đây là thông tin bạn cần để hiển thị đối tượng.

Bạn không cần phải xử lý:

  • Tàu thuyền
  • Hình học hyperbol
  • Biểu tượng phân số Schläfli (không lồi)
  • Biểu tượng Schläfli nhúng (nghiêng không đồng nhất)

Nếu được yêu cầu làm bất kỳ điều nào trong số những điều này, bạn có thể trả lại lỗi.

Ví dụ: Khối lập phương

Đầu vào:

4 3

Đầu ra:

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

Tôi đã có một số ý tưởng về cách thuật toán này có thể hoạt động và rất đệ quy, nhưng cho đến nay tôi đã thất bại, nhưng nếu bạn đang tìm cảm hứng hãy xem: https://en.wikipedia.org/wiki/Euler_characteristic

Như một ví dụ về việc tính ra số đỉnh, cạnh và mặt, hãy xem xét khối lập phương là {4,3}. Nếu chúng ta nhìn vào 4 ban đầu, thì nó có 4 cạnh và 4 đỉnh. Bây giờ nếu chúng ta nhìn vào 3 cạnh tiếp theo, chúng ta biết rằng 3 cạnh gặp nhau ở mỗi đỉnh, mỗi cạnh kết nối với 2 đỉnh, 2 mặt gặp nhau ở mỗi cạnh, mỗi mặt kết nối với 4 cạnh (vì các cạnh vuông) và chúng ta có công thức đặc trưng Euler.

E = 3/2 V

E = 4/2 F

V - E + F = 2

Mà cho E = 12, V = 8, F = 6.

Chấm điểm

Để giữ câu hỏi về chủ đề này, điều này đã được sửa đổi thành Code Golf. Mã ngắn nhất sẽ thắng.

Một github đã được tạo ra cho câu hỏi này


1
Googling cho thấy chỉ có 3 họ polytope thông thường mở rộng ra ngoài 4 chiều: tương tự như khối lập phương, khối tám mặt và tứ diện. Có vẻ đơn giản hơn khi viết cho các gia đình này và mã hóa phần còn lại (hai đa giác 3d, ba đa giác 4d và gia đình vô hạn của các đa giác 2d.) Theo như tôi có thể thấy rằng đáp ứng được thông số kỹ thuật nhưng sẽ không thể khái quát được. Đó sẽ là một câu trả lời hợp lệ? Có thể khả thi khi viết một thuật toán đệ quy để tạo các đồ thị tôpô ngoài phạm vi của thông số kỹ thuật, nhưng kẻ giết người với cách tiếp cận đó ngay cả trong thông số kỹ thuật đang tính toán tọa độ.
Cấp sông St

Làm thế nào để chúng ta biết các đỉnh thực tế, bằng cách chỉ biết chúng là bằng nhau?
Matthew Roh

@SIGSEGV yêu cầu duy nhất được chỉ định là nguồn gốc phải tương ứng với trung tâm hoặc một trong các điểm. Điều đó cung cấp nhiều phạm vi để xoay hình dạng như bạn muốn. en.wikipedia.org/wiki/Simplex đưa ra một thuật toán để tính toán tọa độ của hypertetrahedrons (mà có lẽ có thể được mở rộng để icosahedron và analogue 4d của nó nhưng làm điều đó là quá nhiều đối với tôi, vì vậy câu hỏi của tôi.) Các hypercubes và hyperoctahedrons có tọa độ số nguyên đẹp (và các siêu khối quá thực tế, nhưng thường chỉ có nhiều kích thước hơn hình dạng, không gọn gàng.)
Level River St

@LevelRiverSt, vâng, vì các đa giác thông thường duy nhất tồn tại sẽ được đề cập trong các đề xuất của bạn, sau đó, bạn có thể mã hóa chúng.
Tony Ruth

Tôi đã bỏ phiếu kết thúc cho câu hỏi này bởi vì đây là một thử thách kiểu súng nhanh nhất ở phía tây , trong đó câu trả lời hợp lệ đầu tiên chiến thắng. Điều này thường không được coi là một tiêu chí chiến thắng hợp lệ. Tôi không biết làm thế nào mà nó đã được mở quá lâu, nó nên bị đóng lại.
Đăng Rock Garf Hunter

Câu trả lời:


2

Con trăn

Đây là một chương trình đệ quy mà không có trường hợp đặc biệt. Bỏ qua các dòng và nhận xét trống, nó ít hơn 100 90 dòng, bao gồm cả kiểm tra một cách vô cớ công thức của Euler ở cuối. Không bao gồm các định nghĩa về các hàm toán học đặc biệt (có thể được cung cấp bởi một thư viện) và i / o, thế hệ đa giác là 50 dòng mã. Và nó thậm chí còn làm các đa giác sao!

Đa giác đầu ra sẽ có độ dài cạnh 1 và sẽ ở vị trí và hướng chính tắc, theo nghĩa sau:

  • đỉnh đầu tiên là gốc
  • cạnh đầu tiên nằm dọc theo trục + x,
  • mặt thứ nhất nằm trong nửa mặt phẳng + y của mặt phẳng xy,
  • 3 ô đầu tiên nằm trong nửa không gian + z của không gian xyz, v.v.

Ngoài ra, danh sách đầu ra không theo thứ tự cụ thể. (Chà, thực ra, điều đó không hoàn toàn đúng-- chúng thực sự sẽ xuất hiện theo thứ tự bắt đầu từ yếu tố đầu tiên và mở rộng ra bên ngoài.)

Không có kiểm tra biểu tượng schlafli không hợp lệ; nếu bạn cho nó một cái, chương trình có thể sẽ tắt đường ray (vòng lặp vô tận, tràn ngăn xếp hoặc chỉ bỏ rác).

Nếu bạn yêu cầu một lát phẳng vô hạn như {4,4} hoặc {3,6} hoặc {6,3}, chương trình sẽ thực sự bắt đầu tạo ra ốp lát, nhưng nó sẽ tồn tại mãi mãi cho đến khi hết dung lượng, không bao giờ hết hoàn thiện cũng không sản xuất đầu ra. Điều này sẽ không quá khó để sửa chữa (chỉ cần đặt giới hạn về số lượng phần tử cần tạo; kết quả sẽ là một vùng khá mạch lạc của hình ảnh vô hạn, vì các phần tử được tạo theo thứ tự tìm kiếm đầu tiên theo chiều rộng).

Mật mã

#!/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)

Dùng thử trong một số trường hợp

Đầu vào ( khối ):

4 3

Đầu ra:

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

Đầu vào từ một vỏ lệnh unix ( polychoron 120 ô ):

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

Đầu ra:

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

Đầu vào ( đa giác chéo 10 chiều ):

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

Đầu ra:

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):

Đầu vào ( đơn giản 15 chiều ):

$ 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):

Đa giác sao

Ha, và nó chỉ tự nhiên làm sao đa giác quá! Tôi thậm chí không cần phải thử :-) Ngoại trừ một chút về công thức của Euler cuối cùng không thành công, vì công thức đó không hợp lệ cho các đa giác sao.

Đầu vào ( khối mười hai mặt nhỏ ):

5/2 5

Đầu ra:

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

Đầu vào ( 120 ô lớn ):

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

Đầu ra:

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

Cảm ơn vì đã làm sống lại câu hỏi này, và câu trả lời của bạn trông khá ấn tượng. Tôi thích bản chất đệ quy và các số liệu sao. Tôi đã kết nối mã của bạn với một số opengl để vẽ các đa giác (xem liên kết github ở trên).
Tony Ruth

14

Hồng ngọc

Lý lịch

Có ba họ của polytope thường xuyên mở rộng thành các chiều vô hạn:

  • các đơn giản, trong đó tứ diện là một thành viên (tôi sẽ thường gọi chúng ở đây là hypertetrahedra, mặc dù thuật ngữ đơn giản là chính xác hơn.) Các biểu tượng schlafi của chúng có dạng {3,3,...,3,3}

  • các khối n, trong đó khối lập phương là thành viên. Biểu tượng schlafi của họ có dạng{4,3,...,3,3}

  • các orthoplexes, trong đó bát diện là một thành viên (tôi sẽ thường gọi chúng ở đây là hyperoctahedra) Các biểu tượng schlafi của chúng có dạng {3,3,...,3,4}

Có thêm một họ vô hạn của các đa giác thông thường, biểu tượng {m} đa giác , đó là đa giác 2 chiều, có thể có bất kỳ số cạnh m nào.

Ngoài ra, chỉ có năm trường hợp đặc biệt khác của polytope thông thường: icosahedron 3 chiều {3,5}và dodecahedron {5,3}; 4 chiều của chúng tương tự 600 tế bào {3,3,5}và 120 tế bào {5,3,3}; và một đa giác 4 ​​chiều khác, 24 ô{3,4,3} (có các tương tự gần nhất trong 3 chiều là khối lập phương và khối kép của nó là khối mười hai hình thoi.)

Chức năng chính

Dưới đây là polytopechức năng chính diễn giải biểu tượng schlafi. Nó mong đợi một mảng các số và trả về một mảng chứa một loạt các mảng như sau:

  • Một mảng gồm tất cả các đỉnh, mỗi đỉnh được biểu thị dưới dạng một mảng phần tử n (trong đó n là số lượng kích thước)

  • Một mảng gồm tất cả các cạnh, mỗi cạnh được biểu thị dưới dạng 2 phần tử của các chỉ số đỉnh

  • Một mảng gồm tất cả các mặt, mỗi mặt được biểu thị dưới dạng phần tử m của các chỉ số đỉnh (trong đó m là số đỉnh trên mỗi mặt)

và như vậy là thích hợp cho số lượng kích thước.

Nó tự tính toán các đa giác 2d, gọi các hàm cho 3 họ chiều vô hạn và sử dụng các bảng tra cứu cho năm trường hợp đặc biệt. Nó hy vọng sẽ tìm thấy các hàm và bảng được khai báo ở trên nó.

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
}

Chức năng cho các họ tứ diện, khối lập phương và khối bát diện

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

https://en.wikipedia.org/wiki/5-cell (4d đơn giản)

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

Giải thích gia đình tứ diện - tọa độ

một đơn giản n / hypertetrahedron n chiều có n + 1 điểm. Rất dễ dàng để đưa ra các đỉnh của đơn giản n chiều trong n + 1 chiều.

Do đó (1,0,0),(0,1,0),(0,0,1)mô tả một tam giác 2d được nhúng trong 3 chiều và (1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)mô tả một tứ diện 3d được nhúng trong 4 chiều. Điều này dễ dàng được xác minh bằng cách xác nhận rằng tất cả các khoảng cách giữa các đỉnh là sqrt (2).

Các thuật toán phức tạp khác nhau được đưa ra trên internet để tìm các đỉnh cho đơn giản n chiều trong không gian n chiều. Tôi đã tìm thấy một câu hỏi đơn giản đáng chú ý trong nhận xét của Will Jagy về câu trả lời này /mathpro//a/38725 . Điểm cuối cùng nằm trên đường p=q=...=x=y=zở khoảng cách sqrt (2) so với các điểm khác. Do đó, tam giác trên có thể được chuyển đổi thành một tứ diện bằng cách thêm một điểm tại một trong hai (-1/3,-1/3,-1/3)hoặc (1,1,1). Hai giá trị có thể có của tọa độ cho điểm cuối cùng được cho bởi (1-(1+n)**0.5)/n(1+(1+n)**0.5)/n

Như câu hỏi nói rằng kích thước của n-tope không quan trọng, tôi thích nhân với n và sử dụng tọa độ (n,0,0..0)cho đến (0..0,0,n)điểm cuối cùng trong (t,t,..,t,t)đó t = 1-(1+n)**0.5cho đơn giản.

Vì tâm của khối tứ diện này không nằm ở gốc tọa độ, nên việc hiệu chỉnh tất cả các tọa độ phải được thực hiện bằng đường thẳng s.map!{|j|j-((1-(1+n)**0.5)+n)/(1+n)}tìm trung tâm cách gốc tọa độ bao xa và trừ đi. Tôi đã giữ điều này như là một hoạt động riêng biệt. Tuy nhiên tôi đã sử dụng s[i]+=nnơi s[i]=nsẽ làm, để ám chỉ thực tế là khi mảng được khởi tạo bởi s=[0]*nchúng ta có thể đặt phần bù chính xác vào đây thay vào đó và thực hiện chỉnh sửa định tâm ngay từ đầu thay vì kết thúc.

Giải thích gia đình tứ diện - cấu trúc liên kết đồ thị

Biểu đồ của đơn giản là biểu đồ hoàn chỉnh: mọi đỉnh được kết nối chính xác một lần với mọi đỉnh khác. Nếu chúng ta có một n đơn giản, chúng ta có thể loại bỏ bất kỳ đỉnh nào để tạo một đơn vị n-1, xuống đến điểm mà chúng ta có một hình tam giác hoặc thậm chí là một cạnh.

Do đó, chúng tôi có tổng cộng 2 ** (n + 1) mục để phân loại, mỗi mục được biểu thị bằng một số nhị phân. Điều này dao động từ tất cả 0s cho hư vô, thông qua một 1cho một đỉnh và hai 1s cho một cạnh, lên đến tất cả1 s cho đa giác hoàn chỉnh.

Chúng tôi thiết lập một mảng các mảng trống để lưu trữ các phần tử của từng kích thước. Sau đó, chúng tôi lặp từ 0 đến (2 ** n + 1) để tạo từng tập con có thể của các đỉnh và lưu trữ chúng trong mảng theo kích thước của mỗi tập hợp con.

Chúng tôi không quan tâm đến bất cứ điều gì nhỏ hơn một cạnh (một đỉnh hoặc một số 0) cũng như trong đa giác hoàn chỉnh (vì khối hoàn chỉnh không được đưa ra trong ví dụ trong câu hỏi), vì vậy chúng tôi quay lại tg[2..n]để loại bỏ các yếu tố không mong muốn này. Trước khi trở về, chúng tôi đã xử lý [tv] chứa tọa độ đỉnh ở đầu.

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]}

giải thích các khối lập phương và khối bát diện - tọa độ

Khối lập phương n có 2**ncác đỉnh, mỗi đỉnh được biểu thị bằng một mảng n 1s và -1s (tất cả các khả năng đều được phép.) Chúng tôi lặp qua các chỉ mục 0đến 2**n-1danh sách tất cả các đỉnh và xây dựng một mảng cho mỗi đỉnh bằng cách lặp qua các bit của lập chỉ mục và thêm -1hoặc 1vào mảng (bit quan trọng nhất đến bit quan trọng nhất.) Do đó Binary 1101trở thành điểm 4d [1,-1,1,1].

N-octahedron hoặc n-orthoplex có 2ncác đỉnh, với tất cả các tọa độ bằng 0 trừ một tọa độ, 1hoặc là một -1. Thứ tự của các đỉnh trong mảng được tạo là [[1,0,0..],[-1,0,0..],[0,1,0..],[0,-1,0..],[0,0,1..],[0,0,-1..]...]. Lưu ý rằng vì bát diện là kép của khối lập phương, các đỉnh của khối bát diện được xác định bởi các tâm của các mặt của khối lập phương bao quanh nó.

giải thích các họ khối và khối bát diện - cấu trúc liên kết đồ thị

Một số nguồn cảm hứng được lấy từ các phía Hypercube và thực tế rằng hyperoctahedron là kép của hypercube.

Đối với n-cube, có 3**ncác mục để phân loại. Ví dụ: khối 3 có 3**3= 27 phần tử. Điều này có thể được nhìn thấy bằng cách nghiên cứu khối lập phương của rubik, có 1 tâm, 6 mặt, 12 cạnh và 8 đỉnh với tổng số 27. Chúng tôi lặp qua -1,0 và -1 trong tất cả các kích thước xác định một khối n có độ dài 2x2x2 .. và trả lại tất cả các đỉnh KHÔNG ở phía đối diện của khối. Do đó, tâm điểm của khối lập phương trả về tất cả các đỉnh 2 ** n và di chuyển một đơn vị ra khỏi tâm dọc theo bất kỳ trục nào làm giảm một nửa số đỉnh.

Như với họ tứ diện, chúng ta bắt đầu bằng cách tạo ra một mảng trống và điền vào nó theo số lượng đỉnh trên mỗi phần tử. Lưu ý rằng vì số lượng đỉnh thay đổi là 2 ** n khi chúng ta đi qua các cạnh, mặt, hình khối, v.v., chúng ta sử dụng log2(s.size)+1thay vì đơn giản s.size. Một lần nữa, chúng ta phải loại bỏ hypercube và tất cả các phần tử có ít hơn 2 đỉnh trước khi quay trở lại hàm.

Họ bát diện / orthoplex là đối ngẫu của họ khối, do đó một lần nữa có 3**ncác mục để phân loại. Ở đây chúng tôi lặp lại -1,0,1cho tất cả các kích thước và nếu tọa độ khác không của một đỉnh bằng với tọa độ tương ứng của điểm, thì đỉnh được thêm vào danh sách tương ứng với điểm đó. Do đó, một cạnh tương ứng với một điểm có hai tọa độ khác 0, một tam giác với một điểm có 3 tọa độ khác 0 và một tứ diện với một điểm có 4 tiếp điểm khác không (trong không gian 4d.)

Các mảng kết quả của đỉnh cho mỗi điểm được lưu trữ trong một mảng lớn như đối với các trường hợp khác và chúng tôi phải xóa bất kỳ phần tử nào có ít hơn 2 đỉnh trước khi quay lại. Nhưng trong trường hợp này, chúng tôi không phải xóa n-tope cha hoàn chỉnh vì thuật toán không ghi lại nó.

Việc triển khai mã cho khối được thiết kế giống nhau nhất có thể. Trong khi điều này có một sự tao nhã nhất định, có khả năng các thuật toán hiệu quả hơn dựa trên các nguyên tắc tương tự có thể được đưa ra.

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

Mã để tạo bảng cho các trường hợp đặc biệt 3d

Một hướng với icosahedron / dodecahedron được định hướng với trục đối xứng năm lần song song với kích thước cuối cùng đã được sử dụng, vì nó được tạo ra để dán nhãn nhất quán cho các bộ phận. Việc đánh số các đỉnh và các mặt của icosahedron là theo sơ đồ trong các nhận xét mã, và đảo ngược cho khối mười hai mặt.

Theo https://en.wikipedia.org/wiki/Regular_icosahedron , vĩ độ của 10 đỉnh không phân cực của icosahedron là +/- arctan (1/2) Các tọa độ của 10 đỉnh đầu tiên của icosahedron được tính từ này, trên hai vòng tròn bán kính 2 ở khoảng cách +/- 2 từ mặt phẳng xy. Điều này làm cho bán kính tổng thể của chu vi hình vuông (5) vì vậy 2 đỉnh cuối cùng nằm ở (0,0, + / - sqrt (2)).

Các tọa độ của các đỉnh của khối mười hai mặt được tính bằng cách tính tổng tọa độ của ba đỉnh icosahedron bao quanh chúng.

=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]]

Mã để tạo các bảng cho trường hợp đặc biệt 4d

Đây là một chút của một hack. Mã này mất vài giây để chạy. Sẽ tốt hơn để lưu trữ đầu ra trong một tệp và tải nó theo yêu cầu.

Danh sách 120 tọa độ đỉnh cho 600cell là từ http://mathworld.wolfram.com/600-Cell.html . 24 tọa độ đỉnh không có tỷ lệ vàng tạo thành các đỉnh của 24 ô. Wikipedia có cùng sơ đồ nhưng có lỗi trong thang đo tương đối của 24 tọa độ này và 96 tọa độ khác.

#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

Ví dụ về sử dụng và đầu ra

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
Wow đây là một câu trả lời tuyệt vời !! Tôi rất ngạc nhiên khi bạn có thể làm điều này trong ~ 200 dòng. Tôi chạy khối lập phương, tứ diện, 600 ô và một vài cái khác, và chúng trông ổn. Thật khó để xác minh đầu ra vì có quá nhiều; nó khá dễ dàng cho đầu ra dài hơn chương trình, nhưng tôi sẽ chú ý đến nó. Tôi sẽ thử tải cái này vào openGL và xem các khối rắn đơn giản nên đơn giản vì tất cả các mặt được liệt kê. Tôi nghĩ rằng việc thêm các tàu trong không gian phẳng sẽ dễ dàng và tôi cũng có thể thử điều đó.
Tony Ruth

@TonyRuth chìa khóa đã tìm ra thuật toán tốt nhất. Ít dòng hơn = ít chỗ hơn cho lỗi. Điều đầu tiên tôi làm là kiểm tra những gì tồn tại bên cạnh 3 gia đình vô hạn và đó là khi tôi quyết định trả lời. Ý kiến ​​của Jagy sẽ là một ơn trời (tôi đã suy nghĩ về loại giải pháp đó vì phương pháp của wikipedia có vẻ khó) vì vậy các tọa độ không nguyên được giữ ở mức tối thiểu. Tôi muốn hoàn thành nó trước khi tiền thưởng hết hạn vì vậy việc kiểm tra chưa được thực hiện triệt để và tôi đã không vẽ chúng. Hãy cho tôi biết bất kỳ lỗi nào - tôi đã sửa 24cell vài giờ trước.
Cấp sông St

Các đỉnh của khuôn mặt @TonyRuth không theo thứ tự cụ thể (chúng không đi vòng quanh mặt theo chiều kim đồng hồ hoặc bất cứ thứ gì). Đối với kích thước cao hơn, không có thứ tự tiêu chuẩn. Các hypercubes có các mặt được liệt kê theo thứ tự số, vì vậy các đỉnh thứ 2 và 3 ngược nhau theo đường chéo (bạn sẽ cần hoán đổi đỉnh thứ 1 & thứ 2 hoặc thứ 3 và thứ 4 nếu bạn muốn chúng theo chiều kim đồng hồ / ngược chiều kim đồng hồ.) thứ tự theo chiều kim đồng hồ / ngược chiều kim đồng hồ nhưng 120cell sẽ có các đỉnh mặt trong bất kỳ và tất cả các đơn đặt hàng.
Cấp sông St
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.