東京工芸大学 工学部 電子機械学科 2年 後期 応用プログラミング 第5回
|
1.直線、曲線の描画。 |
最初は、2次曲線を描くプログラムを作成します。
少しずつ順を追って、形を整えていきます。
まず、 Project501 を作成し、線を描く練習をします。
2.出来上がりイメージ |
初めに今日の演習で作るプログラムの内容と、完成(間近の)イメージを掲げておきます。
y=ax^2 のグラフを描きます。
を y=x^2 と書きます。
まず最初に下のような図面を書いてみましょう。
まだそれらしく見えませんが、だんだん近づけていきます。
3.画面の作成 |
もう、1つ1つの配置を順を追って説明する必要はありませんね。
とりあえず、次のような状態になるくらいまで自力で配置しましょう。
ただし、後から、 x^2(xの2乗の意味)の前の部分に、あとから、数字入力BOXを入れますので、少し間をあけておいてください。(早まって、テキストボックスを入れないように。)
「^」印は、キーボード右上の「BackSpace」の左の「¥」の左にあるはずです。
日本語文字の 「あ」が出てしまいますが、「F9」で、「a」になるはずです。
図を描く場所は、 PictureBox1 ですが、ここは、他の部分と区別しやすいように、背景色を変えましょう。
BackgroundColor で、上の「Web」を選び、MistyRose を選びます(自分の気に入った色でも構いませんが、あまり濃い色にすると、これから描く線が見えにくくなります。)
それから、あらかじめ、周りに枠を書いておいたほうがわかりやすいので、BorderStyle を FixedSingle にしておきます。
4.決められた値の中から選択する NumericUpDown |
次に、 y=ax^2
の、a の部分に数値を入力する枠を作ります。
今までのように、textBox でもよいのですが、今回は、値の範囲を、0〜10までの整数に限る、ということにしたいので、次のような、あらかじめ入力する数値を決めておきます。
ツールボックスから、
NumericUpDown を選んで下記の位置に挿入します。
挿入後、次のように、プロパティを設定します。
Minimun 0
Maximum 10
Value 1
としておきます。これは、数値の範囲を0〜10、までの整数に限定するもので、何もしなければ初期値に1を入れるようにします。
下の例は、1,5,10を入力した例です。
5.グラフを描画する |
上のような描画をするためのプログラムは、次のように記述します。
「描画」ボタンを押したときの処理に、次のように記述します。
private void button1_Click(object sender, EventArgs e)
{
Graphics g = this.pictureBox1.CreateGraphics();
int width = this.pictureBox1.Width - 1;
int height = this.pictureBox1.Height - 1;
int x0,y0,x1,y1;
int a = (int)numericUpDown1.Value;
Pen bluePen = new Pen(Color.Blue, 2);
for (int i = 0; i < 10; i++)
{
x0 = i * 50;
y0 = (i * i)*a;
x1 = (i + 1) * 50;
y1 = ((i + 1) * (i + 1))*a;
g.DrawLine(bluePen, x0, y0, x1, y1);
}
}
6.y軸を逆転表示する方法 height から y を引く |
ところで、上の図ですが、 xの2乗のグラフが下に向かっているのは見にくいでしょう。
できれば、普通のグラフのように、上に向かっていたほうがわかりやすいですよね。
下の図の赤線のように引けたほうがよいでしょう。
そのためには、プログラムの一部を改造します。
次のように、プログラムの一部に追加行を入れます。(どの行を入れたかは、自分で考えてください。)
コンピュータ上では、y軸が下向きに+になっていますので、これを逆転させるために、枠の縦の大きさから、データを引いたものを、yの値としています。
この方法は、グラフィックではよく使用される方法です。
【演習問題1】 |
Project501 を作成し、完成した画面を印刷して提出しなさい。
また、Project501.cs をメールに添付して送ってください。
7.横の倍率を変えて、より2次曲線らしく描く |
Project502 として、新規プロジェクトを始めます。
上記の例を参考に、より2時曲線らしく描くために、横の倍率を選べるようにします。
そのほか、いろいろな工夫をして、次のような表示が出るようにします。
いくつも新しく付け加えるところや、プログラムの改変などもありますので、よく読んでから作成してください。
プログラムは、次のような点が、追加、改変されています。
●xが1増えるたびに、右に何ドット進むかを設定する、x軸の倍率を、scale という変数とした。
●描画回数の上限を、10回ではなく、画面からはみ出すまでとするために、for文ではなく、 while 文を用い、x、yの両方が pictureBox
内にあるときに描画する。(どちらかがはみ出したら終了)
このとき、回数のカウントを増やすための、 x++ を入れないと無限ループになり、終了しなくなるので注意。
●描画した線の端点がわかるように、赤の小さな丸を描くようにした。
●画面をクリアするボタンを追加し、その動作として、背景色でクリアするという処理をいれた。
プログラムミスがあると、終了できなくなります。
このような時は、次のように、「デバッグの停止」を選ぶと止まるはずです。
Project502 は、まだ完成ではありません。次に続きます。
8.上下を入れ替え、座標を表示する。 |
上の表示では、y軸の + の向きが下向きになっていますので、これを逆転させます。
さらに、座標がわかるように、座標を文字として、picturebox1 に表示させます。
表示は次のようになります。
この画面ができたら、Project502 は、完成です。
プログラムは、上のプログラムを少し変えます。下記を参照してください。
【演習問題2】 |
Project502 を作成し、完成した画面を印刷して提出しなさい。
また、Project502.cs をメールに添付して送ってください。
9.座標軸を真ん中に書く。 |
Project503 として、次の画面表示を出すプログラムを作成します。
このプログラムは、今までの知識を組み合わせて、少しだけ計算部分を作ることでできるはずですから、ヒントなしで自分で作ってみてください。
第3段階で一応完成ですが、座標の計算をどうするか、考え方がなかなか面倒なので、時間内でできるところまでやってみましょう。
【第1段階】
(参考:部分的に塗りつぶしてありますから、見えない部分は自分で考えてください。)
【第2段階】
【第3段階】
【演習問題3】 |
Project503 を自力で完成させなさい。
10.sin cos 曲線の描画、位置の変更 配列に与えられたデータを画面に表示する |
Project504 として、Sin Cos のグラフの描画をします。
また、配列にあらかじめデータをいれ、それをプロットすることもしてみます。
以下の画面で、赤い点はこの配列データをかいたものです。
以下、順を追って授業中に説明し、最終的に次のような画面を作っていきます。
以下のプログラムをそのまま入れると、問題なく動いてしまいますが、
実際には、途中で何段階か問題点を改良して行かなければなりません。
【演習問題4】 |
sin、cosグラフを描く、新しいプロジェクト、 Project504 を作成しなさい。配列に与えた点を描画する部分は入れても入れなくても良い。
【応用演習問題5】 |
以下のように、 y=(1/4)x^2
を描画するプログラム、
Project505
を作りなさい。
xの刻み幅は、0.1 程度とする。
【応用演習問題6】 |
問題4にあるような、 y=sin x
のグラフを、 −π≦x≦π
の範囲で書きなさい。その際、x軸、y軸と、目盛を入れなさい。
以下のプログラムはあくまで参考とし、うまく動かないときに見るにとどめてください。
そのままコピペせず、
授業でやる順に自分で入力してください。
Project502 ソース
private void button1_Click(object sender, EventArgs e)
{
Graphics g = this.pictureBox1.CreateGraphics();
int width = this.pictureBox1.Width - 1;
int height = this.pictureBox1.Height - 1;
int x0=0, y0=0, x1=0, y1=0;
int a = (int)numericUpDown1.Value;
int scale = (int)numericUpDown2.Value;
Pen bluePen = new Pen(Color.Blue, 2);
Pen redPen = new Pen(Color.Red, 2);
int x = 0;
while( x1<width && y1<height )
{
x0 = x * scale;
y0 = (x * x) * a;
x1 = (x + 1) * scale;
y1 = ((x + 1) * (x + 1)) * a;
g.DrawEllipse(redPen, x1, y1, 2, 2);
g.DrawLine(bluePen, x0, y0, x1, y1);
x++;
}
}
private void button3_Click(object sender, EventArgs e)
{
Graphics g = this.pictureBox1.CreateGraphics();
Color bgcolor1 = pictureBox1.BackColor;
g.Clear(bgcolor1);
}
-------------------------------
Project502(改訂) ソース
private void button1_Click(object sender, EventArgs e)
{
Graphics g = this.pictureBox1.CreateGraphics();
int width = this.pictureBox1.Width - 1;
int height = this.pictureBox1.Height - 1;
int x0 = 0, y0 = 0, x1 = 0, y1 = 0, y2 = 0;
int a = (int)numericUpDown1.Value;
int scale = (int)numericUpDown2.Value;
Pen bluePen = new Pen(Color.Blue, 2);
Pen redPen = new Pen(Color.Red, 2);
int x = 0;
while( x1<width && y1<height )
{
x0 = x * scale;
y0 = (x * x) * a;
x1 = (x + 1) * scale;
y1 = y2 = ((x + 1) * (x + 1)) * a;
y0 = height - y0;
y1 = height - y1;
g.DrawEllipse(redPen, x1, y1, 2, 2);
g.DrawLine(bluePen, x0, y0, x1, y1);
Font font1 = new Font("MS UI Gothic",12);
Brush brush1 = new SolidBrush(Color.Black);
String str1 = "( "+(x+1).ToString()+" , "+y2.ToString()+" )"; //変数名に注意
g.DrawString(str1,font1,brush1,x1+20,y1);
x++;
}
}
Project503
private void button1_Click(object sender, EventArgs e) { double pi=3.1416; double x, y; double xrad; int hight2; int x0,y0,x1,y1; int xmin = 0, xmax = 360, xstep = 1; double[] siny = new double[361]; Graphics g = this.pictureBox1.CreateGraphics(); int width = this.pictureBox1.Width - 1; int height = this.pictureBox1.Height - 1; g.DrawRectangle(Pens.Black, 0, 0, width, height); Pen bluePen = new Pen(Color.Blue, 2); Pen redPen = new Pen(Color.Red, 2); Pen greenPen = new Pen(Color.Green, 2); for (int i = 0; i < 20; i++) { x0=i*10; y0=(i*i); x1=(i+1)*10; y1=((i+1)*(i+1)); g.DrawLine(bluePen,x0,y0,x1,y1); // y0 = height - y0; y1 = height - y1; g.DrawLine(redPen, x0, y0, x1, y1); } // hight2 = height / 2; //y1 = 0; y1 = hight2; x1 = 0; for (int i = xmin; i < xmax; i++) { y0 = y1; x0 = x1; x1 = i; xrad = i * pi / 180; y1 = (int)(Math.Sin(xrad) * 100); y1 = hight2 - y1; g.DrawLine(greenPen, x0, y0, x1, y1); } // int[] data_a; data_a = new int[11]{ 0,11,20,29,41,53,58,72,80,91,99}; Pen deepPinkPen = new Pen(Color.DeepPink, 2); for (int i = 0; i < 11; i++) { g.DrawEllipse(deepPinkPen, i * 10, data_a[i], 5, 5); } } |