我想你想要这样的东西:
这是执行此操作的代码:
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);
}
}
我利用Graphics.TranslateTransform() 和Graphics.RotateTransform() 在直线的中间和沿直线移动和对齐坐标系。箭头的绘制比尝试手动进行矢量旋转要简单得多。