|
Jittaさん、自分の説明がしきれていなかったようで申し訳ございません。
なので、自分の行っていきたいと思っている内容を説明させていただきます。
自分は現在、マウスの左ボタンをドラッグしている間、円と直線を描画し、軌跡を表現したいと思っています。 ですが、皆さまのご指摘で 1.ドラッグをしている間その座標をリストに格納し続けていると動作が遅くなると言う問題 と 2.軌跡を描きつづけていると画面が見づらくなってしまうと言う問題 に気が付きました。
なので、リストの要素が一定数に達したら要素[0]を削除する。 そして、その不要な要素を削除したリストを元に円と直線を描画する。 こうすることで、上記の二つの問題が解決できると思いました。
実際に68775でのanさんのご指摘と自分でプログラムを組んでみました。 結果、1の問題は解決できました。 しかし、2の問題において円が問題なく削除しながら円をリストの要素分描画できるのですが、 直線が一本しか描くことができませんでした。
自分としてはそれは描画先であるbmp2を描画されるたびに初期化しているためだと考えました。 なので、円とおなじく直線の描画するdrawlineをforeachでリストの要素数分だけ処理を回すように修正してみました。
foreach (Point p in Move_MousePoints)//リストに格納されている要素数すべて繰り返す { //マウスの位置に11x11の四角を赤色で描く g.DrawRectangle(Pens.Red, p.X - 6, p.Y - 6, 11, 11);//円の中心を得るために11×11なので //先に描いた四角に外接する楕円を黒で描く //6ずつ描画する座標をずらす g.DrawEllipse(Pens.Black, p.X - 6, p.Y - 6, 11, 11);//マウスの座標を円で描画 g.DrawLine(pen, before_p.X, before_p.Y, p.X, p.Y);//マウスの動いた軌跡を描画 }
が、実行結果を見ると円と円の間直線は描けているのですが、 どうもbefore_p.Xとbefore_p.Yから要素分だけp.Xとp.Yで複数直線が描かれてしまって思うようにはなりませんでした。
他にもDrawLines(Pen pen, Point[] points);なども試してみたのですがうまくいかず、 友人らにも聞いても解決法が見つからなかったので、他によい方法はないでしょうか?
以下にDrawLinesを組みこんでみたプログラムのソースコードを記述します。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms;
namespace WindowsFormsApplication1 { public partial class Form1 : Form { int Drag_Flag = 0; int i=1; private int max_point = 6; private int max_movepoint = 6; private List<Point> MousePoints; // 取得したマウス座標をすべて格納するリスト private List<Point> Move_MousePoints; //円や直線を描画先のマウス座標を格納するリスト System.Drawing.Point before_p; System.Drawing.Point sp; System.Drawing.Point cp; System.Drawing.Point dp; Point[] Pt = new Point[6]; Bitmap bmp1 = (Bitmap)System.Drawing.Image.FromFile(@"C:\\Users\\yoto\\Desktop\\実験画像フォルダ\\WhiteBack.png"); public Form1() { InitializeComponent(); MousePoints = new List<Point>(); Move_MousePoints = new List<Point>(); pictureBox1.MouseDown += new MouseEventHandler(pictureBox1_MouseDown); pictureBox1.MouseMove += new MouseEventHandler(pictureBox1_MouseMove); //PictureBox1に表示する pictureBox1.Image = bmp1; }
//マウスの左ボタンを押したイベント(指先を検出した時) private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { //左ボタンを押すと、タイマースタートかつその時のマウス座標取得 if (e.Button == MouseButtons.Left) { timer1.Enabled = true; Get_MousePoint(); Drag_Flag = 0; } //右ボタンを押すと、実行結果確認のためにテキストボックスに表示 if (e.Button == MouseButtons.Right) { foreach (Point p in MousePoints)//リストに格納されている要素数すべて繰り返す { textBox1.AppendText("座標" + p + "\r\n"); } foreach (Point p in Move_MousePoints) { textBox2.AppendText("座標" + p + "\r\n"); } } }
//マウスを動かした時のイベント(ジェスチャーを始めた時) private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { //ドラッグ時の処理(ドラッグフラグを立てる) if (e.Button == MouseButtons.Left) { this.Text = "追跡スタート"; Drag_Flag = 1; }
else//ドラッグしていないときは動作しない(ドラッグフラグを下げる、立てない) { this.Text = "追跡ストップ"; Drag_Flag = 0; } }
//サンプリング間隔(1s)ごとに起きるイベント public void timer1_Tick_1(object sender, EventArgs e) { if (Drag_Flag == 1)//サンプリング間隔 かつ ドラッグしている時 { Chase_MousePoint();//マウス座標に円と軌跡を描く }
else if (Drag_Flag == 0)//サンプリング間隔 かつ ドラッグしてない時 { Get_MousePoint();//マウス座標を取得 }
List_Check();//古いリストの要素を削除する }
private void Get_MousePoint()//マウスの座標を取得 { // 画像座標でのマウスポインタの位置を取得する sp = System.Windows.Forms.Cursor.Position; //画面座標をクライアント座標(ピクチャボックス座標)に変換する cp = pictureBox1.PointToClient(sp);
if (cp.X > 0 && cp.Y > 0) { if (cp.X < 600 && cp.Y < 400) { dp = cp; MousePoints.Add(new Point(dp.X, dp.Y)); Pt[0]=dp; } } }
private void Chase_MousePoint()//円と軌跡を描く { Bitmap bmp2 = new Bitmap(bmp1); //描画先をbmp2に変更した。実行毎にbmp1から元画像を取得し、bmp2を初期化 Graphics g = Graphics.FromImage(bmp2);
// 画像座標でのマウスポインタの位置を取得する sp = System.Windows.Forms.Cursor.Position; //画面座標をクライアント座標(ピクチャボックス座標)に変換する cp = pictureBox1.PointToClient(sp);
if (cp.X > 0 && cp.Y > 0) { if (cp.X < 600 && cp.Y < 400) { dp = cp; Move_MousePoints.Add(new Point(dp.X, dp.Y)); MousePoints.Add(new Point(dp.X, dp.Y)); //before_p = cp; Pt[i] = dp; i++; } } Pen pen = new Pen(Color.DarkRed); pen.Width = 5; pen.EndCap = LineCap.ArrowAnchor;//終点に矢印をつける foreach (Point p in Move_MousePoints)//リストに格納されている要素数すべて繰り返す { //マウスの位置に11x11の四角を赤色で描く g.DrawRectangle(Pens.Red, p.X - 6, p.Y - 6, 11, 11);//円の中心を得るために11×11なので //先に描いた四角に外接する楕円を黒で描く //6ずつ描画する座標をずらす g.DrawEllipse(Pens.Black, p.X - 6, p.Y - 6, 11, 11);//マウスの座標を円で描画 //g.DrawLine(pen, before_p.X, before_p.Y, dp.X, dp.Y);//マウスの動いた軌跡を描画 }
g.DrawLines(pen, Pt);
/*if (cp.X > 0 && cp.Y > 0) { if (cp.X < 600 && cp.Y < 400) { before_p = cp; } }*/
//リソースを解放する g.Dispose(); //PictureBox1に表示する pictureBox1.Image = bmp2; }
private void List_Check()//古いリストの要素を削除する { // マウス座標を格納する最大数以上なら先頭の座標をリストから削除 if (MousePoints.Count >= max_point) { MousePoints.RemoveAt(0); }
if (Move_MousePoints.Count >= max_movepoint) { Move_MousePoints.RemoveAt(0); } } } }
よろしくおねがいします
|