如何在.Net中绘制有向线?

时间:2010-11-18 20:08:43

标签: c# .net graphics gdi+

有关如何在.Net中绘制有向线的任何建议?我目前正在使用带有破折号笔的Graphics.DrawLine。但破折号指向两个方向。我希望他们都指向一个方向。

using (var p = new Pen(Color.FromArgb(190, Color.Green), 5))
{
    p.StartCap = LineCap.Round;
    p.EndCap = LineCap.ArrowAnchor;
    p.CustomEndCap = new AdjustableArrowCap(3, 3);
    p.DashStyle = DashStyle.Dash;
    p.DashCap = DashCap.Triangle;
    e.Graphics.DrawLine(p, startPt, pt);
}

2 个答案:

答案 0 :(得分:3)

这可能不是很有帮助,但是我在其他项目中完成此类事情的方式是实现一个自定义的“笔”,它接受要绘制的线,计算实际的破折号,然后将每个短划线绘制为具有“真实”笔的单独线。如果您要做这样的事情,那么您实际上可以将“笔”级别的StartCap和/或EndCap应用于每个破折号。

自定义“笔”必须接受一个数组或短划线/间隙长度序列(或者可能是内部解释为特定短划线/间隙长度的标准笔样式的枚举)。

我们多年前使用基于GDI的绘图系统完成了这项工作,我们必须支持比GDI支持的内置线条样式更多的线条样式。

这是一项有趣的练习,但除非你真的必须按照你的描述画出破折号,否则它也可能比它的价值更麻烦。

[编辑]

如果您愿意,可以使用以下示例代码来说明如何执行此操作。

首先是Graphics对象的扩展方法。需要笔,短划线长度,间隙长度,起点和终点。它沿着线p1-> p2进行插值,绘制“破折号”长度段,然后跳过“间隙”长度段。传入的笔应该是实心的,带有箭头端盖(以达到你要求的效果)。

代码非常粗糙,但行为或多或少是这样的: 如果输入线比短划线+间隙长度短,则使用输入笔按原样绘制线。 如果输入线长于总短划线+间隙长度,则绘制“虚线”长度线,直到线的“余数”小于短划线+间隙长度,此时剩余部分按原样绘制,输入笔。

如果你想实现路径绘图,那么你必须在中间顶点周围进行插值(除非你想要廉价出去并且只是为每个段做一个独立的破折号)。

    public static void DrawDashedLine(this Graphics g, Pen p, float dash, float gap, PointF s, PointF e)
    {
      float dx = e.X - s.X;
      float dy = e.Y - s.Y;

      float len = (float)Math.Sqrt(dx * dx + dy * dy);
      float remainder = len;

      float vx = dx / len;
      float vy = dy / len;

      if (len <= dash + gap)
      {
        g.DrawLine(p, s, e);
        return;
      }

      PointF last = s;

      while (remainder > dash + gap)
      {
        PointF p1 = new PointF(last.X, last.Y);
        PointF p2 = new PointF(p1.X + vx*dash, p1.Y + vy*dash);

        g.DrawLine(p, p1, p2);

        last = new PointF(p2.X + vx*gap, p2.X + vy*gap);

        remainder = remainder - dash - gap;
      }

      if (remainder > 0)
      {
        g.DrawLine(p, last, e);
      }
    }
  }

以下是您的称呼方式:

private void button1_Click(object sender, EventArgs e)
{
  using (var p = new Pen(Color.FromArgb(190, Color.Green), 5))
  {
    p.StartCap = LineCap.Round;
    p.EndCap = LineCap.ArrowAnchor;
    p.CustomEndCap = new AdjustableArrowCap(3, 3);
    p.DashStyle = DashStyle.Solid;
    var graph = this.CreateGraphics();
    graph.DrawDashedLine(p, 20, 10, new PointF(20, 20), new PointF(500, 500));
  } 
}

我并不认为代码很棒(甚至不一定好;-),但如果你真的有兴趣绘制有向线,那么它应该给你一个很好的起点。

祝你好运!

答案 1 :(得分:2)

嗯......也许我错过了一些东西,但是当我使用这个(差不多)完全相同的代码时,我只得到了一个指向箭头。

这是我的代码:

private void button2_Click(object sender, EventArgs e)
{
    using (var p = new Pen(Color.FromArgb(190, Color.Green), 5))
    {
        p.StartCap = LineCap.Round;
        p.EndCap = LineCap.ArrowAnchor;
        p.CustomEndCap = new AdjustableArrowCap(3, 3);
        p.DashStyle = DashStyle.Dash;
        p.DashCap = DashCap.Triangle;
        var graph = this.CreateGraphics();
        graph.DrawLine(p, new Point(20, 20), new Point(150, 150));
    }
}

输出: alt text