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

波の屈折のシミュレーション

このVCSSLプログラムは、密度の異なる領域を、波が屈折しながら通過する様子をシミュレーションします。 密度分布は画像ファイルとして読み込む設計になっているため、色々と応用の幅が広いプログラムです。

使用方法

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

まず、PC(スマホは未対応)で上の画面の「 ダウンロード 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされるので、そのZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開(解凍)してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。

» 展開がエラーで止まってしまう場合は…

なお、Linux® 等をご使用で、右クリックメニューから展開するとファイル名が文字化けしてしまう場合は、 コマンドライン端末でZIPファイルのある場所まで cd した上で「 unzip -O cp932 ZIPファイル名 」で展開してみてください。

プログラムの起動

Microsoft® Windows® をご使用の場合

上記の通りにZIPファイルを展開したフォルダ内にある、 「 VCSSL.bat(種類はバッチファイル) 」をダブルクリック実行してください。 もしプログラムの内容を書き変えながら使いたい場合は、代わりに「 VCSSL_Editor.bat 」を実行してください。

実行すると、最初にメモリー使用量や、(必要な場合のみ)Java®実行環境を自動で入手するか 等を尋ねられるので、適時答えると、プログラムが起動します。2回目以降はすぐに起動します。

※ ここで入手したJava®実行環境は、ZIPファイルを展開した中の「 jre 」フォルダ内にダウンロードされ、このプログラムの実行のみに使用されます。PC全体に影響する形でインストールされる事はありません。

Linux® 等やその他のOSをご使用の場合

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

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

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

起動後の操作方法

起動すると、ウィンドウ上に画面が表示され、密度の異なる領域を通過する様子がアニメーションで見られます。

画面

画面ウィンドウ上では、下記のマウス操作を行えます。

  • 左ドラッグ … 視点の回転
  • 右ドラッグ … 視点の平行移動
  • ホイールスクロール … 拡大/縮小

密度分布の変更

密度分布は、画像ファイル「 density.png 」として描いたものを読み込むようになっています。実際にこのシミュレーションで用いているのは以下の画像です:

密度分布画像

この通り、斜めの方向に走る境界の左右で、密度の異なる領域が描かれています。この画像ファイルの内容を描きかえる事により、自由な密度分布に設定できます。 画像ファイルのピクセルごとの明るさが、その点の媒質密度に対応します。具体的には、暗いほど密度が重く、明るいほど軽くなります。

パラメータの変更

波に関する各種パラメータは、プログラムのコードの先頭領域にまとめて記載されています。 それらの値を書き換えると、色々と条件を変えてシミュレーションを楽しめます。

シミュレーションの題材解説

面上を伝わる波

このプログラムは、2次元的な「 面 」の上を伝わる波を扱っています。面上の波について詳しくは、今回は割愛しますので、詳しく知りたい方は以下のプログラムをご参照下さい。

密度が異なる領域

今回のシミュレーションでは、波の媒質の密度が、全体で均一ではありません。中心付近の境界を挟んで、左右で異なる密度分布の領域に分かれています(下図)。

密度が異なる図。中心を斜めに分断する線を境に、左と右で密度が異なる。
密度が異なる領域をもつ媒質
中心付近を斜めに分断する線を境に、左右で密度が異なる領域に分かれています。図中で明るい色は密度が小さい(軽い)領域で、暗い色は密度が大きい(重い)領域となっています。

上図において、青色の領域が波の媒質です。明るい色と暗い色で塗り分けられていますが、明るい色が密度が小さい(軽い)領域で、暗い色が密度が大きい(重い)領域となっています。

軽い/重い領域は、中心付近を斜めに分断する線を境にして分かれています。ここを波が通過する際に、後で述べる屈折が生じます。

なお、上の図は単なる解説イラストではありません。今回のプログラムでは、画像ファイルから密度分布を読み込んでシミュレーションするような設計となっています。実際に上の青色の画像を、そのまま密度分布の設定に使用しています。

波の速さは、密度によって変わる

密度を変えると、波の伝播において一体何が変わるのでしょうか。それは、波が伝わる速さです。

波が伝わる速さは、密度が軽い領域では速く、密度が重い領域では遅くなります。この事は波の屈折を理解する上で非常に重要です。

光の場合は、密度の代わりに屈折率

なお、光も電磁波という種類の波ですが、光の場合は、速さは媒質の質量的な密度ではなく、屈折率という値に依存して変わります。

