【问题标题】:How to draw an arrow between two images in WinForms?如何在 WinForms 中的两个图像之间绘制箭头?
【发布时间】:2011-09-25 09:45:04
【问题描述】:

我必须这样做:在我的画布上的两个图像之间绘制一个箭头,所以当我单击带有箭头的按钮并单击一个图像以将箭头粘贴在其上然后绘制箭头时只要我需要并将其粘贴到第二张图片。

【问题讨论】:

  • 嗯,不太清楚...你能举一个你需要的小视觉例子吗?
  • 你需要2个以上的点来画一个圆弧,你还要怎么确定大小、起点和扫角?
  • 对不起,我不明白你在做什么。你能清楚地解释a)你在屏幕上拥有(想要)什么,就框、按钮、弧线等而言,以及b)你想(用户)在鼠标点击方面做什么,也许点击-n-拖动操作。谢谢。
  • 我正在做一个编辑器(BPMN Editor),我有各种各样的东西来表示:事件、活动、关系等。所以我有所有这些东西的按钮,我的意思是当我按下按钮,在我的画布上绘制了一个代表事件或活动的图像。具有关系的按钮是箭头按钮,所以我想在我的两个图像之间绘制一个箭头,单击一个图像并将箭头绘制到我点击后的另一个图像。

标签: c# winforms draw geometric-arc


【解决方案1】:

要绘制两点圆弧,您需要一个预定义的角度。我想你已经弄清楚了。

为此,您需要绘制两条弧线,每张图像中各一条。圆弧会比每张图片都大,但在第一张图片中,您可以将其剪裁到圆弧离开图像并朝向第二点的位置。

在第二个图像中,您需要将弧偏移两个图像原点之间的 x 和 y 距离。然后在第二张图片中从第一个点到第二个点画弧线,剪掉图片外的那部分。

如果您需要橡皮筋弧线,则必须在鼠标移动时擦除并重新绘制它。如果您想在图像之间的表格上绘制空间,您可以使用适当的偏移量来做到这一点。

【讨论】:

    【解决方案2】:

    你有两个点,所以你可以画一条线。试试这个:

    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);
        }
    }
    

    【讨论】:

    • 我试过这段代码,但它没有画出任何东西:(。也许我做错了什么
    【解决方案3】:
    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# 画得大。
    • 在绘制之前尝试e.Graphics.ScaleTransform(2, 2);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多