Interactive 3D brownian motion with Vispy


In [1]:
import numpy as np

from vispy import geometry
from vispy import scene
from vispy import app

import vispy
import vispy.app.qt as vispyqt

qtapp = vispy.app.use_app('pyqt4')

QtCore = qtapp.backend_module.QtCore
QtGui = qtapp.backend_module.QtGui

In [4]:
class MainWindow(QtGui.QWidget):

    def __init__(self):
        QtGui.QWidget.__init__(self, None)
        self.setMinimumSize(800, 600)
        self.setWindowTitle('Test')
        
        self.canvas = vispyqt.QtSceneCanvas(keys='interactive', app=qtapp, parent=self, bgcolor='white')
        self.canvas.measure_fps(1, self.show_fps)
        
        self.view = self.canvas.central_widget.add_view()
        self.view.camera = scene.cameras.TurntableCamera()

        self.spheres = []
        self.colors = ['red', 'red', 'green', 'green']
        
        # Generate random motion for each spheres
        tmax = 100000
        self.pos = np.random.randint(-1, 2, size=(tmax, len(self.colors), 3))
        
        # Create spheres
        for i, color in enumerate(self.colors):
            position = self.pos[0, i]
            sphere = self.create_sphere(position, color)
            self.spheres.append(sphere)
            self.view.add(sphere)
        
        # Config slider widget according to random motions
        self.slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
        self.slider.valueChanged.connect(self.move)
        self.slider.setRange(0, tmax)
        self.slider.setSingleStep(1)
        
        # Layout
        vlayout = QtGui.QVBoxLayout(self)
        self.setLayout(vlayout)
        vlayout.addWidget(self.canvas.native, 0)
        vlayout.addWidget(self.slider, 1)
        
        # FPS - Does not work :-(
        self.text = scene.visuals.Text('fsdfsdfsdfsdfsd', font_size=200, color='black',
                                       pos=[10, 10], anchor_x='center', anchor_y='baseline')
        self.canvas.draw_visual(self.text)

    def create_sphere(self, position, color):       
        mdata = geometry.create_sphere(64, 64,  radius=0.5)
        sphere = scene.visuals.Mesh(meshdata=mdata, shading='flat', color=color)
        
        t = scene.transforms.AffineTransform()
        t.translate(position)
        sphere.transform = t
        
        return sphere
        
    def move(self, t):
        for i, sphere in enumerate(self.spheres):
            sphere.transform.translate(self.pos[t - 1, i] / 5)
            
    def show_fps(self, fps):
        str_fps = "FPS : {}".format(fps)
        print(str_fps)
        self.text.text = str_fps
        self.canvas.update()
            
qtapp.create()
win = MainWindow()
win.show()
qtapp.run()


FPS : 3.8805687480035926
Out[4]:
0