Вопрос

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

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

Sample

Это было полезно?

Решение

Если вы хотите сделать это на PictureBox, самое простое - унаследовать ваш собственный контроль от PictureBox и предоставьте функциональность, чтобы добавить конечные точки, когда вы мышитесь на 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());

    }
}

Теперь вы можете добавить это в форму, подобную PictureBox, и выбрать Imagege, чтобы пройти внутрь его обычным способом.

Если вы попытаетесь нажать несколько раз внутри Binatebox, вы увидите, что он рисует ваши конечные точки так же, как ваш пример изображения. Вот пример из моей машины:

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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top