首页 > 解决方案 > 在图形工具的 GTK 循环中同步更新图形属性和拓扑的正确方法是什么?

问题描述

我正在尝试找到制作类似于动画的最简洁的方法,不同之处在于我需要同步更新图形拓扑和顶点的属性(它是生命游戏的图形模拟)。到目前为止,我一直在通过在第(i-1)次迭代中复制图形、基于原始图形计算更改并返回更新后的副本来简单地构建图形序列。

在我看来,这种方法的问题在于,在使用 时GraphWindow,就像在链接的示例中一样,我需要就地修改图形,而不是制作副本。所以我能做的最好的事情就是在每次调用update_state函数时在图上迭代两次。第一次迭代是计算新状态,第二次是分配它们。批处理分配适用于具有标量值的属性,但我无法设法为具有字符串值的属性执行此操作。

总结一下,我想在每次调用时update_state同步更新两个属性,一个标量属性,对应于顶点的状态,vp.state一个字符串值属性,对应于它的颜色,vp.color;

这是完整代码的摘录(update_state我命名的函数run_simulation

def run_simulation():

    global count, g
    
    to_remove = []
    alterations = []
    r = 0
    

    for v in g.get_vertices():
        if len(g.get_all_edges(v)) == 0:
            print(r)
            r+=1
            to_remove.append(v)
        else:
            Nv = g.get_all_neighbors(v)
            sum_nbstates = sum([g.vp.state[u] for u in Nv])
            nb_size = len(Nv)
            acoef = sum_nbstates / nb_size
    
            if g.vp.state[v] == 1:
                if 2 / nb_size <= acoef <= 3 / nb_size:
                    state = 1
                    color = "white"
                else:
                    state = 0
                    color = "black"

            elif g.vp.state[v] == 0:
                # if (acoef == 3/nb_size):
                if 2 / nb_size <= acoef <= 4 / nb_size:
                    state = 1
                    color = "white"
                else:
                    state = 0
                    color = "black"
            
            alterations.append([v, state, color])
            states.append(state)
            colors.append(color)

    ###some checks
    #print(vertices)
    diff = len(to_remove)
    if diff >= 1:
        print(f"diff {diff}, count {count}") #this eventually results in something ≠ 0, I still haven't find out why 
    ###
        
    for (v, new_state, new_color) in alterations:
        g.vp.state[v] = new_state
        g.vp.color[v] = new_color


    gt.sfdp_layout(
        g, pos=g.vp.pos, eweight=g.ep.weight, max_iter=1, init_step=0.01, K=0.5
         )

    g.remove_vertex(to_remove) 

    count += 1

    win.graph.regenerate_surface()
    win.graph.queue_draw()
    
    if OFFSCREEN:
        pixbuf = win.get_pixbuf()
        pixbuf.savev(r'./frames/graphol%06d.png' % count, 'png', [], [])

    if count >= max_count:
        sys.exit(0)

    return True

标签: pythongraphgtkgraph-tool

解决方案


推荐阅读