[ 前へ | 目次 | 次へ ]
Japanese English
Now Loading...
ダウンロード
PC (※スマートフォンでは動きません) でダウンロードし、ZIPファイルを右クリックメニューから展開して、できたフォルダ内の「 VCSSL.bat(バッチファイル) 」をダブルクリックすると起動します。 Linux等では「 VCSSL.jar 」をコマンド実行してください。
» 詳しい使用方法や、エラーで展開できない際の対応方法などはこちら

正弦波のアニメーション表示

振幅・波長・周期などのパラメータに基づいて、正弦波のグラフをアニメーションで描画するVCSSLプログラムです。

スポンサーリンク


使用方法

ダウンロードと展開(解凍)

まず、PC(スマホは未対応)で上の画面の「 ダウンロード 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされます。

Windows をご使用の方は、ここでまずZIPファイルを右クリックし、「プロパティ」を選んで開かれる画面で、 下の方にあるセキュリティ項目の「許可する」にチェックを入れて「OK」で閉じてください。 これを行わないと、ZIP展開やソフト起動時に、警告メッセージが出て展開完了/起動できない場合があります。

その後、ZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開(解凍)してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。

» 展開がエラーで止まってしまう場合や、ファイル名が文字化けしてしまう場合は…

プログラムの起動

Windows をご使用の場合

上記でZIPファイルを展開したフォルダ内にある、以下のバッチファイルをダブルクリック実行してください:

VCSSL__ダブルクリックでプログラム実行.bat

もしプログラムを書き変えながら使いたい場合は、代わりに「 VCSSL_Editor__プログラム編集はこちら.bat 」を実行してください。

正常に起動できると、初回のみ、Java実行環境を入手するか等を尋ねられるので、適時答えて済ませると、プログラムが起動します。 2回目以降はすぐに起動します。

» うまく起動できずにエラーになってしまう場合は…

Linux 等をご使用の場合

ZIPファイルを展開したフォルダ内へコマンドライン端末で cd して、以下の通り入力して実行してください:

java -jar VCSSL.jar
(プログラムの内容を書き変えながら使いたい場合は、代わりに VCSSL_Editor.jar を実行)

» javaコマンドが使用できない等のエラーが表示される場合は…

起動後の画面

起動すると、まず波のパラメータを数値入力するか尋ねられます。 特に「ぴったりこの値の波長にしたい」などの必要が無ければ、「いいえ」でスキップして構いません。

その後、グラフ画面とパラメータ設定画面が立ち上がります。

起動後の画面

グラフ画面では、正弦波がアニメーション表示されます。 パラメータ設定画面では、波の波長や振幅、周期などの値をスライダーで操作できます。

ウィンドウを閉じると、プログラムの実行が終了します。

題材解説

正弦波の式

分野や用途によって色々な書き方がありますが、 正弦波の形と動きは、グラフに描く際の横軸を \(x\)、縦軸を \(y\)、時刻を \(t\) として、以下の式で表す事ができます:

\[ y = A \sin 2 \pi \bigg( \frac{t}{T} - \frac{x}{\lambda} \bigg)    (1) \]

一般性をもたせるには、さらに初期位相の項 \( + \delta \) などを sin 関数のカッコ内に追加したりしますが、 ここでは簡単にするため、初期位相は 0 にして無視する事にしましょう( 初期位相を入れても、時刻 t = 0 での正弦波の位置がずれるだけです)。

さて、上の式で \(A\) は振幅、\(\lambda\) は波長、\(T\) は周期 です。 以下では、これら3つのパラメータが、それぞれ正弦波の何を表すのかを簡単に抑えておきましょう。

振幅 \(A\)

振幅は、その名の通り、波の振れ幅 を司るパラメータです。

ただし、振れ幅といっても、一般に振幅は 振動の中心(上の式では \(y=0\) )から端までの長さ を指す事に注意が必要です。 振動の両端の間の長さではありませんよ! それは振幅の2倍です。

正弦波と振幅の図

波長 \(\lambda\) (ラムダ)

