在PictureBox上绘制折线

时间:2011-09-09 05:47:48

标签: c# winforms graphics polyline

我想在PictureBox上绘制折线(由一个或多个线段组成的连续线)。

在此我们可以通过指定每个段的端点来创建多个行,并计算每个段的距离,即每行的距离。

Sample

1 个答案:

答案 0 :(得分:1)

如果您想在图片框上执行此操作,最简单的方法是从PictureBox继承您自己的控件,并提供在鼠标按下图片框时添加端点的功能。

然后将鼠标单击的位置存储在列表中,并覆盖OnPaint以绘制端点(我选择了4x4方格)和每个端点之间的一条线。这是基本代码:

public class EndPointPictureBox : PictureBox
{
    private List<PointF> points = new List<PointF>();
    public EndPointPictureBox()
    {
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        points.Add(new PointF(e.X,e.Y));
        base.OnMouseDown(e);
        this.Invalidate();
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);

        Graphics g = pe.Graphics;
        foreach(var point in points)
            g.DrawRectangle(Pens.Black,point.X-2.0f,point.Y-2.0f,4.0f,4.0f);
        if(points.Count>1)
            g.DrawLines(Pens.Black,points.ToArray());

    }
}

您现在可以将其添加到Form中,就像PictureBox一样,并选择您的想法以通常的方式进入其中。

如果您尝试在图片框内点击几次,您会看到它像您的示例图片一样绘制您的端点。这是我机器上的一个例子:

Example endpoints

然后你的下一个要求,获得端点之间的距离。这可以通过添加一个类来表示EndPoint并引用其隔壁邻居来完成。然后是一些简单的毕达哥拉斯数学来得到当前点和下一点之间的距离:

public class EndPoint
{
    public EndPoint(int index, List<PointF> points)
    {
        this.Position = points[index];
        if (index < points.Count - 1)
            this.Next = points[index + 1];
    }
    public PointF Position { get; private set; }
    public PointF Next { get; private set; }

    public double GetDistanceToNext()
    {
        if(this.Next == PointF.Empty)
            return 0;

        var xDiff = this.Position.X - Next.X;
        var yDiff = this.Position.Y - Next.Y;

        return Math.Abs(Math.Sqrt((xDiff*xDiff) + (yDiff*yDiff)));
    }
}

您可以在新的PictureBox中添加一个方法,以获取这些方法的列表:

public List<EndPoint> GetEndPoints()
{
    var list = new List<EndPoint>();
    for(var i=0;i<points.Count;i++)
        list.Add(new EndPoint(i,points));
    return list;
}