2010-12-05 4 views
1

저는 이것을해야합니다 : 내 캔버스의 두 이미지 사이에 화살표를 그립니다. 그래서 화살표가있는 버튼을 클릭하면 하나의 이미지를 클릭하여 화살표를 붙여 넣은 다음 화살표를 그립니다. 오래 걸리며 두 번째 이미지에 붙여 넣습니다.WinForms에서 두 이미지 사이에 화살표를 그리는 방법은 무엇입니까?

+0

MMH를, 당신은 작은 시각적 인 예를 줄 수 ... 그렇게 명확하지 않다 뭐가 필요할까요? – digEmAll

+0

호를 그리려면 2 점 이상이 필요합니다. 크기, 시작 및 스윕 각도를 결정하려면 어떻게해야합니까? – Doggett

+0

죄송합니다. 귀하가하려는 일을 이해하지 못합니다. a) 박스, 버튼, 호 등의 측면에서 화면 상에 무엇이 있는지 (원하는지), 그리고 b) 마우스 클릭 및 클릭 n- 드래그 작업. 감사. – ja72

답변

1

두 점으로 호를 그리려면 미리 정의 된 각도가 필요합니다. 그 부분을 알아 냈다고 가정합니다.

이렇게하려면 각 이미지에 하나씩 두 개의 호를 그려야합니다. 호는 각 이미지보다 커지지 만 첫 번째 이미지에서는 호가 두 번째 점으로가는 이미지를 종료하는 곳에서자를 수 있습니다.

두 번째 이미지에서 두 이미지의 원점 간 x 및 y 거리만큼 원호를 오프셋해야합니다. 그런 다음 첫 번째 점에서 두 번째 점까지 두 번째 이미지의 호를 그리고 이미지 외부에있는 해당 부분을 클립합니다.

고무줄이 필요한 경우 마우스를 움직일 때마다 지우고 다시 그려야합니다. 이미지 사이에있는 폼의 공간을 그리려면 올바른 오프셋을 사용하여 이미지를 그릴 수 있습니다.

1

두 점이 있으므로 선을 그릴 수 있습니다. 이 시도 :

public class Shape 
{ 
    public float X { get; set; } 
    public float Y { get; set; } 
    public Image Image { get; set; } 
} 

public class Line 
{ 
    public Shape A { get; set; } 
    public Shape B { get; set; } 
} 

및 코드 :

private string _currentTool; 
private readonly List<Shape> _shapes; 
private readonly List<Line> _lines; 
private Line _currentLine; 

private void Button1Click(object sender, EventArgs e) 
{ 
    _currentTool = "img"; 
} 

private void Button2Click(object sender, EventArgs e) 
{ 
    _currentTool = "line"; 
} 

private void PictureBox1MouseDown(object sender, MouseEventArgs e) 
{ 
    switch (_currentTool) 
    { 
     case "img": 
      _shapes.Add(new Shape { Image = button1.Image, X = e.X, Y = e.Y }); 
      pictureBox1.Invalidate(); 
      break; 
     case "line": 
       var selectedShapes = _shapes.Where(shape => (shape.X - 10 < e.X) && (e.X < shape.X + 10) && 
                  (shape.Y - 10 < e.Y) && (e.Y < shape.Y + 10)); 
       if (selectedShapes.Count() > 0) 
       { 
        var selectedShape = selectedShapes.First(); 
        _currentLine = new Line {A = selectedShape}; 
        pictureBox1.Invalidate(); 
       } 
      break; 
    } 
} 

private void PictureBox1MouseUp(object sender, MouseEventArgs e) 
{ 
    switch (_currentTool) 
    { 
     case "line": 
       var selectedShapes = _shapes.Where(shape => (shape.X - 10 < e.X) && (e.X < shape.X + 10) && 
                  (shape.Y - 10 < e.Y) && (e.Y < shape.Y + 10)); 
       if (selectedShapes.Count() > 0) 
       { 
        var selectedShape = selectedShapes.First(); 
        _currentLine.B = selectedShape; 
        _lines.Add(_currentTool); 
        pictureBox1.Invalidate(); 
       } 
      break; 
    } 
} 

