我编写了一个脚本,它采用指定的八面体并对其进行细化。对于上下文,我有
iterations
设置为 0
、1
和 2
的输出图片。
但是,当我设置
iterations=3
时,我收到以下错误:
Traceback (most recent call last):
File "/Users/amaurydeburgos/Documents/WinterBreak2023.py", line 78, in <module>
ax.add_collection3d(Poly3DCollection([ [ Vertices[i] for i in f] for f in Faces],edgecolors='k',facecolors='w'))
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/mpl_toolkits/mplot3d/art3d.py", line 701, in __init__
super().__init__(verts, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/matplotlib/_api/deprecation.py", line 454, in wrapper
return func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/matplotlib/collections.py", line 1176, in __init__
self.set_verts(verts, closed)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/mpl_toolkits/mplot3d/art3d.py", line 745, in set_verts
self.get_vector(verts)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/mpl_toolkits/mplot3d/art3d.py", line 734, in get_vector
xs, ys, zs = np.row_stack(segments3d).T
File "<__array_function__ internals>", line 200, in vstack
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/numpy/core/shape_base.py", line 296, in vstack
return _nx.concatenate(arrs, 0, dtype=dtype, casting=casting)
File "<__array_function__ internals>", line 200, in concatenate
ValueError: all the input array dimensions except for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 3 and the array at index 689 has size 0
我不知道出了什么问题。任何帮助是极大的赞赏。我写的脚本如下:
import pylab as plt
import numpy as np
from numpy import array
from numpy.linalg import norm
from operator import add
from itertools import combinations
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
# Initial octahedron
Vertices = [ (0,0,1), (1,0,0), (0,1,0), (-1,0,0), (0,-1,0), (0,0,-1) ]
Edges = { frozenset({0,1}), frozenset({0,2}), frozenset({0,3}), frozenset({0,4}),
frozenset({1,2}), frozenset({2,3}), frozenset({3,4}), frozenset({1,4}),
frozenset({1,5}), frozenset({2,5}), frozenset({3,5}), frozenset({4,5}) }
Faces = { frozenset({0,1,2}), frozenset({0,2,3}), frozenset({0,3,4}), frozenset({0,1,4}),
frozenset({1,2,5}), frozenset({2,3,5}), frozenset({3,4,5}), frozenset({1,4,5}) }
iterations = 3
for i in range(iterations):
# Initializing set of new vertices, new edges, and new faces
counter = len(Vertices)-1
newVertices = []
newEdges = set()
newFaces = set()
# Adding elements of newVertices and trivial elements of newEdges
for edge in Edges:
counter = counter+1
newVertex = np.array([0,0,0])
for vertex in edge:
newVertex = np.add(newVertex,np.array(Vertices[vertex]))
newEdge = frozenset({vertex,counter})
newEdges.add(newEdge)
newVertex = np.divide(newVertex,norm(newVertex,2))
newVertices.append(tuple(newVertex))
# Adding non-trivial elements of newEdges and elements of newFaces
for face in Faces:
middleFace=set()
SpecialEdges=set()
pairsOfSpecialEdges={(a,b) for a,b in combinations({edge for edge in newEdges if len(edge.intersection(face))==1},2) if (a & b) and len((a-face).intersection(b-face))==1}
for pair in pairsOfSpecialEdges:
for edge in pair:
SpecialEdges.add(edge)
for vertex in face:
incidentEdges={edge for edge in SpecialEdges if vertex in edge}
newEdge=set()
for edge in incidentEdges:
for v in edge:
if v==vertex:
continue
else:
newEdge.add(v)
middleFace.add(v)
newEdges.add(frozenset(newEdge))
newEdge.add(vertex)
newFaces.add(frozenset(newEdge))
newFaces.add(frozenset(middleFace))
Vertices = Vertices+newVertices
Edges.clear()
Edges.update(newEdges)
Faces.clear()
Faces.update(newFaces)
### Plotting ###
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.set(xlim=(-1,1), ylim=(-1,1), zlim=(-1,1))
ax.add_collection3d(Poly3DCollection([ [ Vertices[i] for i in f] for f in Faces],edgecolors='k',facecolors='w'))
plt.axis('off')
plt.show()
所以我看了一下,我相信你的循环中的某些东西可能正在创建顶点数量较少的多边形(老实说,没有看得太深以确定它发生在哪里/如何发生)。
Poly3DCollection 一定会抱怨它无法创建没有边的多边形。
希望这足以为您指明正确的方向。该应用程序非常好,如果您设法修复它,希望看到它功能齐全,祝您好运! :)
import pylab as plt
import numpy as np
from numpy import array
from numpy.linalg import norm
from operator import add
from itertools import combinations
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
# Initial octahedron
Vertices = [ (0,0,1), (1,0,0), (0,1,0), (-1,0,0), (0,-1,0), (0,0,-1) ]
Edges = { frozenset({0,1}), frozenset({0,2}), frozenset({0,3}), frozenset({0,4}),
frozenset({1,2}), frozenset({2,3}), frozenset({3,4}), frozenset({1,4}),
frozenset({1,5}), frozenset({2,5}), frozenset({3,5}), frozenset({4,5}) }
Faces = { frozenset({0,1,2}), frozenset({0,2,3}), frozenset({0,3,4}), frozenset({0,1,4}),
frozenset({1,2,5}), frozenset({2,3,5}), frozenset({3,4,5}), frozenset({1,4,5}) }
for iterations in range(0,3):
# iterations = 3
for i in range(iterations):
# Initializing set of new vertices, new edges, and new faces
counter = len(Vertices)-1
newVertices = []
newEdges = set()
newFaces = set()
# Adding elements of newVertices and trivial elements of newEdges
for edge in Edges:
counter = counter+1
newVertex = np.array([0,0,0])
for vertex in edge:
newVertex = np.add(newVertex,np.array(Vertices[vertex]))
newEdge = frozenset({vertex,counter})
newEdges.add(newEdge)
newVertex = np.divide(newVertex,norm(newVertex,2))
newVertices.append(tuple(newVertex))
# Adding non-trivial elements of newEdges and elements of newFaces
for face in Faces:
middleFace=set()
SpecialEdges=set()
pairsOfSpecialEdges={(a,b) for a,b in combinations({edge for edge in newEdges if len(edge.intersection(face))==1},2) if (a & b) and len((a-face).intersection(b-face))==1}
for pair in pairsOfSpecialEdges:
for edge in pair:
SpecialEdges.add(edge)
for vertex in face:
incidentEdges={edge for edge in SpecialEdges if vertex in edge}
newEdge=set()
for edge in incidentEdges:
for v in edge:
if v==vertex:
continue
else:
newEdge.add(v)
middleFace.add(v)
newEdges.add(frozenset(newEdge))
newEdge.add(vertex)
newFaces.add(frozenset(newEdge))
newFaces.add(frozenset(middleFace))
Vertices = Vertices+newVertices
Edges.clear()
Edges.update(newEdges)
Faces.clear()
Faces.update(newFaces)
### Plotting ###
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.set(xlim=(-1,1), ylim=(-1,1), zlim=(-1,1))
col =[ [ Vertices[i] for i in f] for f in Faces]
n_vertices_per_polygon=[len(x) for x in col]
print(f"Iteration {iterations}: Polygon with least number of vertices has {min(n_vertices_per_polygon)} vertices")
print("Vertices on polygons:", n_vertices_per_polygon)
col3d=Poly3DCollection(col,edgecolors='k',facecolors='w')
ax.add_collection3d(col3d)
plt.axis('off')
plt.show()