しかしだからと言って、話が全く違ってきてしまうわけではありません。なぜなら、波の屈折を説明するのに最も重要なのは、領域によって速さが異なるという事だからです。なので、それが密度によるのか屈折率によるのかは本質ではありません。

今回のシミュレーションを、光についてあてはめる場合は、密度を屈折率に置き換えて読んで下さい。

波の速さが異なる領域に、斜めに入射した波は、「 屈折 」 しながら進む

いよいよ本題の、波の屈折についてです。

ここから先は、シミュレーションの画像を身ながら、起こる現象について解説していきます。

まず、下図のように左端から波が進んできて、領域の境界に入射します。

波が、領域の境界に対して斜めに入射していく開始時の図。
入射の開始
波が進行してきて、領域の境界に入射していきます。波は、境界に対して斜めに入射しているのが重要です。

密度の異なる領域は、画面中心付近の斜めの境界で左右に分かれています。そして、波はまっすぐ画面右方向に入射します。つまりこの時、波は、領域の境界に対して斜めに入射している事になります。これは重要な点です。

続いて、入射途中の様子です。

波が、領域の境界に対して斜めに入射していく途中の図。
入射の途中
入射の途中では、波の端の部分から、密度の大きい(重い)領域に突入していきます。この領域に入った部分から、波が遅くなっていきます。まだ密度の小さい(軽い)領域を進んでいる部分は遅れません。

波は境界に対して斜めに入射しているので、波の端の部分から、密度の大きい(重い)領域に突入していきます。

密度の大きい(重い)領域では波が遅いですから、結果、波の端の部分から、波が伝わる早さが遅くなっていきます。

対して、波の中で、まだ密度の小さい(軽い)領域にいる部分は、もとの速さのまま進んでいきます。

この結果、領域境界を突破した部分が遅れて、まだ突破していない部分が先に進んで行くという現象が起こります。

このようにして、最終的に全体が境界を突破した時点では、下図のようになります。

波が、領域の境界に対して斜めに入射し終わった図。
入射後
波の端から次々と遅れていった結果、波全体が領域を突破し終えた後は、入射時に比べて波に角度が付きました。これが波の屈折です。

上図のように、波の端から次々と遅れていった結果、波全体が領域を突破し終えた後は、波が斜めに傾いています。 波は最初は画面の上下にまっすぐと延びていました。これが傾いたので、入射時に比べて波に角度が付いたという事になります。

密度の境界を基準に見ると… いわゆる波の屈折に

今回は計算の都合上、密度の境界を画面の斜め方向に設定して、波を画面右にまっすぐ入射させました。

しかし、この結果を、密度の境界をまっすぐにして考えるとどうなるでしょう。すると下図のようになります。

入射角と屈折角の図。
入射角と屈折角
境界を基準に見ると、斜め(入射角)に入射してきた波が、別の角度(屈折角)になって進んでいくと見る事ができる。

上図は、密度の境界( = 異なる媒質の境界 )を水平にして見た図です。こうすると、斜めにある角度(入射角)で入射してきた波が、境界を跨いだ後は、別の角度(屈折角)になって進んでいくように見る事ができます。

これは、波の屈折を解説する際によく見る図ですね。

コード解説

それでは、このプログラムのコード内容について解説していきます。 このプログラムのコードは、プログラミング言語VCSSLで記述されています。

前提

このプログラムのコードは、「 力学アルゴリズムによる波のシミュレーション(面上の波) 」のコードの応用となっています。 波のシミュレーションアルゴリズムなどについては、今回は割愛しますので、詳しく知りたい方はそちらのプログラムをご参照下さい。

今回は、上記のプログラムから拡張した内容を中心に解説していきます。

コード全体

このプログラムのコード全体は少し長ですが、以下の通りです。

以上がコード全体です。ここからは、部分ごとに着目して見ていきます。

不均質な密度 → 各質点の質量を配列に

土台部分で「 力学アルゴリズムによる波のシミュレーション(面上の波) 」のコードから変わった点は、密度が不均質になった事です。

これによって、グローバル領域に、格子点(ポリゴン頂点)の質量を配列で用意しています。

mass というのが格子点の質量配列です。

mass の内容は、プログラム内で適当に設定しても良いのですが、それだと応用性に欠けます。せっかくですから、やはり条件は気軽に色々変えて遊びたいですね。

そこで、今回は密度分布を画像ファイルから読み込むようにしています。グローバル変数の DENSITY_FILE_PATH は、そのファイルパスを指定する変数です。