続いて波長です。これもその名の通り、波の「形」の長さを司るパラメータです。 波長が長いほど、x 軸上で横に長く引き延ばされた形になり、逆に波長が短いと押し縮められた形になります。

より具体的な波長の説明は、色々な言い方があり得るのですが、 波を \(x\) 軸上で平行移動してずらしていった時に、元の形と初めてぴたっと重なるまでの移動の長さが、ちょうど1波長になります。 これをもう少し図示しやすいように噛み砕くと、 ある点から、山と谷を1個づつ超えて、元と同じ位置・形(つまり同位相)の地点までの長さと言う事もできます。

正弦波と波長の図

ここで、山1個や谷1個だけの長さを波長と思ってしまうと、間違いなので注意が必要です。 だって、波を山1個分だけ平行移動でずらしても、元の形と重なりませんよね? 山と谷をワンセットで越えて、はじめて1波長です。

周期 \(T\)

周期も波長と似ているのですが、こちらは空間( \(x\) )ではなく時間( \(t\) )に関するパラメータです。 具体的には(これも色々な言い方があるでしょうが)、 ある瞬間に波のある1点に注目した際に、 その点が時間の経過で動いていくうえで、初めて元と同じ状態になる(位置やその後の動きも含めて同じ、つまり同位相になる)までの経過時間の長さが、 ちょうど1周期になります。

もうイメージしやすいように少し噛み砕くと、 ある瞬間に、ちょうど波の上端に位置している点( \( x を固定\) )に注目した場合、その点が下まで降りてからまた昇ってきて、再び上端に来るまでの時間 が、ちょうど1周期になります。

正弦波と周期の図

ここで最初に振動の上端にいる点に注目しているのがちょっとしたポイントです。 もし最初に中途半端な点に注目してしまうと、1周期の間で「上方向への通過」と「下方向への通過」の2回、同じ y の位置を通過するので、 判断がちょっとややこしくなります(実際に上図で、x = 3.0 の位置の点を追いかけてみると分かりやすいです)。 最初に振動の端の点に注目すれば、同じ y の位置に戻って来るのは1周期ごとに1回ずつで、単純で済みます。

平行移動しても同じ形にならない波の波長や、複雑な振動の周期は?

ここで扱っている正弦波については、波長や周期に関する上の説明は素直に当てはまります。 しかし、正弦波というのは理想的な波であって、日常で出会うもっと一般の波や振動では、 波長を測ろうにも平行移動してぴたっと重なる事なんてなかったり、周期を測ろうにも不規則な動きをしていたりもします。

じゃあ、波長や周期のような量は、正弦波くらいにしか使えず、一般では全然使い物にならないのかというと、そうではありません。 実は、一般の複雑な波や振動も、無数の正弦波の重ね合わせとして表す事ができます。 なので、その中で、どれくらいの波長(や周期)の正弦波が、どれくらい多く含まれているのか、といった見方ができます。 例えば、細かい凹凸のある波は、波長の短い正弦波の比率が多く、のっぺりした波は、波長の長い正弦波の比率が多いです。 周期についても同様です。

つまり一般の波や振動では、波長や周期が1つの値から、幅を持った分布になるイメージです。 そのような分布の解析は、様々な分野で非常に重要なものとなっています。


スポンサーリンク


コード解説

このプログラムのコードはVCSSLで記述されています。 ここではそのコード内容について簡単に解説します。 VCSSLはC系の単純な文法の言語なので、C言語などに触れた事のある方なら簡単に読めると思います。

グラフの範囲などを変えたり、色々と改造したいといった場合などは、 プログラムのコード「 SineWave.vcssl 」をテキストエディタで開いて改造してください。 スクリプト言語なので、コンパイラなどの別ソフトは不要で、コードを書き換えるだけでOKです。

コード全体

まずは、コード全体を見てみましょう。

以上です。大体200行ちょっとの規模の短いコードですね。 各部で行っている処理はコード内のコメントの通りですが、 以下では先頭から順を追って、もう少し詳しく説明します。

先頭領域

