Python 脚本在 2 次迭代后失败

问题描述 投票:0回答:1

我编写了一个脚本,它采用指定的八面体并对其进行细化。对于上下文,我有

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()
python matplotlib iteration visualization
1个回答
0
投票

所以我看了一下,我相信你的循环中的某些东西可能正在创建顶点数量较少的多边形(老实说,没有看得太深以确定它发生在哪里/如何发生)。

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

© www.soinside.com 2019 - 2024. All rights reserved.