Как обновить ipyvolume формы сразу без промежуточных представлений - PullRequest
0 голосов
/ 05 февраля 2019

Учитывая блокнот jupyter со сценой, отображаемой с помощью ipyvolume, и ползунками, которые обновляют черты x, y, z фигуры на сцене, 3D-рендерер имеет анимацию изменения сцены, которая рисует промежуточные виды фигуры, которые не соответствуютпросмотры на слайдере.

Как заставить ipyvolume отображать только последнюю сцену при обновлении без анимации смены сцены?

Например, запустите следующую команду в блокноте jupyter и перетащите theta/ phi:

import numpy as np
from numpy import pi, sin, cos, radians
import ipyvolume as ipv
import ipywidgets as widgets

def transform_xyz(theta, phi, x, y, z):
    x, y, z = [np.asarray(v) for v in (x, y, z)]
    shape = x.shape
    points = np.matrix([x.flatten(), y.flatten(), z.flatten()])
    Ry_theta = [[+cos(theta), 0, +sin(theta)],
                [0, 1, 0],
                [-sin(theta), 0, +cos(theta)]]
    Rz_phi = [[+cos(phi), -sin(phi), 0],
              [+sin(phi), +cos(phi), 0],
              [0, 0, 1]]
    points = np.matrix(Rz_phi)*np.matrix(Ry_theta)*points
    x, y, z = [np.array(v).reshape(shape) for v in points]
    return x, y, z

def torus(R=100, r=10, Rsteps=100, rsteps=100):
    u = np.linspace(0, 2*pi, rsteps) # tube
    v = np.linspace(0, 2*pi, Rsteps) # ring
    U, V = np.meshgrid(u, v)
    x = (R + r*cos(U))*cos(V)
    y = (R + r*cos(U))*sin(V)
    z = r*sin(U)
    return x, y, z

class Scene:
    def __init__(self, view=(0, 0, 0), hkl=(1,1,1)):
        self.view = view
        self.figure = ipv.figure()
        R = 100.
        r = R/30.
        ipv.xlim(-R, R)
        ipv.ylim(-R, R)
        ipv.zlim(-R, R)
        ipv.style.box_off()
        self.torus_xyz = torus(R=R, r=R/10)
        self.torus = ipv.plot_surface(*self.torus_xyz)
        ipv.show()
        self.ui = widgets.interact(self.update, theta=(-90.,90.), phi=(-180., 180.))
        #self.ui.widget.children[0].continuous_update = False
        #self.ui.widget.children[1].continuous_update = False

    def update(self, theta, phi):
        print("update with", theta, phi)
        x, y, z = transform_xyz(radians(theta), radians(phi), *self.torus_xyz)
        self.torus.x = x.flatten()
        self.torus.y = y.flatten()
        self.torus.z = z.flatten()

scene = Scene()

enter image description here

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Вы также можете попытаться установить для animation_exponent значение 0. Ipyvolume использует линейную интерполяцию для обновления фигуры при изменении данных, экспонента задает скорость этой интерполяции.Нулевой показатель должен привести к мгновенному обновлению.

self.figure = ipv.figure(animation=0.,animation_exponent=0.)
0 голосов
/ 06 февраля 2019

Установка времени анимации для перехода к нулю при создании фигуры в основном решает проблему:

...
self.figure = ipv.figure(animation=0.)
...

Фигура все еще немного дрожит, когда ползунки пользовательского интерфейса настроены на постоянное обновление, возможно потому, что естьслучайный переходный кадр, который рисуется.


Другой возможный источник дрожания - это то, что traitlets не отправляет обновления x, y, z синхронно, и, возможно, иногда он показывает обновления с x и y дляновый вид при сохранении z из старого вида.

...