Up

ランダムドットパターンの運動と奥行き知覚(PyGame

 

平面上のランダムなドットパターンは、適切な運動を与えると奥行きのある立体に見える。例えば、図1に示されているランダムドットパターンは、リストのプログラムで与えられる運動により、円筒に貼りつけられたドットが運動しているように見える。

図1

 

リストのスクリプトファイルは、圧縮ファイルullman_files.zipとしているが、ダウンロード展開すれば自由に利用できる。図1の画面において、キーGを押せば、ドットパターンは運動するが、キーSを押すと停止する。停止したドットパターンは、平面上のランダムドットパターンに見えるが、キーGを押して、ドットパターンが運動を始めると、円筒に貼りつけられたドットパーンの運動に見える。

リスト1のスクリプトでは、モジュールPyGameを利用しているが、PyGameのインストールはこのウェブサイトで説明しているように簡単である。

ランダムドットパターンは、次のコードで設定している。

 

n = 200

x_polar = np.random.rand(n) * np.pi * 2         #     横軸角度座標

y = np.random.rand(n) * 260                     #     縦軸座標

 

縦軸の座標値は、一様乱数で与えているが、横軸は角度座標で与え、次のコードで横軸座標に変換している。

 

    x = np.cos(x_polar) * 100                    #    角度座標ー>X軸座標

 

ランダムドット(x[i], y[j])は、次のコードで、中央黒画面内にプロットしている。

 

    for i in range(n):

        pg.draw.circle(screen, (0,255,255), (400 + x[i], 70 + y[i]), 4)

 

画面の更新後、角度座標値の更新を次のコードで行っている。すなわち、値をx_stepだけ増やした後、2πで割った余りを求めることにより、更新値が0から2πの範囲に収まるようにしている。

 

    x_polar = (x_polar + x_step) % (np.pi * 2)    #    角度座標の更新

 

角度座標の更新後、次のコードでキー押しのチェックを行い、対応する処理を行っている。キー押しのチェック後、10msのウェイトを置いて処理速度の調整を行っている。

 

    for e in pg.event.get():

        if e.type == pg.KEYDOWN:

            if e.key == pg.K_q:      #    「キーJ」が押されたか?

                ck0 = False          #     While文の終了

            elif e.key == pg.K_s:

                x_step = 0           #     角度座標の更新量を0にする

            elif e.key == pg.K_g:

                x_step = 0.015       #     角度座標の更新量を0.015にする

    pg.time.wait(10)

 

 

 

リスト1 ドットパターンの運動(Ullman.py

 

import numpy as np

import pygame as pg

from pygame import font

 

pg.init()

screen = pg.display.set_mode(size=(800, 500))       #   画面の大きさ

pg.display.set_caption('Ullman')

screen.fill((255, 255, 255))                        #   白背景

pg.draw.rect(screen, (0,0,0), (200, 50, 400, 300))  #   黒画面

#

#            表示文字列の作成と表示

#

msg = 'G: Go,    S: Stop,    Q: Quit'

my_font = pg.font.SysFont(None, 48)

img_msg = my_font.render(msg, True, (0, 0, 200), (255, 255, 255))

rect_msg = img_msg.get_rect()

screen.blit(img_msg, (400 - rect_msg.width//2, 500 - rect_msg.height*2))

 

pg.display.flip()           #   描画の表示

 

n = 200

x_polar = np.random.rand(n) * np.pi * 2         #     横軸角度座標

y = np.random.rand(n) * 260                     #     縦軸座標

x_step = 0.015                                  #     角度座標値のステップ値

ck0 = True

while ck0:

    pg.draw.rect(screen, (0,0,0), (200, 50, 400, 300))    #    中央黒画面

 

    screen.blit(img_msg, (400 - rect_msg.width//2,        #    文字列表示

                          500 - rect_msg.height*2))

    #

    #              ドットの描画

    #

    x = np.cos(x_polar) * 100                    #    角度座標ー>X軸座標

    for i in range(n):

        pg.draw.circle(screen, (0,255,255), (400 + x[i], 70 + y[i]), 4)

 

    pg.display.flip()                             #    描画画像の表示

 

    x_polar = (x_polar + x_step) % (np.pi * 2)    #    角度座標の更新

    #

    #        キーイベントのチェック

    #

    for e in pg.event.get():

        if e.type == pg.KEYDOWN:

            if e.key == pg.K_q:      #    「キーJ」が押されたか?

                ck0 = False          #     While文の終了

            elif e.key == pg.K_s:

                x_step = 0           #     角度座標の更新量を0にする

            elif e.key == pg.K_g:

                x_step = 0.015       #     角度座標の更新量を0.015にする

    pg.time.wait(10)

 

pg.quit()

 

 

 

Home