具体的には、画像のピクセルを格子点に対応させ、そのピクセルの明るさから、格子点の局所的な面密度の値を決めます。明るいほど軽く、暗いほど重いと見なします。

具体的には、明るさが最大( = 白色)の場合、その格子点の局所面密度は 0 になります。そして最小の場合( = 黒色)、局所密度はグローバル変数の DENSITY_SCALE の値になります。

なお、局所面密度を質点の質量に変換するには、領域面積をかけて、領域が含む格子点数で割ります。

初期化処理を行う onStart 関数

続いて、プログラムの準備的な処理 = 初期化処理 を行う onStart 関数です。

この関数は、プログラム開始後に一度だけ、フレームワークから自動でコールされる仕組みになっています。

この関数の内容は、基本的に土台のプログラムと同じです。違うのは最後の一行で loadDensityFile 関数を呼んでいる部分です。

loadDensityFile 関数は、画像ファイルを読み込んで、密度などを設定する処理をまとめた関数であり、今回のコードの中核部分です。

密度分布の読み込みと設定 - loadDensityFile関数

実際に、loadDensityFile 関数の中を見ていきましょう。

前半では、標準ライブラリである Graphics ライブラリの関数を用いて、画像ファイルを読み込んでピクセル色配列を取得しています。

その後、画像ファイルの X / Y 方向のピクセル数が、メッシュの X / Y 方向の格子点数と一致しているかを確認しています。

後半部分では、面密度の係数となるグローバル変数の DENSITY_SCALE を、面密度的の量から、質点の質量的な量に変換しています。これには面積をかけて、格子点数で割ります。

そしてそれを引数にして、getMassFromPixel関数で格子点の質量配列を取得し、グローバルの質量配列 mass に代入しています。getMassFromPixel はピクセル配列を質量配列に変換する処理をまとめた関数で、すぐ後に解説します。

最後に、setModelColorFromPixel 関数をコールして、画像ファイルと見た目が一致するよう、波のメッシュモデルに色を塗っています。この関数の内容についても後で解説します。

ピクセル配列から質量配列への変換 - getMassFromPixel関数

続いて、ピクセル配列から質量配列への変換を行う、getMassFromPixel関数の内容を見てみましょう。

引数の pixel はピクセル色配列です。次元については [ Y ][ X ][ R/G/B/A ] となっています。ここで R/G/B/A の部分は、0のとき赤(R)、1のとき緑(G)、2のとき青(B)、3のとき不透明度(A)の成分を意味します。

ただし、いちいち0が赤(R)で…などと考えるのも面倒なので、可読性を上げるために前半部で R, G, B を変数で定義しています。不透明度成分は今回は使いません。

続いて、X および Y についてのループの中身を見ていきましょう。このループで、各ピクセルの値から、各格子点の質量を求めて設定しています。

まず、3D格子点の [ i ][ j ] 番地に対応している、2D画像の中の座標を x2d と y2d に求めています。なぜこのような事をするかですが、簡単に言えば 2D は左上が座標原点で、3D は左下が座標原点になるので、Y軸を反転させる必要があるからです。

そして、3D格子点の [ i ][ j ] 番地に対応する 2D座標 [ x2d ][ y2d ] の地点にあるピクセルの明るさを、brightnessに求めています。値は白色のとき 1.0 になり、黒色のとき 0.0 になるようにしています

最後に、3D格子点の [ i ][ j ] 番地の質量を、1.0 - brightness に比例するように設定しています。なぜ 1.0 - にしているかというと、白の時に軽く、黒の時に重いほうが、一般的なイメージに合っているからです。

ピクセル配列でモデルに色を塗る - setModelColorFromPixel関数

続いて、密度分布を目で見えるようにするために、ピクセル配列から波のメッシュモデルに色を塗る setModelColorFromPixel関数です。

これも基本的に getMassFromPixel と同じような事をしていて、格子メッシュ上のポリゴンの位置に対応しているピクセル座標(Y軸反転に注意)を求めて、そこの色をポリゴンの色に設定しています。

ただし、モデルの中のポリゴンには、1次元のインデックスでアクセスする必要がありますので、2次元インデックスを1次元インデックスに落としています(indexという変数)。

モデル内のポリゴンの色を設定するには、標準ライブラリである Graphics3D ライブラリのsetModelPolygonColor関数を使用しています。一つ目の引数にモデルのID、二つ目にモデル内のポリゴンインデックス(1次元)、三つ目にポリゴンの色( int[4] )を指定します。

更新処理を行う onUpdate 関数

最後に、力学計算による変形などを行う、更新処理 の内容です。