まずは、先頭の4行です。

1行目では、コードのファイルで使用している文字コード(Shift_JIS)を宣言しています。 書かなくても動きますが、書いておくと、別のOSのPC上で実行した際などに文字化けするのを防げます。Shift_JISの他にUTF-8も使用できます。

2行目では、数学関数を使用するためにMath ライブラリを読み込んでいます。 正弦波では sin 関数を使いますが、それがこのライブラリで提供されています。

3行目では、GUIの機能を提供する GUI ライブラリを読み込んでいます。 波のパラメータを操作する設定画面を構築するためです。

4行目では、2次元グラフソフトの制御機能を提供する Graph2D ライブラリを読み込んでいます。 今回は、正弦波の描画処理は自力では書かず、グラフソフトに配列で座標データを渡してプロットしてもらいます。

波のパラメータ用変数の宣言

続きです。題材解説で触れた、波の3つのパラメータである振幅・波長・周期を変数として宣言しています。

この通り、振幅を amplitude、波長を wavelength、周期を period の名前で宣言しています。 これらの変数の値は、設定画面でスライダーを操作した際に、イベントハンドラの処理で書き換えられます。

※ 数式通りに A、lambda、T と名付けてもよかったのですが、 実はこのプログラムの派生版で複数の波が存在するものを扱うつもりで、 その時に波A、波B、波Cが登場した時に、A_A とか L_A とか T_A とか T_B とか出てくるとなんかややこしそうだな… と思って、振幅・波長・周期を表す英語で素直に名付けました。 大文字の変数名は定数とする命名規則の存在も考えると余計に紛らわしいですし…

設定画面用の変数

続いて、スライダーで波のパラメータを操作するための設定画面で使う変数を宣言しています。 といっても、GUIコンポーネントのIDを控えるものが列挙してあるだけです。

GUIコンポーネントIDは、ウィンドウやスライダーなどのGUI部品ごとに割りふられる番号で、 例えばどのスライダーが操作されたかなどを判別する際に使います。 詳細は GUI開発ガイド をご参照ください。

グラフ関連の変数

その後も、グラフ描画関連で使う変数などの宣言が続きます。

大半はプロット範囲やアニメーションの時間刻みなどの設定値の定義で、役割はコメントの通りです。

最後の2行はちょっと違って、描画時にグラフソフトに渡す座標値データを格納するための配列を宣言しています。 描画する内容を細かい点の集まりで表して、各点のX座標とY座標をこのように配列にまとめて渡すと、 グラフソフトはその点を線で結んで描いてくれます。

配列からグラフをプロットする単純な例は「 配列を2Dグラフにプロットする 」の回をご参照ください。

その他の制御用変数

変数宣言の最後です。その他の変数を宣言しています。

speed はアニメーションの速度を調整するための変数で、設定画面のスライダーで操作できます(操作すると値が書き換えられます)。

graphは、上で触れたGUIコンポーネントのIDと同様に、グラフに割りふられるIDを格納するための変数です。 グラフは複数使用できるので、データを渡したりオプションを設定したりする際に、どのグラフが操作対象なのかを指定するためにIDが割りふられるのですが、それを控えます。

continuesLoop は、アニメーションループを継続するか脱出するかを制御するための変数で、true で継続、false で脱出します。すぐ後の main 関数で使うので、またそこで軽く触れます。

t は時刻の値を格納する変数で、アニメーションループの中で小刻みに増加します。時刻リセットボタンでリセットできるように、グローバル変数にしています。

グローバルな変数の宣言は以上です。

中心的な処理

続いて処理内容です。まずは最も中心的な(全体を俯瞰した)処理の流れを見ていきましょう。 それは main 関数の中にまとめてあります。main 関数は、プログラム実行時に自動で実行されます。

最初に、createGraph 関数を呼び出してグラフを起動していますが、この関数は同じコード内に記述されていて、すぐ後で説明します。 その後は続いて、createSettingWindow を呼び出して設定画面を構築していますが、これについても同様です。

