東京工芸大学 工学部  電子機械学科 2年 後期?

応用プログラミング 第9回
2017.11.21
藤木 文彦

http://fujiki.tv/t-kougei/ouyouprog/
fujiki.kougei@gmail.com  
■ 1 ■ 2 ■ 3 ■ 4 ■5 ■6       ??■ 11 ?■ 12? ??■ 13 ??■ 14 ??■ 15 ??■ 00 ??■ 00 ??■ 00

 先週は、いままでのまとめ課題をやりましたが、自力で作るのは難しいようで、まだ、1番しかできていないと言う人が多かったようです。
 そこで、
今週は新しい項目に入らず、先週のやり残しの問題をやってもらいます。

 
 10時位から、プログラムの作り方の解説をします。

 既にやった問題はやらなくて構いません。続きからやってください。その際、混乱しないように、

問題番号は 先週のままの 800番台
とします。 (本日は9回目ですが問題番号は 800番台です。)




【演習課題】


 【演習問題1】 


 以前のプログラムを参考に、再度次のようなグラフを書くプログラム、"Project801" を作成しなさい。
画面をプリントして提出し、プログラムcsファイル)をメールで提出しなさい。






 【演習問題2】 画面をプリントして提出し、プログラムcsファイル)をメールで提出しなさい。

 


Project802


 y=ax^2+bx+c


描画するプログラムを書きなさい。 座標軸も描くこと。

a,b,c は、画面から入力するものとします。(実数の範囲) 範囲は、原点からあまり離れないものと仮定して構いません。
範囲は、 -5≦x≦5 位とし、y軸の値は、それに対応した適切な範囲となるようにしなさい。原点が必ずしも中央である必要はなく、縦軸と横軸のスケールが違っていても構いません。





 【演習問題3】 画面をプリントして提出し、プログラムcsファイル)をメールで提出しなさい。

 


Projec803


 y=sin(x)  

を、 −4π<x<4π
の範囲で描くプログラムを書きなさい。
座標軸も描くこと。

軸をうまくとり、縦軸も ±1.5 くらいになるようにして、刻みを0.1にしなさい。




 【演習問題4】 画面をプリントして提出し、プログラムcsファイル)をメールで提出しなさい。

 

Project804

 ファイル一覧の中から画像ファイルを選択して入力し、それを表示するプログラムを作成しなさい。

 表示したファイルを、指定したファイルに別の名前で(ファイル名は画面から入力する)保存できるようにしなさい。



 1.マウス位置の取得・表示


 プロジェクト名: Project805
 csファイル名: ?MouseMove1


 こんなのを作ってください。




? public Form1()
{
InitializeComponent();
pictureBox1.MouseDown += new MouseEventHandler(fm_MouseDown);
pictureBox1.MouseMove += new MouseEventHandler(fm_MouseMove);
}
public void fm_MouseMove(Object sender, MouseEventArgs e)
{
Point p1 = new Point();
p1.X = e.X;
p1.Y = e.Y;
this.textBox1.Text = p1.X.ToString();
this.textBox2.Text = p1.Y.ToString();

}
public void fm_MouseDown(Object sender, MouseEventArgs e)
{
Point p2 = new Point();
p2.X = e.X;
p2.Y = e.Y;
this.textBox3.Text = p2.X.ToString();
this.textBox4.Text = p2.Y.ToString();

}

オブジェクト指向の考え方


 ここで、以下のようなことをやっている部分は何をしているのでしょうか?

? public Form1()
{
InitializeComponent();
pictureBox1.MouseDown += new MouseEventHandler(fm_MouseDown);
pictureBox1.MouseMove += new MouseEventHandler(fm_MouseMove);
}


 これは、「自分で作ったプログラムを、毎回調べられるイベントに登録する」という作業です。
 この作業を行わないと、プログラムを作っても、どこからも呼ばれないので、実行されません。

 なお、デザインウインドウで作ったものに関しては、イベントとして、自動的に登録されるので、自分で登録しなくても動くのです。しかし、ツールでボタンをダブルクリックするなどして作成されたものでないと、自動登録されません。
 自分で名前だけ書いても、自動登録されないので注意が必要です。



 初期化
  InitializeComponent();
?  自動的に追加されないものを、自分で追加
? ? ?pictureBox1.MouseDown += new MouseEventHandler(fm_MouseDown);
? ? ?pictureBox1.MouseMove += new MouseEventHandler(fm_MouseMove);

その後、
 無限ループ
   登録イベントが起こったかどうか、順次チェック
     あれば実行、なければスキップ

   全部イベントを調査したら、また、無限ループの最初に戻る。



   Intialize


【提出物1】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物1としなさい。

(表示される数値は、こことは違うものになっているように。)

 2.マウスの軌跡の描画と、クリックした場所の表示


 プロジェクト名: Project806
 csファイル名: ?MouseMove2


 次は、少し改造して、次のようなものを作ってください。
 マウスが動いた後に、ドットを描いていき、クリックしたところに大きな丸を付けます。



 ヒントは、以下を見てください。(スペース部分が ・・・ になっていますが、これは、何も入れない空白を見えるように書いただけです。)

 下のプログラムの .... は、空白を表すので、入力しない。





【提出物2】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物2としなさい。

(表示される数値は、こことは違うものになっているように。)


 3.タイマーを用いた、動くグラフィックス


 赤いボールが pictureBox 内を飛び回るプログラムを作成します。
 タイマーを用いて、黙っていても、少しずつ動き、画像枠の端まで来たら跳ね返ります。


 プロジェクト名: Project807
 csファイル名: ?MouseMove3

 タイマーの時間設定は、

 timer1.Interval=200;

