在两点之间的直线之间绘制箭头

问题描述

我如何绘制一个错误显示线的方向?我设法做到了,但是箭头的形状不正确。

enter image description here

//For Line
Point point1 = new Point(100,110);
Point point2 = new Point(300,210);
Point point3 = new Point(200,310);
Point point4 = new Point(100,310); 

e.Graphics.DrawLines(pen,points);

//For Arrow
e.Graphics.DrawLine(pen,200,150,180,130);
e.Graphics.DrawLine(pen,150);

解决方法

我认为您想要这样的东西:

draw

这是执行此操作的代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        this.pictureBox1.Paint += PictureBox1_Paint;
    }

    private void PictureBox1_Paint(object sender,PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        for (int i = 0; i < 5; i++)
        {
            DrawLineWithArrow(e.Graphics,Color.Blue,new PointF(50,50),new PointF(340,120+35*i),4f+3f*i,false);
            DrawLineWithArrow(e.Graphics,Color.Red,new PointF(340+290,true);
        }

    }

    public void DrawLineWithArrow(Graphics g,Color color,PointF start,PointF end,float arrowSize=8f,bool filled = false)
    {
        if (start==end) return;

        PointF mid = new PointF((start.X+end.X)/2,(start.Y+end.Y)/2);

        float angle = (float)(180/Math.PI*Math.Atan2(end.Y-start.Y,end.X-start.X));

        var gp = new GraphicsPath();
        gp.AddLines(
            new PointF[] 
            {
                new PointF(-arrowSize,-arrowSize/3),new PointF(0,0),new PointF(-arrowSize,arrowSize/3)
            }
        );
        if (filled)
        {
            gp.CloseFigure();
        }
        var state = g.Save();
        using (Pen pen = new Pen(color,0)) 
        {
            g.DrawLine(pen,start,end);
            g.TranslateTransform(
                mid.X,mid.Y);
            g.RotateTransform(angle);
            if (filled)
            {
                using (Brush fill = new SolidBrush(color))
                {
                    g.FillPath(fill,gp);
                }
            }
            g.DrawPath(pen,gp);
        }
        g.Restore(state);
    }
}

我利用Graphics.TranslateTransform()Graphics.RotateTransform()在直线的中间并沿着直线移动和对齐坐标系。箭头的绘制比尝试手动进行矢量旋转要简单得多。

,

另一个例子:

enter image description here

生产者:

private void pictureBox1_Paint(object sender,PaintEventArgs e)
{
    Point[] points = {
        new Point(100,110),new Point(300,210),new Point(200,310),new Point(100,310)
    };
    for(int i=0; i<(points.Length-1); i++)
    {
        Point p1 = points[i];
        Point p2 = points[i + 1];                
        e.Graphics.DrawLine(Pens.Black,p1,p2);

        float angle = getAngle(p1,p2);
        Point mid = getMidPoint(p1,p2);
        e.Graphics.TranslateTransform(mid.X,mid.Y);
        e.Graphics.RotateTransform(angle);
        e.Graphics.RotateTransform(135);
        e.Graphics.DrawLine(Pens.Black,new Point(0,new Point(8,0));
        e.Graphics.RotateTransform(-270);
        e.Graphics.DrawLine(Pens.Black,0));
        e.Graphics.ResetTransform();
    }
}

private float getAngle(Point p1,Point p2)
{
    float deltaX = p2.X - p1.X;
    float deltaY = p2.Y - p1.Y;
    return (float)(Math.Atan2(deltaY,deltaX) * 180.0 / Math.PI);
}

private Point getMidPoint(Point p1,Point p2)
{
    return new Point((p1.X + p2.X)/2,(p1.Y+p2.Y)/2);
}