そういった立ち上げ時の下準備が終わると、 while( continuesLoop ) { 〜 のアニメーションループに突入します。 continuesLoop の値は終了時以外はずっと true なので、基本的にはこのループは無限ループのようなものです。

このアニメーションループ内で、時刻 t の値を少しずつ変えながら、正弦波の形を表す座標値データをグラフに渡して描画させる事をくり返しています。 するとパラパラ漫画の容量で、グラフが動いて見えるわけです。

より具体的に、正弦波の座標値データを配列 x、y に格納し、グラフに渡している箇所に注目してみましょう。

for 文の部分で、グラフのX軸の範囲を小刻みDTずつ刻んだ各点(X座標は x )において、 その点の正弦波の値を以下のように計算し、waveY に格納しています:

この行は、冒頭で扱った正弦波の式:

\[ y = A \sin 2 \pi \bigg( \frac{t}{T} - \frac{x}{\lambda} \bigg) \]

をそのままプログラムの記述に直したものです。

もし、今回扱った正弦波とは違う形のグラフをアニメーションさせたい場合は、この行を書き換えてください。 ( 実際に次回では、複数の正弦波が干渉する式にして、波の干渉の様子をシミュレーションしてみます。)

データをグラフに渡して描画させたら、後はアニメーションが速くなりすぎないように wait 関数で30ミリ秒(1ミリ秒は1000分の1秒)だけ休止して、 また時刻 t をちょっと変えつつアニメーションループの内容を延々と繰り返します。

ただし、ユーザーがウィンドウを閉じると、continuesLoop の値が false になって、アニメーションループを脱出します。 すると exit 関数が呼ばれて、プログラムの実行が終了します。 このあたりの一見無駄に複雑になっている仕掛けは、ウィンドウを閉じた瞬間に exit 関数を呼ぶようにすれば必要無いのですが、 それだとメインスレッドが処理中にイベントハンドラのスレッドから強制終了するような形になるので、 ちょっと行儀よくするためにこう書いています。そう深い意味は無いです。

プログラムの大枠の流れは、以上の通りです。あとは細かい部品的な処理になります。軽めにざっと説明します。

波のパラメータの入力 - inputParameters関数

main 関数の冒頭で最初に呼ばれていた inputParameters 関数では、 ユーザーに波のパラメータを手動入力するか尋ねたうえで、 必要なら input 関数でパラメータを入力してもらい、 それをグローバル変数に代入しています。

波のパラメータはスライダーで調整できるのですが、 スライダーは直感的である代わりに細かい調整が難しかったりするので、 「ぴったりこの値の波長にしたい」といった場合のために、 起動時に値を数値入力できるようにしています。

起動後もいつでも値を指定できるように、 スライダーの横に数値入力項目を設けてもいいのですが、 設定画面の構築が少し手間ですし、 あまり本質的でない部分でコードを長く複雑にしたくもないので、 割り切ってちょっと楽をしています。

グラフの起動と設定 - createGraph関数

同じく main 関数の冒頭で呼ばれていた createGraph 関数では、2次元グラフソフトを起動して、各種設定を行っています。

基本的にはコメントの通りですが、留意点としては、起動したグラフに割りふられたID番号を、グローバル変数の graph に格納している所です。 main 関数内でグラフにデータを渡す際などに、この id を引数で指定しています。

設定画面の構築 - createSettingWindow関数

同様に main 関数の冒頭で呼ばれていた createSettingWindow 関数では、波のパラメータをスライダーで操作するための設定画面を構築しています。

基本的には、まずウィンドウを生成して、その上にスライダーやラベルなどのGUIコンポーネントを生成しては配置して、生成しては配置して、... と繰り返しているだけです。 いくつかのコンポーネントでは、グラフ同様に、グローバル変数にIDを控えています。

単品の簡易コードなので、スライダーの位置やラベル値などをベタ書きしていますが、ご容赦ください (各引数の意味などは、コードの関数名部分に張られているリンクから仕様書ページに飛んで確認できます)。

なお、VCSSLでのGUIの構築方法について詳しく知りたい方は、GUI開発ガイド をご参照ください。

スライダー値の表示ラベルの更新 - updateInfoLabel 関数

上で見た createSettingWindow 関数内で、updateInfoLabel 関数を呼び出していますが、これも同じコード内に記述された関数です。

何をする関数かというと、スライダーの値を「(A=1.0, λ=2.0, T=0.5)」のように表示するための、ラベルの内容を設定(更新)する関数です。

基本的にはパラメータ値を文字列に埋め込んでラベルに設定しているだけですが、 パラメータ値は16桁くらいある倍精度浮動小数点数なので、ものすごい長い桁数になると見づらいため、 round関数で小数点以下2桁に丸めた値を表示用に使うようにしています。

イベントハンドラ

最後に、スライダーやウィンドウなどのGUIコンポーネントが操作された際に実行される、イベントハンドラ関数です。

イベントハンドラ関数は、どのGUIコンポーネントが操作されたかを区別するために、引数にIDが渡されます。 スライダーが操作された際に呼び出される onSliderMove 関数では、実際に受け取った ID に基づいて、 振幅スライダーなら振幅、波長スライダーなら波長、といったように、対応する波の変数を書き換えています。

スライダーが操作されると、スライダーの値を表示するラベルの内容もリアルタイムで書き換えたいので、 先ほど見た updateInfoLabel 関数を末尾で呼び出しています。

次の関数である onButtonClick 関数はボタンを押した際に呼び出される関数で、 時刻リセットボタンが押されると時刻変数 t を 0 にリセットする処理を書いています。 今はボタンは 1 つしかないのですが、後々追加する可能性が結構ありそうなので、 一応は ID による分岐で、押されたボタンの判定をしています。

その後の onWindowClose 関数はウィンドウを閉じた際に呼び出されますが、 そこではアニメーションループを脱出してプログラムを終了させるために continuesLoop の値を false にしています。 今は自分で構築したウィンドウは1つしかなく(グラフは別扱いです)、また今後増やす事も考えにくいので、IDによる分岐は省略しています。 グラフを閉じると onGraph2DClose 関数が呼ばれるのですが、そこでも同じ処理をしています。

コード内容は以上です。

ライセンス

このVCSSL/Vnanoコード( 拡張子が「.vcssl」や「.vnano」のファイル )は実質的な著作権フリー(パブリックドメイン) である CC0 の状態で公開しています。 記事中にC言語/C++/Java言語などでのサンプルコードが掲載されいてる場合は、それらについても同様です。 そのままでのご利用はもちろん、改造や流用などもご自由に行ってください。

※ ただし、このコードの配布フォルダ内には、ダウンロード後すぐに実行できるように、 VCSSLの実行環境も同梱されており、そのライセンス文書は「 License 」フォルダ内に同梱されています (要約すると、商用・非商用問わず自由に使用できますが、使用の結果に対して開発元は一切の責任を負いません、といった具合の内容です)。 配布フォルダ内の各構成物の一覧やライセンスについては「 ReadMe_使用方法_必ずお読みください.txt 」をご参照ください。

※ Vnano の実行環境については、別途スクリプトエンジンのソースコードも一般公開しており、 何らかのソフトウェア内に組み込んでご利用いただく事も可能です。詳細はこちらをご参照ください。

この記事中の商標などについて

  • OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
  • Windows は、米国 Microsoft Corporation の米国およびその他の国における登録商標です。この記事は独立著作物であり、Microsoft Corporation と関連のある、もしくはスポンサーを受けるものではありません。
  • Linux は、Linus Torvalds 氏の米国およびその他の国における商標または登録商標です。
  • その他、文中に使用されている商標は、その商標を保持する各社の各国における商標または登録商標です。


スポンサーリンク



Japanese English
[ 前へ | 目次 | 次へ ]
Vnano版 | ローレンツ方程式を数値的に解くプログラム

ローレンツ方程式を4次ルンゲ=クッタ法によって解き、グラフ描画用のデータを出力するプログラムです。
波の干渉(面上の円形波)のアニメーション表示

面上の円形波が干渉する様子を、パラメータを操作しながらアニメーションで見られるプログラムです。
円形波のアニメーション表示

振幅・波長・周期をスライダ―で操作しながら、円形波のグラフをアニメーションで見られるプログラムです。
波の干渉(線上の正弦波)のアニメーション表示

線上(1次元の)の正弦波が干渉する様子を、パラメータを操作しながらアニメーションで見られるプログラムです。
正弦波のアニメーション表示

振幅・波長・周期をスライダ―で操作しながら、正弦波のグラフをアニメーションで見られるプログラムです。
凹レンズを通過する波のシミュレーション

凹レンズ形状の高密度媒質を通過する、波のシミュレーションです。
凸レンズを通過する波のシミュレーション

凸レンズ形状の高密度媒質を通過する、波のシミュレーションです。
乱雑な密度分布における波のシミュレーション

密度分布が乱雑な媒質中における、波の伝播のシミュレーションです。
ローレンツアトラクタ(ファイル出力版)

4次精度ルンゲ=クッタ法により、ローレンツアトラクタを求めるプログラムです。
波の屈折のシミュレーション

密度の異なる領域を、波が屈折しながら通過するシミュレーションです。
力学アルゴリズムによる波のシミュレーション(面上の波)

媒質をバネと格子点で近似し、力学的なアルゴリズムで動かす事による、波のシミュレーションです。
手動で波を発生させるシミュレーション

スライダーをマウスで動かす事により、波を発生させるシミュレーションです。
力学アルゴリズムによる波のシミュレーション(線上の波)

媒質をバネと格子点で近似し、力学的なアルゴリズムで動かす事による、波のシミュレーションです。
二重振り子のシミュレーション

ラグランジュ方程式を用いた、二重振り子のシミュレーションです。
ローレンツアトラクタ(GUI版)

4次精度ルンゲ=クッタ法により、ローレンツアトラクタを求めるプログラムです。
この階層の目次
[ 前へ | 目次 | 次へ ]
お知らせ

各ソフトウェアをアップデート、リニアングラフのコマンド拡張やVCSSLの英語対応など
2024/02/05 - 各ソフトの一斉アップデートの内容をお知らせします。今回は、リニアングラフのコマンド機能を大幅拡張したのがメインです。また、VCSSLのメッセージ類の英語対応も行いました。

Vnano の Ver.1.1 で実装した反復計算高速化の内側
2024/01/17 - 前回のお知らせ記事の続編です。スクリプトエンジン Vnano の Ver.1.1 において実施した高速化を、エンジン内部の実装面から掘り下げて解説します。

スクリプトエンジン Vnano の Ver.1.1 を公開、同じ内容の反復実行が劇的に高速化
2023/12/22 - スクリプトエンジン Vnano の最新版を公開しました。同じ計算式やスクリプトを反復実行する速さが、大幅に向上しました。次期版リニアングラフ3D内での活用例を交えつつ、詳しく解説します。

新着
[公式ガイドサンプル] 各種の図形や画像を描画する

「VCSSL 2DCG開発ガイド」内のサンプルコードです。図形や画像などを描画します。
2022-12-16
角度の「度」とラジアンとを相互変換し、図示もするツール

45度などの「度」の値と、ラジアンの値とを相互に変換できるツールです。対応する角度の図示もできます。
2022-11-22
[公式ガイドサンプル] 立体モデルを回転させるアニメーション

「VCSSL 3DCG開発ガイド」内のサンプルコードです。立体モデルを、アニメーションで回転させ続けます
2022-11-18
[公式ガイドサンプル] 立体モデルを回転させる

「VCSSL 3DCG開発ガイド」内のサンプルコードです。立体モデルを、指定した角度だけ回転させます。
2022-11-17
[公式ガイドサンプル] 四則演算の計算順序や、カッコを使った順序指定

「VCSSLスタートアップガイド」内のサンプルコードです。四則演算が計算される順序や、カッコを使って順序を指定する方法を例示します。
2022-10-31