2011-12-09 25 views
1

描画された線をマウスでつかんで移動しようとしています。マウスで描画された線を移動する

ラインはすでにGraphics.DrawLine(Pen P, Point A, Point B)で描かれています。

ラインを作成し、フォーム上に描画して全く問題があります。

私が試してみた:

  • GraphicsPathに行を追加する - これは、偶数ラインOnPaintを描画しません。 MouseEventArgs e.Locationは、いくつかの基本的な代数とのライン上にある場合は

  • はチェック(私は今のように捨ててきた計算)

だからそれを要約すると:私はラインをつかむと、どこかでそれをドラッグしたいですe.Locationがライン上にあるかどうかを確認することすらできません。どうすればいいですか?

EDIT:これは、GraphicsPathを使用しているときのコードの表示方法です。私はGraphicsPathを使用しない場合は

は私が持っている:drawingShapes方法で

if (s.thisShape == ShapeType.Line) { 
    g.DrawLine(pen, s.p1, s.p2); 
} else { ... }` 

。ユーザーコントロールクラス:drawStuffから

private void drawStuff_MouseDown(object sender, MouseEventArgs e) 
{ 
    pointRegion = e.Location; 
    for (int i = 0; i < Shapes.Count; i++) 
    { 
    if (Shapes[i].Region.IsVisible(pointRegion)) 
    { 
     isDragging = true; 
     count = i; 
     break; 
    } 
    } 
} 

private void drawStuff_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (isDragging) 
    { 
    Shapes[count].moveWithDiff(pointRegion, e.Location); 
    pointRegion = e.Location; 
    Refresh(); 
    } 
} 

private void drawStuff_MouseUp(object sender, MouseEventArgs e) 
{ 
    isDragging = false; 
    Refresh(); 
} 

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 
    drawShapes(e.Graphics); 
} 

private void drawShapes(Graphics g) 
{ 
    temporaryPen = pennaLeft; 
    foreach (Shape s in Shapes) 
    { 
    g.FillRegion(temporaryPen, s.Region); 
    } 
} 

形状から:ユーザーコントロールクラス:drawingShapesでのif文

public void moveWithDiff(Point pr, Point mp) 
{ 
    Point p = new Point(); 
    if (this.thisShape == ShapeType.Line) 
    { 
    p.X = mp.X - pr.X; 
    p.Y = mp.Y - pr.Y; 
    this.p1.X += p.X; 
    this.p1.Y += p.Y; 
    this.p2.X += p.X; 
    this.p2.Y += p.Y; 
    } 
    RefreshPath(); 
} 

private void RefreshPath() 
{ 
    gPath = new GraphicsPath(); 
    switch (thisShape) 
    { 
    case ShapeType.Line: 
     gPath.AddLine(this.p1, this.p2); 
     break; 
    } 
    this.Region = new Region(gPath); 
} 

今これは偶数ラインを描画しません、しかし、とは(言いました)それは完全に引き寄せますが、私はそれをどこかにドラッグできません。

+0

@HansPassant私は、私が望むもので十分であるという質問を編集しました。これはRectangleやEllipseなどの他の図形と完全に機能しますが、線を移動するだけでなく、描画することもできます。 – NJS

答えて

6

基本的なことから始めて、画面に線を引いてみましょう。

public class MyLine 
{ 
    public Pen pen { get; set; } 
    public Point Start { get; set; } 
    public Point End { get; set; } 

    public MyLine(Pen p, Point p1, Point p2) 
    { 
     pen = p; 
     Start = p1; 
     End = p2; 
    } 

    public float slope 
    { 
     get 
     { 
      return (((float)End.Y - (float)Start.Y)/((float)End.X - (float)Start.X)); 
     } 
    } 
    public float YIntercept 
    { 
     get 
     { 
      return Start.Y - slope*Start.X; 
     } 
    } 

    public bool IsPointOnLine(Point p, int cushion) 
    { 
     float temp = (slope * p.X + YIntercept); 
     if (temp >= (p.Y-cushion) && temp <=(p.Y+cushion)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

このクラスは、私たちの生活が楽になりますいくつかのヘルパー関数が用意されています。私は、このプロセスのために、私は私に利用可能たい機能の一部を処理するカスタムクラスを作成しました。勾配とY切片を返すプロパティがあるので、特定のポイントがライン上にあるかどうかを判断できます。次にポイントとクッションをとるヘルパー関数IsPointOnLine()を提供します。このクッションは、ユーザーがラインを閉じるのに十分に近くをクリックするだけで、それを真に戻すことができます。

次の私はラインをインスタンス化し、フォームのPaintイベントでそれを描画するつもりです:

MyLine m; 

private void Form1_Load(object sender, EventArgs e) 
{ 
    m= new MyLine(Pens.Black, new Point(20, 20), new Point(40, 40)); 
} 



private void Form1_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.DrawLine(m.pen, m.Start, m.End);  
} 

今、あなたはあなたのアプリケーションを実行し、20,20から40に行くラインを見ることができるはずです、 40を画面に表示します。

私はマウスとマウスのやりとりを処理したいので、MouseDownでは、クリックポイントがラインと交差しているかどうか、フラグがセットされていてエンドポイントからデルタを保持しているかどうかを確認します。 MouseMoveイベントでは、行がクリックされたが解放されず、座標が適切にリセットされているかどうかを確認します。 MouseUpイベントでは、我々は、単純な私達のフラグをリセットします。

Point deltaStart; 
Point deltaEnd; 
bool dragging = false; 

private void Form1_MouseDown(object sender, MouseEventArgs e) 
{ 

    if (e.Button == System.Windows.Forms.MouseButtons.Left && m.IsPointOnLine(e.Location, 5)) 
    { 
     dragging = true; 
     deltaStart = new Point(m.Start.X - e.Location.X, m.Start.Y - e.Location.Y); 
     deltaEnd = new Point(m.End.X - e.Location.X, m.End.Y - e.Location.Y); 
    } 
} 

private void Form1_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (dragging && deltaStart != null && deltaEnd != null) 
    { 
     m.Start = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y); 
     m.End = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y); 
     this.Refresh(); 
    } 
} 

private void Form1_MouseUp(object sender, MouseEventArgs e) 
{ 
    dragging = false; 
} 

今、あなたは行の5つのピクセル以内をクリックして、マウスを使って移動していすることができるはずです。

特に、0エラーによる除算を処理するには、追加のエラー処理が必要なコードがいくつかあります。

+0

私のプログラムに適合する変更はほとんどありませんが、これは完全に機能します!ありがとう! :) – NJS

+0

非常に良い回避策ですが、いくつかの行を描画する必要がある場合は、それぞれをどのようにドラッグしますか? –

0

私は、あなたがあなたはまた、それが簡単につかむために作るために長方形を膨らませることができ

if(rectangle.Contains(Point p)) 
{ 
    // do your move 
} 

を使用することができ、あなたが行と行の長さの幅である矩形を作成するお勧め:

rectangle.Inflate(1, 1); 
関連する問題