ここもほぼ土台のプログラムそのままですが、質量が均質ではないので、配列になっている事だけが異なります。

(最後のループ、vertexVZ[i][j] += vertexFZ[i][j] / mass[i][j] * DT; )

あとの力の計算や境界処理などは同じです。このあたりの力学計算を詳しく追いたい方は、下記のプログラムをご参照下さい。

詳しいVCSSLのプログラミングガイド(無料)はこちらへ!

上記のコードはプログラミング言語VCSSLで記述されており、VCSSLのプログラミングガイドは下記で無料公開しています。 上記のコードを改造したい方や、新しいコードを書いてみたい方はぜひご活用ください!

ブラウザで読めるWeb版だけでなく、PDF版も無料で配布しています!

スタートアップガイド( プログラミングがはじめての方向け )
プログラミングの入門書に相当する内容です。プログラミングが初めての方はこちらがおすすめです。
即席ガイド( C系言語ユーザー向け )
C言語や C++ などのC系の言語を扱われている方が、即席でVCSSLを扱うための簡易ガイドです。
文法ガイド
VCSSLの文法や基本的な機能を淡々とまとめた、リファレンスマニュアル的な位置づけのガイドです。
GUI開発ガイド
ボタンや入力項目などのGUI部品が並ぶ、画面を備えたVCSSLプログラムを開発するためのガイドです。
2DCG開発ガイド
画面上や画像ファイルなどに、2次元的な描画を行うVCSSLプログラムを開発するためのガイドです。
3DCG開発ガイド
画面上や画像ファイルなどに、3次元的な描画を行うVCSSLプログラムを開発するためのガイドです。
標準ライブラリ 仕様書
コード内で呼び出される関数は、大半が標準ライブラリのものです。その詳細仕様を掲載しています。

ライセンス

このVCSSLコード( 拡張子が「.vcssl」のファイル )は実質的な著作権フリー(パブリックドメイン) である CC0 の状態で公開しています。 そのままでのご利用はもちろん、言語の種類を問わず、改造や流用などもご自由に行ってください。

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

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

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

[ 前へ | 目次 | 次へ ]
波の干渉(面上の円形波)のアニメーション表示

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

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

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

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

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

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

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

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

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

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

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

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

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

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

リニアングラフ3DのVCSSL用APIにカメラ制御関数を追加、回転アニメーションツールも同梱
2019年10月09日 - RINEARNでは10月9日にソフトウェアの最新版をリリースしました。VCSSLのAPI関数の追加や、リニアングラフ3Dのアニメーションツールの追加など行っています。その概要をお知らせします。

小型関数電卓 RINPn(旧称リニアンプロセッサー nano)の公式ページを開設
2019年10月02日 - 現在オープンソースで開発中の、「シンプル&コンパクト」を目指した小型プログラマブル関数電卓ソフト「 RINPn 」の公式ページが、RINEARNサイト内にオープンしました。その概要をお知らせします。

Vnanoの公式サイトがオープン、チュートリアルやAPI仕様書等も掲載
2019年08月07日 - オープンソースのアプリケーション組み込み用スクリプトエンジン「 Vnano 」の公式サイトを開設しました。チュートリアルや、スクリプトエンジンのAPI仕様書などが参照できます。その概要をお知らせします。

新着
3Dグラフを回転アニメーションさせるツール

3Dグラフを、Z軸まわりにゆっくりと回転アニメーションさせるツールです。全角度のグラフを、連番の画像ファイルに保存する事もできます。
2019年10月09日
[公式ガイドサンプル] ユーザーのGUI操作に対して処理を行う

「VCSSL GUI開発ガイド」内のサンプルコードです。ユーザーがGUIを操作した際に行う処理を実装します。
2019年07月28日
[公式ガイドサンプル] 各種GUIコンポーネントを画面上に配置する

「VCSSL GUI開発ガイド」内のサンプルコードです。色々な種類のGUI部品を画面上に配置します。
2019年07月28日
連番ファイルから3Dグラフをアニメーション描画するツール

フォルダ内の連番データファイルを読み込み、3Dグラフを高速で連続描画して、アニメーションさせるツールです。グラフを連番の画像ファイルに保存する事もできます。
2019年06月03日
連番ファイルから2Dグラフをアニメーション描画するツール

フォルダ内の連番データファイルを読み込み、2Dグラフを高速で連続描画して、アニメーションさせるツールです。グラフを連番の画像ファイルに保存する事もできます。
2019年05月24日
開発元Twitterアカウント