REALbasic かってに連載します(第5回)


 モニターのサイズの違う複数のマックを使っていると、画面サイズの情報がほしくなります。このためにScreen Functionがあり、「screen(0).width」や「screen(0).height」で現在使用しているモニターのサイズがわかります。
    第5回 -「微分方程式でサインカーブを描く」の後編 -

 前回はクラリスを使って微分方程式を解いてみましたが、今回はいよいよ、REALbasicを使ってのプログラミングです。メニューの作り方も合わせて説明します。 かなり、しつこい説明になりましたが、今回の説明で、REALbasicでのプログラミングがかなり自由に出来るようになるものと思います。
 サンプルに、バネによる単振動をマウスでシミュレーション出来るものを付け加えました。REALbasicでこんなことが簡単に出来ます。
 お楽しみください。
  1.  - 準備 (前回を参考に)-
     
    1. REALbasicのアイコンをダブルクリックすると、初期画面が出ます。 まずEditメニューのEditor Settingsを選びます。ここでDefault Control FontのFontを「System」に変更しておきます。これで表示に日本語が使えるようになります。
    2.  Untitledのウィンドウをアクティブにして、作業をはじめます。まずTitleの欄にはUntitleと表示されています。この「Untitle」を「微分方程式」に変更して下さい。
    3. HasBackColorにチェックを入れて、BackColorのプロパティをダブルクリックして好きな色を選んで下さい。

  2.  - StaticTextを配置する -

     ツールボックスから「A」の絵の付いたアイコン(StaticText)をドラッグして「微分方程式」のウィンドウに持ってきます。4隅に黒いマークの付いたハンドルが表示されます。StaticTextは文字や数字を表示するためのものです。「微分方程式」のウィンドウの上部に表示したいので。適当に配置して下さい。

  3.  - 終了ボタンを配置する -

    ツールボックスからボタン(「OK」の絵の付いたアイコン)をドラッグして「微分方程式」のウィンドウに持ってきます。このボタンに、終了のプログラムを書き込んで下さい。ボタンをダブルクリックして「quit」でしたね。ボタンの表示は「終了」にしておきます。

  4.  - スタートボタンを配置する -

     2つめのボタンを「微分方程式」のウィンドウに持ってきます。Captionの欄は「スタート」としておきます。

  5.  - Canvasを配置する -

     Canvas(ツールボックスにある夕日の絵(朝日かな?)の付いたアイコンです。)を「微分方程式」のウィンドウに持ってきます。今回は、LeftやTopの設定をプログラム内で行ってみましょう。先ほどのStaticTextと3つのボタンは適当に位置に配置し直して下さい。

  6.  - Dialog1を作る -

    設定を変更するためのもう1つの画面を用意します。作り方は、File MenuからNew Windowを選択します。これで「Untitled」と表示されたウィンドウ、Dialog1が作られました。「Untitled」は「Dialog1」と表示を変更しておきます。
    またこのとき、Dialog1のウィンドウをダブルクリックして、Code Browser (Dialog1)を開き、この中のEventsにあるCloseを選択して現れる画面に「close」とプログラムするくせを付けておくとよいと思います。これは、ウィンドウの左上のボタンが押されたとき、ウィンドウを閉じる命令です。
    (注意、このときのDialog1のFrameの欄は「0-Document Window」にしておきます。)
    Sub Close()
     close
    End Sub
    ですね。
    もちろん「閉じる」のボタンを作ってもよいわけです。
     ついでに、Dialog1のウィンドウに、Pushbutton1とEditField1を作っておきます。Pushbutton1のCaptionの欄は「設定終了」にしておきます。

  7.  - Module1を作る -

    Window1とDialog1の2つのウィンドウの間で共通に使える変数やサブルーチンを定義するにはModuleが必要となります。Dialog1からはじめのWindow1に変数を送り込むため手段としては「self」を使う方法もあります。(REALbasic覚え書きにサンプルがあります。)今回はModuleを使います。Projectウィンドウをアクティブにして下さい。File MenuからNew Moduleを選択します。これでModule1が作られました。ProjectウィンドウにWindow1とMenuとDialog1とModule1の4つが表示されていることを確認して下さい。

  8.  - メニューの設定 -

    今回はメニューから設定変更できるようにしてみます。
    1.  ProjectウィンドウよりMenuをダブルクリックするとApplication Menuの画面が表れます。この画面でメニューの編集をする事になります。
    2.  Editの横の灰色の四角を反転させて、PropertiesウィンドウのAppearanceのTextの欄を「その他」にする。
    3.  Application Menuの画面でこの「その他」の下に出てきた灰色の四角を反転させ、同様にしてPropertiesウィンドウのAppearanceのTextの欄を「設定変更」にする。このときNameの欄にはプログラム内で使うことになるメニュー名を書いておく。ここでは「settei」としました。
       これでApplication Menuの画面での作業は終わりです。
    4.  次に、Window1のCode Browserの画面にします。ここで、EditメニューのNew Menu Handlerを選択してNew Menu Handlerの画面を出します。Menu Itemのポップアップメニューから「settei」を選択してOKボタンを押します。先ほどのApplication Menuの画面での作業でメニュー名に「settei」を付けていなければこのMenu Itemのポップアップメニューにはもちろん「settei」は現れません。 これで、Menu Handlerに「settei」が付け加えられます。
    5.  このsetteiに書き込んだプログラムが、メニューから設定変更を選択したとき実行されるわけです。
       最後にもう一ステップあります。けっこう面倒ですね。でも、このような仕様ですので仕方ありません。
       Window1のCode Browserの画面でEventsの中からEnableMenuItemsを選択して、この中に、
      Sub EnableMenuItems()
       settei.enabled=true
      End Sub
      とします。 これがなければ、実行したとき、メニューが灰色の状態で、選択できない状態になります。これで、メニューの準備は終了です。

  9.  - Module1にプログラム開始 -

       今回のプログラムは、Moduleにサブルーチンの形で作ります。後から、このサブルーチンを、Window1のスタートボタンから呼び出すことにしましょう。
    1. Projectのウインドウで、Module1をダブルクリックします。
    2. EditメニューからNew Methodを選びます。
      Procedure name : には「sinndou」。
      Parameters : には「k1 as double、ca1 as canvas」。
      Return Type : には何も書き込みません。
      としします。これは、プログラム中での名前が「sinndou」で、引数としてdouble型の「k1」と グラフを描くための「canvas」を表すcanvas型の「ca1」をもつサブルーチンを定義したものです。「k1」には前回の、単振動の公式中での比例定数を指定できるようにするためです。

    3. Methodsに「sinndou」が加えられました。いよいよここにメインプログラム開始です。

       まず変数の定義です。これは必ずプログラムの先頭に置きます。
       数式に使う予定の変数 a1 v1 x1 dt t は double で定義し、for〜next 文に使う文字 n は integer で定義します。始めにすべての変数を考えるのは相当に神経を使いますが、実際にはメインのプログラムを書いた後、使った変数を先頭の位置に定義すれば良いし、Debug から RUNすれば定義を忘れた変数はメッセージが出て止まるのでわかります(いいかげんすぎるか?)。
       先頭に 「rem」 または 「//」 または 「' 」 を置くとその行は、プログラムには関係なく覚え書きや、コメントを書き込んでかまわない行となります。
       Sub sinndou(k1 As double) の下に続く命令は、以下のようになります
      //
      dim a1, v1,x1, dt,t as double
      dim n as integer
      dim ca1 as canvas
      //
       つぎは、微少時間Δt(ここではdt) の値を0.1と決め、時刻0での初期条件として kを1 x1を100(前回の説明では10としましたが今回は100としました) v1を0 とすると a1 の初期条件は a1=-k*x1=-100 となります。これらの値の代入式は以下のようになります。1行に1つの式を書き必ず改行します。
      //
      dt=.1
      x1=100
      v1=0
      a1=-k*x1
      //
       次に、座標軸を描きましょう。グラフを描くためのCanvasの座標は、左上端から右に向かってx軸があり、左上端から下に向かってy軸があります。この座標軸上ですべての位置を考えます。直線を引く命令は、Canvasつまりこのサブルーチン内では「ca1」を指定して  ca1.graphics.DrawLine x1,y1,x2,y2 の形式となり、直線の始点と終点の座標がそれぞれ(x1,y1) (x2,y2)となります。
       グラフを描くための縦軸と横軸の直線を引きます。ここではグラフの原点をこのウインドウ上の座標で(100,200)としています。
      // 
      ca1.graphics.DrawLine 100 ,200 , 500 , 200
      ca1.graphics.DrawLine 100 ,10 , 100 , 350
      //
       さて計算と作図開始です。時間軸に沿って100点ほど計算したいので
       for n=0 to 10/dt とします。dt は0.1 でしたね。t=20*n*dt は、横軸の時間 t を表す式です。n*dt は実際の時間に相当する値ですがこれではグラフは 0 から10 までの非常に短いグラフになりますので、目盛りを拡大するために、20*n*dt としました。
      ここからが、メインのプログラムです。
       前回の説明を思い出してください。加速度の初期値 a0 を使って、dt 秒後の速度 v1 を計算し、この v1 を使って x1 を求め、さらにこの x1 を使って次の加速度 a1 を求めます。この加速度 a1 が次の計算では加速度の初期値となるわけです。ここまでの操作を何度も繰り返すわけですから、プログラムとしては、次のようになります。ここが1番肝心な部分ですから、何度も考えてください。この考え方がコンピュータで数値解析プログラムを作る基本です。おおげさに云っていますが、このアルゴリズムを楽しんでください。
      for n=0 to 10/dt
      t=20*n*dt
      v1=v1+a1*dt
      x1=x1+v1*dt
      a1=-k1*x1
      next
       さて、プログラムの中心部分の説明は終わりましたが、このまま実行しても、計算するだけで結果は表示されません。これでは何のために苦労しているのかわかりませんね。そこで、計算の途中経過をグラフ上に示します。
       位置 x と速度 v と加速度 a を一度に表示してしまいましょう。
       直線を引く命令はありますが、個人的には点を打つ方が好きなので今回は、小さな四角を利用します(小さな丸でも楕円でも結構です)。
       ca1.graphics.drawrect x1,y1,w,h が四角を描く命令です。x1,y1 は四角の左上の頂点の座標で w ,h はその四角の幅と高さです。この幅と高さを小さくとれば点に見えるわけです。
      x1,y1 に描きたい点の座標を入れればよいのですから、 x1 には時間 t を、 y1 には位置 x と速度 v と加速度 a それぞれを入れた命令を書くと、微分方程式を解く過程で必要になる、速度 v や加速度 a の変化もグラフにすることが出来ます。従って、3つのグラフを同時に描くために、幅と高さが共に2の四角の点を打つには、次のように、
      ca1.graphics.drawrect t,x1,2,2
      ca1.graphics.drawrect t,v1,2,2
      ca1.graphics.drawrect t,a1,2,2
      とすれば良さそうですが、このままではとんでもないところにグラフを描いてしまいます。 
       思い出してください、座標軸を描いたとき、ウインドウの座標は、左端から右に向かってx軸があり、上端から下に向かってy軸があるのでしたね。この座標軸上ですべての位置を考えることになりますから。y軸はいつもとは逆の方向です。このために、 x1 , v1 , a1 の符号を負にします。また描きたいグラフの原点をこのウインドウ上の座標で(100,200)としましたので正しい命令は次のようになります。
      ca1.graphics.drawrect 100+t,200-x1,2,2
      ca1.graphics.drawrect 100+t,200-v1,2,2
      ca1.graphics.drawrect 100+t,200-a1,2,2
       ついでに、3つのグラフの区別を色で見分けられるように、それぞれの命令の前に色指定の命令をつけ加えます。
       色指定は ca1.graphics.forecolor = RGB(50、80、100) の命令を使います、はじめの50はレッドの値、次の80はグリーンの値、次の100はブルーの値、というように使いますが、実際の色は、実行してみないとわかりません。(覚え書きのページに、実際の色とRGBのColor値を表示するサンプルがあります。)数字を変えて試してください。最後の行の ca1.graphics.forecolor = RGB(0,0,0) は、ほかのところに色づかいが影響しないように、黒に戻しておく命令です。
      //
      for n=0 to 10/dt
      t=20*n*dt
      v1=v1+a1*dt
      x1=x1+v1*dt
      a1=-k1*x1
      ca1.graphics.forecolor = RGB(100,0,100)
      ca1.graphics.drawrect 100+t,200-x1,2,2
      ca1.graphics.forecolor = RGB(100,100,0)
      ca1.graphics.drawrect 100+t, 200-v1,2,2
      ca1.graphics.forecolor = RGB(0,100,100)
      ca1.graphics.drawrect 100+t, 200-a1,2,2
      ca1.graphics.forecolor = RGB(0,0,0)
      //
       最後に、 for n=0 to 10/dt と必ずペアーで使う next を入れて終了です。
      //
       next
      //
       これでModule1での作業は、おしまいです。いや、もう1つ残っていました。後から、設定変更のDialog1から変数をWindow1に持ってくるために、ウィンドウ間で使える変数「k」をModule1で定義しておきます。EditメニューからNew Propertyを選びます。Declaration : に「k as double」です。

    4.  - Window1にプログラム -
        さて、ProjectのウィンドウからWindow1をダブルクリックして「微分方程式」のウィンドウを開きます。このウィンドウをダブルクリックしてCode Browserを開きます。
      1.  PushButtonやCanvasなどの各コントロールをウィンドウ上に配置する方法は、ウィンドウの画面上をマウスでドラッグする方法と、プログラムで指定する方法があります。今回は、プログラムで指定してみます。
         そこで、EventsのOpenに次のように書き込みます。
        //スクリーン一杯にwindow1を広げる
        //screen(0)は今使っているコンピュータ
        //のスクリーンの情報を表す。
        window1.top=0
        window1.left=0
        window1.width=screen(0).width
        window1.height=screen(0).height
        //window1に対して、上に少しボタン
        //を配置する隙間を考えて、canvas1を
        //配置する。
        canvas1.top=window1.height*.2
        canvas1.left=0
        canvas1.width=window1.width*.8
        canvas1.height=window1.height
        //ボタンとテキスト上に配置する。
        pushbutton1.top=canvas1.top
        pushbutton1.left=canvas1.width*.5
        pushbutton2.top=canvas1.top
        pushbutton2.left=canvas1.width*.8
        statictext1.top=canvas1.top
        statictext1.left=canvas1.left+10
         このように、プログラム内で、各コントロールの位置は自由に設定することができます。でも、マウスで画面の上に配置する方がずっとらくですね。
      2.  「スタート」ボタンとなるPushbBtton2のAction に, 定数 k の表示と、サブルーチンに飛ぶ命令「sinndou k,csnvas1」を書きこみます。サブルーチン内では、「k」は「k1」に、「csnvas1」は「ca1」に代入されます。(サブルーチンに関しては「覚え書きのページ」にサンプルがあります。)
        Sub Action()
         staticText1.text="定数 K= "+str(k)
         sinndou k,canvas1
        End Sub
        となります。
      3.  メニューの動作のプログラムを書きます。
         Menu Handlersの「settei」に次の2行を書き込みます。
        dim d as dialog1
        d=new dialog1
         これで、メニューの設定変更からDialog1が開きます。

    5.  - Dialog1にプログラム -

      「設定終了」のpushbutton1に次のコードを書き込みます。
      k=val(editfield1.text)
      close
       注意、プログラムを実行したときは、設定変更での値は、小数でかまいませんが、範囲は0から5くらいが見やすいです。

    6.  - Build Application -

       Debug から RUNしてみてください。たぶんどこかにミスが出ると思います。それを修正できましたらいよいよ最終段階です。Debug から RUNして正常に動くことが確認できたところで、KILLして止めます。
       メニューのFile からBuild Applicationを選びます。
       68k CodeかPowerPC Codeにチェックマークを入れますName は適当に好きな名前を付けます。 これで Build のボタンを押します。あなたが自分の手で作ったマック用のアプリケーションの完成です!!
        少し、説明がだらだらとなってしまいましたが、この後は皆さん方で楽しんで(苦しんで?)ください。

       サンプルにもう1つ、減衰振動の表示プログラムを作ってみました。REALbasicの可能性がわかることでしょう。
       今回の「微分方程式」と「Oscillation」の ソースプログラムです
        
        プロジェクトファイルのみです。REALbasicの最新バージョンが必要です。30 kバイト
                koko-@mx2.tiki.ne.jp

このホームページのホストはです。 無料ホームページをどうぞ!