Нарисуйте ломаную линию на PictureBox - PullRequest
3 голосов
/ 09 сентября 2011

Я хочу нарисовать ломаную линию (непрерывную линию, состоящую из одного или нескольких отрезков) на PictureBox.

В этом мы можем создать несколько линий, указав конечные точки каждого сегмента, а также рассчитать расстояние каждого сегмента, равное расстоянию каждой линии.

Sample

1 Ответ

1 голос
/ 09 сентября 2011

Если вы хотите сделать это для Picturebox, проще всего унаследовать свой собственный элемент управления от PictureBox и предоставить функциональность для добавления конечных точек при наведении курсора мыши на Picturebox.

Затем вы сохраняете положение щелчка мыши в списке и переопределяете OnPaint, чтобы нарисовать ваши конечные точки (я выбрал квадрат 4х4) и линию между каждой конечной точкой.Это основной код:

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

    }
}

Теперь вы можете добавить это в форму, как в 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;
}
...