リサジュー曲線による スクリーンセーバーの作成 - Ryukoku...

18
T000132 Visual C++ 、プ ラミ ・イ ラフ Open GL x, y z パラメ パラメ プル

Transcript of リサジュー曲線による スクリーンセーバーの作成 - Ryukoku...

  • リサジュー曲線によるスクリーンセーバーの作成

    理工学部 数理情報学科T000132 結城 洋志指導教員 池田 勉

    概要

    卒業研究の課題であるスクリーンセーバーの作成は、Visual C++と、プログラミング・インターフェースとして、グラフィック処理に秀でたOpen GLを使って行う。ユークリッド幾何学に始まる曲線の歴史で、19世紀に発見されたリサジュー曲線に焦点を当てて研究を進めている。本来リサジュー曲線とは平面図形のことであるが、本研究では x, y成分に z成分を加えた空間図形で考えている。その理由は、人間の脳は物体を3次元でとらえる空間把握能力を持っていることにある。それなら、より「凄い」と思わせるには3次元が効果的だと考えたからである。何より、3次元の方が綺麗に見えるというのが大きな要因である。まずは平面図形のリサジュー曲線の変化の性質や特徴について調べ理解を深める。その上で空間図形のリサジュー曲線がパラメータによってどのような変化をするのかについて調べ理解を深めていく。これはスクリーンセーバーにより適した曲線を選ぶために最も重要な仕事になる。文献やインターネットで調べようにも3次元リサジューに関する記述はあまりに少ないため、全てが自分で1から発見していく作業になった。これが充実感を与えてくれる楽しい作業になった。作品を作るにあたって大切にしたかったことは、何よりリサジュー曲線の美しさを生かすことであった。時に線対称に、時に点対称にと、必ず対象な図形を生み出すリサジュー曲線は人を惹きつける魅力を確かに持っている。それを生かしたかったのだ。出来上がった作品は、いくつか選らんだリサジュー曲線を線分で描き、等間隔で球体を飛ばすというものである。リサジュー曲線を表現するには1本の線分で表すのが一番理解しやすい。しかし、線分で書いたのでは立体的にとらえにくく3次元で得られる美しさが損なわれる。そこで線分の上を球体が動くという手段をとった。何故に球体だったのかは、どの角度から見ても同じ姿を見せる球体がどんな図形よりも綺麗だと感じたからである。リサジュー曲線を形作るパラメータもシンプルで見やすく理解しやすいものを選んだ。こだわりを持って研究をすすめたことに非常に満足している。

  • 2005年度特別研究

    リサジュー曲線によるスクリーンセーバーの作成

    龍谷大学理工学部数理情報学科T000132  結城 洋志指導教員  池田 勉

  • 目 次

    1 はじめに 11.1 研究の流れ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 スクリーンセーバー . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 曲線の歴史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

    2 リサジュー曲線(Lissajous’ curves) 32.1 リサジュー曲線 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 2次元リサジュー曲線 . . . . . . . . . . . . . . . . . . . . . . . . . 32.3 3次元リサジュー曲線 . . . . . . . . . . . . . . . . . . . . . . . . . 5

    3 プログラム 93.1 Open GL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

    3.2 アニメーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.3 プログラム内容 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

    4 おわりに 15

  • 1 はじめに

    1.1 研究の流れ

    研究を開始するにあたって最初にすることは、テーマを決めることではなくVisualC++, Open GLに慣れることであった。Open GLは単純な命令で綺麗なグラフィックを展開してくれる。しかし、色々なことをしようと考えたらかなりの量の知識とプログラムが必要になってくる。そこで、テーマを決めた後に作品製作を進めながら必要な知識を得ていこうと考えた。当初、卒業研究のスクリーンセーバーを作成するにあたって思いついたテーマは

    「惑星の運動」であった。実際に作ってみると、太陽の周りを地球等の惑星が回り、惑星の周りを衛星が回るといった太陽系が出来てきた。しかし、惑星に色を着けたり、視点を変えてみたところで、ただ同じ動きを繰り返す惑星の運動に面白みを感じることはなかった。行き詰まったところで、池田先生の勧めもあり、研究テーマをリサジュー曲線に変更した。値を変えることで姿を変えるリサジュー曲線は面白かった。さらに、それを3次元で描くと、見たこともないような美しい姿を見せてくれた。その魅力を十分に伝えられるような作品を作りたいと研究を進めていった。

    1.2 スクリーンセーバー

    スクリーンセーバーとは、ユーザがマシンを使用していない間に画面を黒くしたり、常に動きを与えたりするアニメーションソフトウェアのことである。これは、表示されている文字や画像が画面に焼きつくのを防ぐためのもので、最近のOSには標準装備されている。焼きつきが起こるのはブラウン管を利用したディスプレイで、液晶ディスプレイでは基本的に起きないとされている。そのため、焼きつき防止の意味は薄れている。しかし、スクリーンセーバーの終了時にパスワードを要求できる機能がついている OS(あるいはアプリケーションソフト) が多くなり、ユーザが席を離れる際、マシンを他人に利用されるのを防止する機能として利用されることが多くなっている。そして、娯楽好きの日本人らしくただアニメーションを楽しむために使用するユーザも多いようである。

    1.3 曲線の歴史

    幾何学の源流はユークリッドによる原論であるとされており、原論には、数々の定義,公理,公準,証明が書かれてあるのみである。内容は、平面幾何、数論、無理数論、立体幾何から構成されている。ユークリッド幾何学は直線と円の幾何学であったが、円錐曲線と呼ばれる放物線,楕円,双曲線はアポロニウスによって研究され、17前半に座標幾何がデカルト

  • およびフェルマーによって創始され、円錐曲線は2次曲線として理解されるようになった。その後,いろいろな曲線が発見され,研究の対象になる。

    1638年にデカルトによって発見された葉線(x3 + y3 − 3axy = 0)、1650年にE.パスカルによって発見されたリマソン曲線(r = b + 2a cos θ)、リマソン曲線のb = 2aの時に現れるカージオイド曲線(円に外接する円上の点の軌跡)、ネイルの放物線(y3 − ax2 = 0)、スルーズの真珠形曲線(yn − k(a− x)pxm = 0)、2点からの距離の積が一定値 c2 に等しい点の軌跡として描いたカッシーニの卵型曲線((x2 + y2)2 − 2a2(x2 − y2) + a4 − c4 = 0)。18世紀に入ってからは、グランディによって研究されたバラ曲線(r = a sin(kθ))、オイラーによって研究された3尖点曲線((x2 + y2 + 12ax + 9a2)2− 4a(2x + 3a)3 = 0)、ベルヌーイによって研究された4尖点曲線1((x2 + y2 − 1)3 + 27x2y2 = 0)。そして、1815年にボウディッチによって研究され、1850年にリサジューが考察した三角関数を用いてパラメータ表示されたリサジュー曲線が発見された。そして現在でも平面曲線だけに留まらず、空間曲線などの分野に渡っても研究が進められている。

    1アステロイド曲線、星型曲線とも呼ばれる。

  • 2 リサジュー曲線(Lissajous’ curves)

    2.1 リサジュー曲線

    前述の通り、リサジュー曲線は 1855年にフランスの物理学者ジュール・アントワーヌ・リサジュー(J.A.Lissajous)によって考案されたもので、彼の名にちなんで呼び名が付いた。日本人には「リサジュー」ではなく「リサージュ」と呼ぶ方が好まれる傾向にあるため、そう呼ばれることが多々ある。また、1815年にナタニエル・ボウディッチ(Nathaniel Bowditch)が先行的な研究を行っていた為、ボウディッチ曲線と呼ばれることもある。このレポートでは、発音的に近いと思われる「リサジュー」で表記している。リサジュー曲線とは「直行した2つの単振動を合成した平面図形」のことであり、周波数の測定に用いられることが多い。広く知られているものにはオシロスコープがある。オシロスコープを X-Y入力モードに設定し、各入力に定義式を入力するとリサジュー波形を観測することができる。周波数の測定を行う時は、基準波を横軸に、被測定波を縦軸に入力すると、上下に描かれた凸の数と、左右に描かれた凸の数が、基準波と被測定波の周波数比となって現れる。これを基に周波数を測定することが出来る。この周波数測定法を、比較法という。また、お互いの信号の位相が安定しないと曲線は常に変化を繰り返す為、複数のモーターの位相合わせ、ICなどの信号の同期合わせなどにも利用されている。

    2.2 2次元リサジュー曲線

    定義式は、{

    x = A sin(ω1t + α)

    y = B sin(ω2t + β)

    で、表される。この時、A,Bは振り幅、ω1 ,ω2 は振動数、α ,β は位相のことである。今回は x,y共に sin で記述しているが、必ずしも sin である必要はない。cos でも同様に単振動になるからである。

  • 位相差 [α− β]

    0π6

    π4

    π3

    π2

    2π3

    3π4

    5π6

    π

    周波数比[ω2ω1

    ]

    11

    21

    31

    32

    65

    周波数比と位相差の対応表

    表のように描き出される図は、上下にω1個、左右にω2個の凸を持ち、(2ω1−1)(ω2−1)+ (ω1− 1) 個の交点を持つ。位相差によっては、閉曲線がぺしゃんこになって線分になっているものもある。この場合の交点は (ω1−1)(ω2−1)

    2個になる。リサジュー

    曲線は、周波数比が有理数の時は閉曲線になるが、周波数比が無理数の時は閉曲線にはならい。

    y

    x

    y

    x

    2π 4π 6π 8π 10π 12π

    sin(3t)

    sin(2t)

    0

    上図の例のように、周波数比が有理数であれば必ず公倍数が存在する。そしてグラフは、(振動数の最小公倍数)× 2π · · · (1) 例でいえば 0 ≤ t ≤ 12π の範囲が繰り返し表示されるグラフになる。これは、2つのグラフを合成した時に (1) の範囲で閉曲線となり重なり合うグラフとなるということである。つまり、振動数に公倍数がない(=周波数比が無理数である)時、閉曲線になることは決してないのである。また、周波数比を限りなく∞に近づけていくと下図のように A×Bの長方形に近似していく。また、周波数比が無理数の時は閉曲線にならないので少しずつラインにずれが生じ、長方形を黒く染める。

  • この例は ω1 : ω2 = 30 : 1の時である。

    2.3 3次元リサジュー曲線

    3次元のリサジュー曲線を描くにあたって与えたパラメータは

    x = A sin(ω1t + α)

    y = B sin(ω2t + β)

    z = C sin(ω3t + γ)

    である。3次元リサージュに於いても同様で、ω1ω2

    ,ω2ω3

    ,ω3ω1の全ての周波数比が有理

    数でないと閉曲線にはならない。

  • この図は実際にスクリーンセーバーに使用したリサジュー曲線で、左上が ω1 :ω2 : ω3 = 1 : 2 : 3の場合、右上が ω1 : ω2 : ω3 = 1 : 2 : 4の場合、左下がω1 : ω2 : ω3 = 2 : 3 : 4の場合である。これをそれぞれ x−y平面、y− z平面、x− z平面を取り出して見てみると、2次元リサージュ曲線と同じ図形が確認できる。

  • この図は ω1 ω2 ω3それぞれの周波数比を限りなく1に近づけた時に現れる図形で、左が位相差なしの時、右は x− yの位相差はなしで y− zの位相差が π/2の時である。途中経過は下図のようになっている。

    図からわかるように中は空洞になっている。

  • また、周波数比を∞に近くしていくと下図のようになることから、周波数比が無理数の時は A×B × Cの立方体になると考えられる。

    この例は ω1 : ω2 : ω3 = 1099 : 980 : 97の時である。与えた数が中途半端な印象を受けるかもしれないが、公倍数を少しでも大きい数字にするためにこうしている。

  • 3 プログラム

    3.1 Open GL

    Open GL は Silicon Graphics Incorporated(SGI)社のハードウェア用に開発された GLというインターフェースに由来し、単純かつ強力なインターフェースであったため、様々なグラフィックスハードウェアで使用可能なOpen GL の基礎を形成したのである。Open GLとは、グラフィックスハードウェアにアクセスするプログラムを書けるようにしてくれるアプリケーションプログラマインタフェース(API)のことである。今の世の中では、コンピュータを使うとなるとほとんどの処理について回るコンピュータグラフィックスは重要な役割を占めている。Webサイト、ゲーム、業務用ソフトと様々な面で必須になってくる。ハードウェアとソフトウェア、両方の面でより高速,高度化されたことにより、使われるグラフィカルアプリケーションも高速,高度化されてきている。アプリケーション開発の際には、標準ソフトウェアインターフェースを頼りに開発,構築される。こういったインターフェースがあるために、開発者は多くのアプリケーションに共通する標準的な関数のコードを書かずに済み、アプリケーションがハードウェアの詳細から遮断,保護される。そのため、より迅速に開発でき可搬性が増すのである。

    3.2 アニメーション

    アニメーション(動画)は静止絵を何枚も用意し、素早く順番に表示していくというものである。パラパラ漫画というものがあるが、誰しもが一度は見たことや作ったことがあるだろう。原理はアレと全く同じである。現在の映写機は毎秒48フレームという速さで映写している。コンピュータ・グラフィックスの画面においては毎秒60~76回も描き直していて、中には再描画が約120回というものもある。当然、描き直す回数が増えれば増えるほど滑らかに見えるので、より回数が多い方が優れているといえる。しかし、120回を超えると、人間の肉眼で追随できる限界を超えてしまうため無意味となる。動画の映写が可能になるのは、予め用意されている完成されたフレームを映写しているからである。しかし、コンピュータ・グラフィックのアニメーションではフレームを描画する時間が必要になってくる。画面表示,描画,画面クリアとを合わせた時間を十分にとれるなら問題はないが、それに必要な時間は1/24秒を要すると言われている。毎秒24回の描画では当然ながら滑らかなアニメーションにはならないだろう。かといって、回数を増やしたところで描画する時間が足りなくなり、描画しきる前にクリアされるという状況がおこり、部分的に描画された未完成のフレームが表示されるといった現象がおこる。

  • そこで使われるのがダブル・バッファ処理である。Open GLが使用可能な動作環境には、2つの完全なカラー・バッファを供給する機能が備わっている。これがダブル・バッファ処理機能であり、表バッファと裏バッファがあり、表バッファが表示されている間に裏バッファに描き込む。そうして、裏バッファに描き込みが完了すると表と裏を交換するのである。表示時間と描画,画面クリア時間が同時にとれることになり、完成した1枚絵を順に映写する時とほとんど相違ない認識が得られる。ダブル・バッファ処理を使用すると、各フレームが完成した時だけ表示されるため、部分的に描画されたフレームが表示されることはなくなる。

    3.3 プログラム内容

    リサジュー曲線を描くためのプログラムは

    vx[j] = amp1 * sin(freq1 * time + epoch1);

    vy[j] = amp2 * sin(freq2 * time + epoch2);

    vz[j] = amp3 * sin(freq3 * time + epoch3);

    (ampは振り幅、freqは振動数、epochは位相の変数である)のように、x,y,z座標をそれぞれの配列に格納し、

    glBegin(GL_LINE_STRIP);

    for(j = time - 1000; j < time; j++)

    if(j>=0)

    glVertex3f(vx[j], vy[j], vz[j]); ・・・・(1)glEnd();

    とプログラムして描画する。(1)は点を定め、順に線分でつないでいくという線セグメントである。for文の下りは、別関数で timeを 1ずつ加算し、timeまで jを加算していくというものである。初期値が j=time-1000となっているのは、描画する配列を新しい 1000までのものにする為である。

    リサジュー曲線を描くだけではスクリーンセーバーとしては面白くないので、スクリーンセーバーらしくみせるための工夫をしてみた。

  • ○球体を飛ばすただ単に線を描くだけでは面白くないので、球体を飛ばしてその軌跡を描いているというようにしている。プログラムは

    glPushMatrix();

    glTranslatef (amp1 * sin(freq1 * i + epoch1)//

    , amp2 * sin(freq2 * i + epoch2)//

    , amp3 * sin(freq3 * i + epoch3)); ・・・・(2)glutSolidSphere(0.1, 20, 16); ・・・・(3)glPopMatrix();

    である。これは (3)というOpen GLに用意されている3次元オブジェクトを描画するためのルーチンで、括弧内は順に半径、経線の数、緯線の数を設定している。また、表面を滑らかに見せるために glShadeModel(GL_SMOOTH)でシェーディング処理を施している。しかし、これらのモデルは、ワールド座標系の原点を中心として描画されるので、リサジュー曲線の軌跡上を飛ばすための命令が必要である。それが、(2)である。これは、今ある行列を指定した x,y,zの値分オブジェクトを移動させる行列と乗算するルーチンである。

    ○球体を数珠繋ぎにするこれは、線分だけの表示では平面としてしか捉えられず立体感に欠けていたため、少しでも奥行きを表現できればと考えてプログラムに追加した。

    for(h = 10.0; h

  • ○球体に光を当てる

    GLfloat mat_specular[] = { 0.0, 0.0, 0.0, 1.0 };

    GLfloat mat_shininess[] = { 50.0 };

    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); ・・・・(4)glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); ・・・・(5)glLightfv(GL_LIGHT0, GL_POSITION, light_position); ・・・・(6)

    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

    glEnable(GL_DEPTH_TEST);

    mat_spexularは光の鏡面RGBA輝度の設定値、mat_shininessは光の鏡面係数の設定値、light_positionは光源の位置の設定値をそれぞれ設定している。(4),(5)は照光計算で使用する材質特性の指定をしていて、括弧内は順に材質を適用するオブジェクトの面、設定される材質の識別、特性に必要な値を設定している。このプログラムの場合、材質を適用する面は FRONT、GL_SPECULARは鏡面カラー、GL_SHININESSは鏡面係数をそれぞれ設定している。(6)は光の特性すべての指定に使われ、括弧内は順に光の作成、光の特性の設定、特性に必要な値を設定している。このプログラムの場合、LIGHT0の作成、GL_POSITIONで光の位置を設定している。glEnable()はスイッチだと考えるとよい。glEnable(GL_LIGHTING)で照光を有効化し、glDisable(GL_LIGHTING)で無効化する。次に、どの照光を有効化するかの指定をしなければならない。今回は光源は1つなので LIGHT_0のみの有効化でよい。

    ○周波数比を変更するこのプログラムの時間経過は変数 timeで表されている。timeが一定置に達するとリサジュー曲線の振動数を変えて図形が変化するようにした。

    if(time >5000)

    {

    time = 0;

    k = k + 1;

    switch (k % 4){

    case 0 :

    freq1 = 0.01;

    freq2 = 0.02;

  • freq3 = 0.03;

    epoch2 = 0.0;

    epoch3 = 0.0;

    break;

    case 1 :

    freq1 = 0.009;

    freq2 = 0.018;

    freq3 = 0.036;

    break;

    case 2 :

    freq1 = 0.007;

    freq2 = 0.021;

    freq3 = 0.035;

    epoch2 = PAI / 2.0;

    epoch3 = PAI / 2.0;

    break;

    case 3 :

    freq1 = 0.004;

    freq2 = 0.012;

    freq3 = 0.036;

    break;

    }

    }

    プログラムは以上の通りで、timeが 2000を超えると時間を 0に戻すようにしている。また、戻した際に kの値によって振動数の値が4パターンを順に選ばれるようにしている。プログラムを見てわかるように、値を変化させているのは設定されている9つのパラメータ (amp123,freq123,epoch123)の中で5つ (freq123,epoch12)だけである。これには訳がある。あくまで作品のテーマは綺麗に見せることである。リサジュー曲線は四角い箱の中に内接して入っていると考えられる。では、箱を見る時に綺麗に見えるのはどういった時か?それは立方体の時であると考える。リサジュー曲線において箱とは振り幅のことである。つまり、振幅比を A:B:C=1:1:1にし値 amp123を固定することによって均整の取れた形を表現できると考えたからである。振幅比を A:B:C=1:1:1にしたまま値を変えることで大きさを変え迫力を出すといったことも考えた。しかし、これは視点位置を変えることで対応した。位

  • 相差が2つしか値を変化させていないのかはリサジュー曲線の性質によるものである。リサジュー曲線は各成分を比べた時の位相差が重要なのであって、各成分ごとの位相がいくらであろうと関係はない。そのため、基点とした freq1は固定しているのである。

  • 4 おわりに本研究の作品テーマを決めてから1つだけこだわりを持って製作にあたった。そ

    れは「リサジュー曲線の美しさを損なわないすること、より美しさを強調できるようにする」ことである。本研究で初めて、プログラミングで全くの0から何か1つのものを創るという作業を経験した。基本となるプログラムはすぐにできた。そこからスクリーンセーバーとして、より綺麗に見せる方法などを模索し作品としての純度を上げていく。リサジューの曲線と球体の曲線と、全て曲線で仕上げることで美しさをより強調する。その他にも、リサジュー曲線を美しく見せることだけにこだわって工夫をした。たった1つのこだわりのために出来た作品は完成度とは別の満足感をくれた。そして、作品製作に打ち込んだ時間は充実した時間であった。

    謝辞本論文を作成するにあたって、色々御指導くださった数理 池田教授に深く御礼申し上げます。また論文作成に当たって、いろいろ相談にのってくれた 5階研究室の皆様に感謝します。

    参考文献

    Open GLプログラミングガイド 第2版  著:Mason Woo, Jackie Neider, TomDavis

    Open GL 入門  著:Edoward Angelhttp://www.rimath.saitama-u.ac.jp/lab.jp/fsakai/alggeom.html  酒井文雄のページ -微分幾何-http://ja.wikipedia.org/wiki/  ウィギペディア