2013-07-24 30 views
0

我正在使用vtk库构建地震动态地图。Python - 如何追踪(添加/删除)多个迭代中的大量类实例?

我已经做了一个静态的(见这里:https://github.com/yacobuk/QuakeCloud和这里:http://www.youtube.com/watch?v=4HVdTcI_ozI),所以我知道基本思想的作品,但现在我想尝试并随时间显示地震。

我有一些代码示例,告诉我如何更新框架,以及如何添加/删除对象,但我坚持搞清楚如何启动一个实例,跟踪它几个时期,然后删除它。

基本的添加/删除的代码看起来是这样的:

for point_and_mag in pm.points_mag: 
     time.sleep(0.5) 
     mag = point_and_mag[1] 
     point = point_and_mag[0] 
     if mag > 2: 
      pointCloud = VtkPointCloud(pm) 
      pointCloud.addPoint(point, math.log(mag)*10) 
      renderer.AddActor(pointCloud.vtkActor) 
      renderer.ResetCamera() 
      renderWindow.Render() 
      time.sleep(0.3) 
      renderer.RemoveActor(pointCloud.vtkActor) 
      renderer.ResetCamera() 
      renderWindow.Render() 

但当然,这仅允许一个对象在时间(通过renderer.AddActor(pointCloud.vtkActor)pointCloud.vtkActor一个实例等待一段时间,然后用renderer.RemoveActor(pointCloud.vtkActor)

删除它

如何添加一些演员(我将使用10分钟的时间间隔,并且当时有多达5次地震),用计数器标记它,在每次循环迭代时增加计数器,并且当它达到5次迭代时,删除演员?

有一些更多的上下文这个问题在这里:Python/vtk - set each point size individually in a vtkPolyData object?

回答

1

的可能(未经测试)解决方案可能是:

from collections import deque 

# The number 5 indicates for how many iterations the actors should be rendered. 
rendered_actors = deque([None] * 5, maxlen=5) 

for point_and_mag in pm.points_mag: 
    if rendered_actors[-1] is not None: 
     renderer.removeActor(rendered_actors[-1]) 
     renderer.ResetCamera() 
     renderWindow.Render() 

    time.sleep(0.5) 
    mag = point_and_mag[1] 
    point = point_and_mag[0] 
    if mag > 2: 
     pointCloud = VtkPointCloud(pm) 
     pointCloud.addPoint(point, math.log(mag)*10) 
     rendered_actors.appendleft(pointcloud.vtkActor) 
     renderer.AddActor(pointCloud.vtkActor) 
     renderer.ResetCamera() 
     renderWindow.Render() 
    else: 
     rendered_actors.appendleft(None) 

此代码创建一个deque(这是一个双向链表)长度为5.演员插入在该双排扣的左侧,在每次迭代时插入最右侧的值,如果它是“演员”,则将其从场景中移除并且场景重新呈现。

请注意,我没有vtk,所以我无法测试此代码。


小样式注意:这是真的unpythonic代码风格:

for point_and_mag in pm.points_mag: 
    mag = point_and_mag[1] 
    point = point_and_mag[0] 

使用元组拆包:

for point, mag in pm.points_mag: 
    # ... 
    if mag > 2: 
     # ... 
+0

啊,OK。我认为我正朝着正确的方向前进,计划是将一个时间段中的每个点添加到单个演员,然后我只有5个演员跟踪该集。我没有意识到这个想法,我可以看到使用滚动缓冲区/队列来有效地窗口实时数据的价值。谢谢,这很好。我还看到了双开箱,并认为它是笨拙的,我打算单独解开它,但你的方法是waaaay更清洁 - 谢谢你的提示!赞赏。 –

+0

这是非常接近的,但是当它碰到'不是None'子句--' AttributeError:removeActor'时会抛出一个错误。我查看了'rendered_actors [-1]'对象,它看起来是相同的对象(数据在'pointCloud.vtkActor' =='rendered_actors [-1]'中。 –

+0

纠错:'renderer.RemoveActor(rendered_actors [-1])'。就像一个魅力!太棒了,谢谢! –