저는 이것을해야합니다 : 내 캔버스의 두 이미지 사이에 화살표를 그립니다. 그래서 화살표가있는 버튼을 클릭하면 하나의 이미지를 클릭하여 화살표를 붙여 넣은 다음 화살표를 그립니다. 오래 걸리며 두 번째 이미지에 붙여 넣습니다.WinForms에서 두 이미지 사이에 화살표를 그리는 방법은 무엇입니까?
답변
두 점으로 호를 그리려면 미리 정의 된 각도가 필요합니다. 그 부분을 알아 냈다고 가정합니다.
이렇게하려면 각 이미지에 하나씩 두 개의 호를 그려야합니다. 호는 각 이미지보다 커지지 만 첫 번째 이미지에서는 호가 두 번째 점으로가는 이미지를 종료하는 곳에서자를 수 있습니다.
두 번째 이미지에서 두 이미지의 원점 간 x 및 y 거리만큼 원호를 오프셋해야합니다. 그런 다음 첫 번째 점에서 두 번째 점까지 두 번째 이미지의 호를 그리고 이미지 외부에있는 해당 부분을 클립합니다.
고무줄이 필요한 경우 마우스를 움직일 때마다 지우고 다시 그려야합니다. 이미지 사이에있는 폼의 공간을 그리려면 올바른 오프셋을 사용하여 이미지를 그릴 수 있습니다.
두 점이 있으므로 선을 그릴 수 있습니다. 이 시도 :
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);
}
}
이 코드를 시도했지만 아무것도 그려지지 않습니다. (아마도. 내가 틀린 일을했을 수도 있습니다.) – Lidia
@Lidia : 10을 늘리고 다시 테스트 해 봅시다. –
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)));
}
}
이 코드가 작동하고 저는 약간 특별한 화살표를 그립니다. ArrowArc가있는 endCap이 더 커지면 C#이 그것을 그립니다. – Lidia
그리기 전에'e.Graphics.ScaleTransform (2, 2);'를 시도하십시오. –
MMH를, 당신은 작은 시각적 인 예를 줄 수 ... 그렇게 명확하지 않다 뭐가 필요할까요? – digEmAll
호를 그리려면 2 점 이상이 필요합니다. 크기, 시작 및 스윕 각도를 결정하려면 어떻게해야합니까? – Doggett
죄송합니다. 귀하가하려는 일을 이해하지 못합니다. a) 박스, 버튼, 호 등의 측면에서 화면 상에 무엇이 있는지 (원하는지), 그리고 b) 마우스 클릭 및 클릭 n- 드래그 작업. 감사. – ja72