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

C# 在两点之间的直线上绘制箭头,c#,winforms,graphics,gdi+,C#,Winforms,Graphics,Gdi+,我怎样画一个箭头来表示线的方向?我设法做到了,但箭头的形状不对 我想你想要这样的东西: 下面是执行此操作的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.p

我怎样画一个箭头来表示线的方向?我设法做到了,但箭头的形状不对


我想你想要这样的东西:

下面是执行此操作的代码:

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, 120+35*i),
                new PointF(340+290, 50),
                4f+3f*i, 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);
    }
}
公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
}
受保护的覆盖无效加载(事件参数e)
{
基础荷载(e);
this.pictureBox1.Paint+=pictureBox1_Paint;
}
私有void PictureBox1_Paint(对象发送方,PaintEventArgs e)
{
e、 Graphics.SmoothingMode=SmoothingMode.AntiAlias;
对于(int i=0;i<5;i++)
{
带箭头的抽绳(如图形、,
颜色,蓝色,
新的点F(50,50),
新的点F(340120+35*i),
4f+3f*i,假);
带箭头的抽绳(如图形、,
颜色,红色,
新的点F(340120+35*i),
新点F(340+290,50),
4f+3f*i,正确);
}
}
带箭头的公共空心绘图线(图形g,颜色,点F开始,点F结束,浮动箭头大小=8f,布尔填充=假)
{
如果(开始==结束)返回;
PointF mid=新的PointF((start.X+end.X)/2,(start.Y+end.Y)/2);
浮动角度=(浮动)(180/Math.PI*Math.Atan2(end.Y-start.Y,end.X-start.X));
var gp=新图形spath();
gp.AddLines(
新点F[]
{
新点F(-arrowSize,-arrowSize/3),
新的点F(0,0),
新点F(-arrowSize,arrowSize/3)
}
);
如有(已填写)
{
gp.CloseFigure();
}
var state=g.Save();
使用(画笔=新画笔(颜色,0))
{
g、 抽绳(笔、起点、终点);
g、 翻译形式(
X月中旬,
年中);
g、 旋转变换(角度);
如有(已填写)
{
使用(笔刷填充=新的SolidBrush(颜色))
{
g、 填充路径(填充,总成);
}
}
g、 绘图路径(笔,总成);
}
g、 恢复(状态);
}
}

我利用了<代码>图形.TrimeTeaTror()/<代码>和<代码>图形。箭头的绘制比手动进行矢量旋转要简单得多。

另一个示例:

制作人:

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, 0), new Point(8, 0));
        e.Graphics.RotateTransform(-270);
        e.Graphics.DrawLine(Pens.Black, new Point(0, 0), new Point(8, 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);
}
private void pictureBox1\u Paint(对象发送方,PaintEventArgs e)
{
点[]点={
新点(100110),
新点(300210),
新点(200310),
新点(100310)
};

对于(int i=0;我不理解这个问题。如果你所做的只是硬编码坐标,那么只需硬编码正确的坐标。如果你想要某种计算箭头,那么你需要在你的问题中提供更多的细节。这包括一个显示你所尝试的,以及详细解释你具体需要什么我认为问题很清楚。如何在windows窗体中为
GDI
绘制的线条添加箭头功能。
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, 0), new Point(8, 0));
        e.Graphics.RotateTransform(-270);
        e.Graphics.DrawLine(Pens.Black, new Point(0, 0), new Point(8, 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);
}