private void PictureBox1Paint(object sender, PaintEventArgs e) 
{ 
    foreach (var shape in _shapes) 
    { 
     e.Graphics.DrawImage(shape.Image, shape.X, shape.Y); 
    } 
    foreach (var line in _lines) 
    { 
     e.Graphics.DrawLine(new Pen(Color.Black), line.A.X, line.A.Y, line.B.X, line.B.Y); 
    } 
} 
+0

이 코드를 시도했지만 아무것도 그려지지 않습니다. (아마도. 내가 틀린 일을했을 수도 있습니다.) – Lidia

+0

@Lidia : 10을 늘리고 다시 테스트 해 봅시다. –

0
public class Shape 
{ 
public float X { get; set; } 
public float Y { get; set; } 
public Image Image { get; set; } 

public bool Test_int(int x, int y) 
    { 
     if (((x <= this.x + (float)image.Width) && (x >= this.x)) && ((y <= this.y + (float)image.Height) && (y >= this.y))) 
      return true; 
     else 
      return false; 
    } 
} 



public class Line 
{ 
    public Shape A { get; set; } 
    public Shape B { get; set; } 
} 

하고 코드

private string currentTool; 
private readonly List<Shape> shapes; 
private readonly List<Line> lines; 
private Line currentLine; 

private void Button1Click(object sender, EventArgs e) 
{ 
    currentTool = "img"; 
} 

private void Button2Click(object sender, EventArgs e) 
{ 
    currentTool = "line"; 
} 


private void PictureBox1MouseDown(object sender, MouseEventArgs e) 
{ 

    switch (currentTool) 
    { 
     case "img": 
      shapes.Add(new Shape { Image = button1.Image, X = e.X, Y = e.Y }); 
      pictureBox1.Invalidate(); 
      break; 
     case "line": 
      foreach (Shape shape1 in shapes) 
       { 

        if (shape1.Test_int(e.X, e.Y)) 
        { 

         currentLine = new Line { A = shape1 }; 

        } 

       } 
       drawArea1.Invalidate(); 
     break; 
    } 
} 

private void PictureBox1MouseUp(object sender, MouseEventArgs e) 
{ 

    switch (currentTool) 
    { 
     case "line": 
      foreach (Shape shape1 in shapes) 
      { 

       if (shape1.Test_int(e.X, e.Y)) 
       { 


        currentLine.B = shape1; 

        } 

       } 
       lines.Add(currentLine); 
       drawArea1.Invalidate(); 

      break; 
    } 
} 

private void PictureBox1Paint(object sender, PaintEventArgs e) 
{ 

    foreach (var shape in shapes) 
    { 
     e.Graphics.DrawImage(shape.Image, shape.X, shape.Y); 
    } 
    foreach (var line in lines) 
    { 
     Pen p = new Pen(Color.Gray, 1); 
     Pen p2 = new Pen(Color.Black, 5); 

     e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 

     p2.StartCap = System.Drawing.Drawing2D.LineCap.Round; 
     p2.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor; 

     float x1 = line.A.X+line.A.Image.Width ; 
     float y1 = line.A.Y+line.A.Image.Height/2; 
     float x2 = line.B.X; 
     float y2 = line.B.Y+line.B.Image.Height/2; 
     double angle = Math.Atan2(y2 - y1, x2 - x1); 

     e.Graphics.DrawLine(p, x1, y1, x2, y2); 
     e.Graphics.DrawLine(p2, x2, y2, x2 + (float)(Math.Cos(angle)), y2 + (float)(Math.Sin(angle))); 

    } 
} 
+0

이 코드가 작동하고 저는 약간 특별한 화살표를 그립니다. ArrowArc가있는 endCap이 더 커지면 C#이 그것을 그립니다. – Lidia

+0

그리기 전에'e.Graphics.ScaleTransform (2, 2);'를 시도하십시오. –