No.2です、前回の回答で、色濃度変換関数が変でしたね。sin関数の範囲を勘違いしたものになっていました。あと、振幅の減衰も入ってなかった。
まあ、物理学的な細かい計算は省いて、単純なsin関数で色を決めて、同心円を描くだけでも、雰囲気は出せそうです。
ということでJava Appletで作ってみました。
減衰を入れてないのと、drawOvalの精度の問題で水面と云うより、なんだか電波の発信のような感じになってしまったけど、絵を描くところだけ抜粋すると以下のようなプログラムです。
MATLABはやったことないので、Cも今使ってないので忘れたし、計算部分をコメントでなんとか理解して貰えれば、画像出力部分を使用言語に合わせて書き換えれば、なんとかなるかと思います。
あと、定数項を適宜変更すると、もうちょっと雰囲気が出るかもです。
// クラス内フィールドで保持変数
private int img_width = 200; // 画像横幅
private int img_height = 200;; // 画像縦幅
private int x0 = 100; // 中心位置x
private int y0 = 100; // 中心位置y
private double rmax= 100; // 最大半径
private double rf = 50; // 波の水平方向 1周期の距離 dot
private double tf = 2; // 中心での波の 1周期に要する時間 sec
/** @param t : 時刻tでの画像を得る */
Image calcImage( double t ){
Image off_img = createImage(img_width,img_height);
Graphics dt_img = off_img.getGraphics();
double tht,k;
int r,g,b,x,y,rr;
double pai_rad = 2* Math.PI ; // 1周期=2π
for ( int i = 2; i< rmax; i+=2 ){
tht = pai_rad * ( (t/tf) - ((double)i/rf) );
// t/tf で中心位置の位相、 i/rf で半径r位置の位相、離れたところは位相が遅れるので引き算
k = ( Math.sin( tht ) +1.0 ) * 0.5;
//sin関数を 0~1に変換
g = (int)( 255.0 * k); // green
if( g>255 ){ g=255; }else if( g<0 ){ g=0; }
r = 125; // red
b = 255; // blue
dt_img.setColor(new Color( r, g, b));
// ペン色設定 青紫~薄水色で変化
x = x0-i;
y = y0-i;
rr= i*2;
dt_img.drawOval( x,y, rr,rr);
// javaでは外接四角形を指定して内接円を描くので
}
return off_img;
}
お礼
重ね重ねご回答ありがとうございます。 Javaはよく知らないので理解するのに手間取ってしまいました。 ネット上にいくつかうまく作っているのを見ましたが、それらは波動方程式を差分法で解いているような感じなんでしょうか?? よくはわからないのですが。 いろいろ調べてみてうまくできるようにがんばってみます。 ありがとうございます。