2010. 5.30.
石立 喬
Visual C++ 2010 Express の易しい使い方(9)
――― リサージュ波形を画面に表示させる ―――
リサージュ(Lissajous)波形は、電気技術者にとって、非常に馴染みの深い波形である。二つの周波数源の同期や位相を調整するのに便利で、オッシロスコープを学ぶ際に、必ずと言っても良いほど実験させられる。ここでは、新たにスクロールバーの使用方法を紹介する。
リサージュ(Lissajous)波形とは
リサージュ図形、リサージュ曲線などとも呼ばれることがある。フランスの物理学者Jules Antoine Lissajousが、1857年に発表したと言われ、その名前が付けられている。これは、直交するX軸とY軸のそれぞれに異なる正弦波を加えて得られる平面図形のことで、それぞれの正弦波の周波数、位相の違いなどによって、多様な曲線が描かれる。
リサージュ波形による周波数の測定(設定)
オッシロスコープで、基準波を横軸に、被測定波を縦軸に入力すると、リサージュ図形が得られる。上下に描かれた山の数と、左右に描かれた山の数が、基準波と被測定波の周波数比となって現れるので、周波数の測定ができる。リサージュ波形を見ながら被測定波の周波数を調整することにより、周波数を設定することもできる。
リサージュ波形による位相の測定(設定)
同様に、基準波を横軸に、それと同じ周波数の被測定波を縦軸に入力し、縦横が同振幅に表示されるように調節すると、二つの波の位相関係により、直線、円、楕円のリサージュ図形が得られる。位相差を0またはπ(逆相)にすると直線になり、2/πまたは-2/πにすると円になる。この原理により、位相の測定または設定ができる。
パソコン上でのリサージュ波形の作成方法
画面上の座標を(x,y)としたとき、
横軸入力波形 x = A・sin ωt
縦軸入力波形 y = B・sin(ωt + φ)
で描いた図形がリサージュ波形である。
ただし、ここで紹介する例では、A = B とし、tは時間で 0秒から1秒までとする。ωは角周波数で、ω = 2πfの関係がある。fは周波数で、1 Hzから10Hzまでとする。φは縦軸入力波形に付加する位相シフトで、-πラジアンからπラジアンまで変化させる。
プログラムの使用方法
1) プログラムを起動させると、横軸周波数 = 2Hz、縦軸周波数 = 3Hz、位相 = 0の初期設定になっており、その条件でのリサージュ波形が描かれる。
2) 横軸周波数と縦軸周波数は、コンボボックスによって設定可能で、変更すると、直ちにリサージュ波形が描かれる。
3) 縦軸周波数の位相は、スクロールバーで、0.01π単位で設定でき、これも変更と同時にリサージュ波形の描画が行われる。
4) 「ゆっくり」ボタンをクリックすると、その時の設定条件で、各種波形の再描画がゆっくり行われる。
コンボボックスの設定
すでに説明した方法に従い、二個のコンボボックスを設ける。「プロパティ」ウインドウから開いた「文字列コレクション
エディター」で、二個のコンボボックス共に図1のように設定する。
図1 コンボボックスで周波数を決めるための文字列
水平スクロールバーの設定
「ツールボックス」ウインドウの「すべてのWindowsフォーム」の中から、「HScrollBar」をクリックして、フォーム上の希望する場所で、再びクリックする。配置されたスクロールバーを右クリックし、「プロパティ」ウインドウで、図1のように設定する(変更したのは「Maximum」のみで、その他はデフォルトのまま)。
スクロールバーで数値を設定できるのは正の整数に限られ、使用できる最大値は、Maximum
+ 1 - LargeChange の関係がある。「Maximum」を「209」に設定したことは、使用できる最大値が「200」であることを意味する。
図2 水平スクロールバーの「プロパティ」ウインドウで、「Maximum」を変更する。
プログラム
1) 時間待ちをさせる Thread::Sleep(10); を使用するために、System::Threading を名前空間として追加する。Sleepのカッコ内は、msecで指定する。
2)コンボボックスでは、周波数を1Hzから10Hzまで、1Hz刻みで設定できる。これを、SelectedIndexの0から11に対応させているので、周波数は、SelectedIndex+1で得られる。
using namespace System::Threading;
Boolean slow_flag;
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
comboBox1->SelectedIndex=1; //横軸入力波形の周波数を2Hzに初期設定
comboBox2->SelectedIndex=2; //縦軸入力波形の周波数を3Hzに初期設定
hScrollBar1->Value=100; //縦軸位相を0に初期設定
slow_flag=false;
}
private: System::Void Form1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^
e) {
Graphics^ g=e->Graphics;
int X0=10,Y0=50; //横軸入力波形用
int X1=190,Y1=50; //縦軸入力波形用
int X2=20,Y2=230; //リサージュ波形用
int t,x1,x2,y1,y2;
double time,x,y,old_x,old_y;
int freq_x=comboBox1->SelectedIndex+1;
int freq_y=comboBox2->SelectedIndex+1;
double omega_x=2.0*Math::PI*freq_x;
double omega_y=2.0*Math::PI*freq_y;
double phi1=(hScrollBar1->Value-100)/100.0;
double phi=phi1*Math::PI;
//位相シフトを表示する
if(phi1==0.0) label4->Text=" 0";
else if(phi1==1.0) label4->Text=" π";
else if(phi1==-1.0) label4->Text=" -π";
else label4->Text=String::Format("{0}π",phi1);
//グラフの背景を黒にする
g->FillRectangle(Brushes::Black,X0,Y0,160,160);
g->FillRectangle(Brushes::Black,X1,Y1,160,160);
g->FillRectangle(Brushes::Black,X2,Y2,320,320);
//グラフに目盛を入れる
for(int i=0;i<=10;i++){
//横軸入力波形用
g->DrawLine(Pens::LightGray,X0+16*i,Y0,X0+16*i,Y0+160);
g->DrawLine(Pens::LightGray,X0,Y0+16*i,X0+160,Y0+16*i);
//縦軸入力波形用
g->DrawLine(Pens::LightGray,X1+16*i,Y1,X1+16*i,Y1+160);
g->DrawLine(Pens::LightGray,X1,Y1+16*i,X1+160,Y1+16*i);
//リサージュ波形用
g->DrawLine(Pens::LightGray,X2+32*i,Y2,X2+32*i,Y2+320);
g->DrawLine(Pens::LightGray,X2,Y2+32*i,X2+320,Y2+32*i);
}
//各種波形を描く
for(t=0;t<=320;t++){
time=t/(320.0);
x=Math::Sin(omega_x*time);
y=Math::Sin(omega_y*time+phi);
if(t==0){
x_old=x;
y_old=y;
}
else{
x1=0.5*(t-1);
x2=0.5*t;
y1=80-64*old_x;
y2=80-64*x;
g->DrawLine(Pens::LightGreen,X0+x1,Y0+y1,X0+x2,Y0+y2);
//横軸入力波形
y1=80-64*old_y;
y2=80-64*y;
g->DrawLine(Pens::LightGreen,X1+x1,Y1+y1,X1+x2,Y1+y2);
//縦軸入力波形
x1=160-128*old_x;
x2=160-128*x;
y1=160-128*old_y;
y2=160-128*y;
g->DrawLine(Pens::LightGreen,X2+x1,Y2+y1,X2+x2,Y2+y2);
//リサージュ波形
x_old=x;
y_old=y;
}
if(slow_flag) Thread::Sleep(10); //10msecだけ待つ
}
slow_flag=false;
}
//「横軸周波数」が変更になった
private: System::Void comboBox1_SelectedIndexChanged(System::Object^ sender,System::EventArgs^
e) {
Invalidate();
}
//「縦軸周波数」が変更になった
private: System::Void comboBox2_SelectedIndexChanged(System::Object^ sender,System::EventArgs^
e) {
Invalidate();
}
//「縦軸位相」が変更になった
private: System::Void hScrollBar1_ValueChanged(System::Object^ sender,System::EventArgs^
e) {
Invalidate();
}
//「ゆっくり」ボタンが押された
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^
e) {
slow_flag=true;
Invalidate();
}
得られた画面
図3は、コンボボックスにより、横軸周波数を3Hzに、縦軸周波数を5Hzに設定し、スクロールバーで縦軸位相を0.51πに設定した場合のリサージュ波形を示す。上の山が5個、横の山が3個ある。
図3 リサージュ波形の例
「Visual C++ の勉強部屋」(目次)へ