としてありますが、これは、 「200ミリ秒に1回動かす」ということです。この値を小さくすると早く動きます。

 その他、今までには無かった 「Ball 型クラスの設定」など、いくつか新しい事項がありますが、以下のプログラムを参照して作成してください。




【明確なエラーが無いのに動かないときのチェック事項】
 MouseMove と MouseDown を間違えていないか。
 変数名の、 x1,y1,p1,p2 などのチェック
 ボタンを押して起動されるものの場合、自分で書いたのではなく、ボタンを押して書いたものでないとならない。
 自分で書いたのなら、ボタンを押してできたところにコピー。
 (現状では、 public でも private でも動く。あまりよくはないが。)
 自分で書いたものなら、 Form1 の検索イベントに、 += で追加されているか。


【注意】
 以下のプログラム入力時に、あらかじめ、
 ボタンをクリックして、その時に表示された button1_Click() の中にプログラムを組み込まないと、正常に動作しません。
 自分で、全部書いたのではだめです。
 これは、button1_Click というイベントが、毎回のループで探されるイベントに、登録されないからです。
 ボタンを押してプログラムを書いた時には自動的に登録されています。
 自分で作った時には、自分で登録しないといけません。他にも、自分で作ったものに関しては、

 += で、イベントハンドラに追加して、初めて意味があるものとなったはずです。

?namespace Project903
{


public partial class Form1 : Form
{
private Ball a1;
private int x1=10, y1=10;
public Form1()
{
InitializeComponent();
}

public void button1_Click(object sender, EventArgs e)
{
a1 = new Ball();
Point p = new Point(0, 0);
Color c = Color.Red;
Timer timer1 = new Timer();
timer1.Interval = 200;
timer1.Start();
pictureBox1.Paint += new PaintEventHandler(fm_Paint);
timer1.Tick += new EventHandler(timer1_Tick);
}
public void fm_Paint(Object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Point p = a1.Point;
Color c = Color.Red;
SolidBrush brush1 = new SolidBrush(c);
int x1 = p.X;
int y1 = p.Y;
g.FillEllipse(brush1, x1, y1, 10, 10);
}
public void timer1_Tick(Object sender,EventArgs e)
{Point p=a1.Point;
if(p.X<0||p.X>pictureBox1.ClientSize.Width-10) x1=-x1;
if(p.Y<0||p.Y>pictureBox1.ClientSize.Height-10) y1=-y1;
p.X=p.X+x1;
p.Y=p.Y+y1;
a1.Point=p;
pictureBox1.Invalidate();

}
private void pictureBox1_Click(object sender, EventArgs e)
{

}

private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
//  以下の部分を付け加えるのを忘れないように。付け加える場所に注意!
public partial class Ball
{
public Color Color;
public Point Point;
}



}

来週
【提出物3】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物3としなさい。






【演習課題】




 授業の説明に従って、"Project901" 以下の各プログラムを一緒に作成します。


 画面表示ができた人から、先週と同じようにして、画面をコピーして、Word画面に貼り付け、番号、氏名を最初に記入したものを、プリンタに出力し、提出しなさい。
 また、授業で作成したcsファイルを全てメールに添付して送りなさい。
 メールのタイトルは、”Project901" 等とします。


プリントのイメージ

 番号
 氏名



   画面コピーを貼り付け










?



参考プログラムリスト

---------------------------------------------------

namespace Project6033
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
textBox1.Text = "0";
textBox2.Text = "0";
}

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 xmid = width / 2;
int ymid = height / 2;
int step = 20;
int len = 3;
int ofs = 6;

Pen blackPen = new Pen(Color.Black, 2);
Pen bluePen = new Pen(Color.Blue, 2);
Pen redPen = new Pen(Color.Red, 2);

Font font1 = new Font("MS UI Gothic", 6);
Brush brush1 = new SolidBrush(Color.Red);
String str1;

g.DrawLine(blackPen, 0, ymid, width, ymid);
g.DrawLine(blackPen, xmid, 0, xmid, width);
for (int x = 0; x < xmid; x += step)
{
g.DrawLine(bluePen, xmid + x, ymid - len, xmid + x, ymid + len);
str1 = ((int)(x / step)).ToString();
g.DrawString(str1, font1, brush1, xmid + x, ymid + ofs);
g.DrawLine(bluePen, xmid - x, ymid - len, xmid - x, ymid + len);
str1 = (-(int)(x / step)).ToString();
g.DrawString(str1, font1, brush1, xmid - x, ymid + ofs);
}
for (int y = 0; y < ymid; y += step)
{
g.DrawLine(bluePen, xmid + len, ymid - y, xmid - len, ymid - y);
str1 = ((int)(y / step)).ToString();
g.DrawString(str1, font1, brush1, xmid + ofs, ymid - y);

g.DrawLine(bluePen, xmid - len, ymid + y, xmid + len, ymid + y);
str1 = (-(int)(y / step)).ToString();
g.DrawString(str1, font1, brush1, xmid + ofs, ymid + y);

}

Pen deepPinkPen = new Pen(Color.DeepPink, 2);
double a = double.Parse(textBox1.Text);
double b = double.Parse(textBox2.Text);
Point c=new Point();
c.X=xmid;
c.Y=ymid;
Point p0=new Point(),p1=new Point();

for (int x = -10; x <= 10; x++)
{
p0.X = c.X + (int)(x * step);
p0.Y = c.Y - (int)((x * a + b) * step);
p1.X = c.X + (int)((x + 1) * step);
p1.Y = c.Y - (int)(((x + 1) * a + b) * step);
g.DrawLine(deepPinkPen, p0.X, p0.Y, p1.X, p1.Y);
}


}
}
}
































--

ファイル入力
private void ファイル入力ToolStripMenuItem_Click(object sender, EventArgs e)