5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Bokehを用いた回転行列演算可視化(手動でスライダー)

Last updated at Posted at 2017-11-23

本日は

先日の記事

の応用という事で, 回転行列の角度をスライダーで変更させるコードを書いてみましょう.

# 実装例

rotmatslider.py
import numpy as np
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Slider
from bokeh.layouts import column, widgetbox, gridplot
from bokeh.io import curdoc


def rot_mat(degree):
    theta = np.deg2rad(degree)
    mat = np.array([[np.cos(theta), -np.sin(theta)],
                    [np.sin(theta), np.cos(theta)]])
    return mat


class RotationViewer(object):

    def __init__(self):
        xs = np.linspace(-np.pi, np.pi, 11)
        ys = xs
        Xs, Ys = np.meshgrid(xs, ys)
        self.Xs, self.Ys = Xs.flatten(), Ys.flatten()
        initdegree = 0
        mat = rot_mat(initdegree)
        transXs, transYs = mat @ np.array([self.Xs, self.Ys])

        TOOLS = "pan,lasso_select,save,reset"

        self.source = ColumnDataSource(data=dict(Xs=self.Xs, Ys=self.Ys,
                                                 transXs=transXs,
                                                 transYs=transYs))

        self.fig = figure(tools=TOOLS, title="target",
                          x_range=(-np.pi*np.sqrt(2)-1, np.pi*np.sqrt(2)+1),
                          y_range=(-np.pi*np.sqrt(2)-1, np.pi*np.sqrt(2)+1))
        self.fig.circle('Xs', 'Ys', source=self.source)

        self.transfig = figure(tools=TOOLS, title="transformed",
                               x_range=self.fig.x_range, y_range=self.fig.y_range)
        self.transfig.circle('transXs', 'transYs', source=self.source, size=6)

        self.rot_param = Slider(title="degree", value=0,
                                start=0, end=360, step=1)
        self.rot_param.on_change('value', self.update_data)

        self.plot = column(self.rot_param, gridplot([[self.fig, self.transfig]]))

    def update_data(self, attr, old, new):
        mat = rot_mat(self.rot_param.value)
        transXs, transYs = mat @ np.array([self.Xs, self.Ys])
        self.source.data = dict(Xs=self.Xs, Ys=self.Ys,
                                transXs=transXs, transYs=transYs)
        self.transfig.title.text = "degree {}".format(self.rot_param.value)


def main():
    viewer = RotationViewer()
    document = curdoc()
    document.add_root(viewer.plot)

main()

実行例

$ bokeh serve --show rotmatslider.py

こんな感じです.

rotation_param.gif

気持ち悪いぐらいヌルヌル動きます.
お試しあれ.

追加

2x2 行列のパラメータ版も作ってみました.

2by2matanim.gif

こんな風に動いてたんですね.

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?