代码之家  ›  专栏  ›  技术社区  ›  skolima

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

  •  4
  • skolima  · 技术社区  · 14 年前

    关于如何在.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 回复  |  直到 14 年前
        1
  •  3
  •   wageoghe    14 年前

    这可能不是很有帮助,但是我们在其他项目中完成这类工作的方式是实现一个自定义的“笔”,它接受要绘制的线,计算实际的破折号,然后用“真实”的笔将每个破折号绘制为一条单独的线。如果你要做这样的事情,那么你可以在每一个破折号上应用一个“笔”级的起始值和/或结束值。

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

    许多年前,我们使用了一个基于GDI的绘图系统,在该系统中,我们必须支持比GDI支持的内置线条样式更多的线条样式。

    这是一个有趣的练习,但它也可能比它的价值更麻烦,除非你真的需要画出你所描述的破折号。

    [编辑]

    下面是一些示例代码,说明如果您愿意,可以如何执行此操作。

    首先是图形对象的扩展方法。它需要一支笔、短划线长度、间隙长度、起点和终点。它沿直线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));
      } 
    }
    

    我并不认为代码很好(或者说一定很好;-),但是如果你真的对绘制有向线感兴趣的话,它应该给你一个很好的起点。

    祝你好运!

        2
  •  2
  •   Josh    14 年前
    Hmm.。也许我遗漏了一些东西,但是当我使用这个(几乎)完全相同的代码时,我得到一个只有一点的定向箭头。

    这是我的代码:

    private void button2_click(object sender,eventargs e)
    {
    使用(var p=新笔(color.fromargb(190,color.green),5))
    {
    p.startcap=linecap.round;
    p.endcap=linecap.arrowanchor;
    p.customNdcap=新的可调箭头帽(3,3);
    p.dashStyle=dashStyle.dash;
    p.dashcap=dashcap.triangle;
    var graph=this.creategraphics();
    绘图线(P,新点(20,20),新点(150,150));
    }
    }
    < /代码> 
    
    

    输出:

    (几乎)完全相同的代码,我得到一个只有一点的有向箭头。

    这是我的代码:

    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