欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

c# 实例——绘制波浪线(附源码)

程序员文章站 2022-11-16 10:34:49
效果图界面绘制操作private point? _startpoint = null; private void containercanvas_onpreviewmouseleftbutt...

效果图

c# 实例——绘制波浪线(附源码)

界面绘制操作

private point? _startpoint = null;
  private void containercanvas_onpreviewmouseleftbuttondown(object sender, mousebuttoneventargs e)
  {
    var position = e.getposition(containercanvas);
    if (_startpoint == null)
    {
      _startpoint = position;
    }
    else
    {
      //删除预览
      if (_previewlineelement != null)
      {
        containercanvas.children.remove(_previewlineelement);
        _previewlineelement = null;
        _lastmovedpoint = null;
      }
      //确定结束点,绘制波浪线
      var mylineelement = new mylineelement();
      mylineelement.drawline((point)_startpoint, position);
      containercanvas.children.add(mylineelement);
      _startpoint = null;
    }
  }

  private mylineelement _previewlineelement = null;
  private point? _lastmovedpoint = null;

  /// <summary>
  /// 波浪线绘制预览
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void containercanvas_onmousemove(object sender, mouseeventargs e)
  {
    var position = e.getposition(containercanvas);
    if (_startpoint != null && (_lastmovedpoint == null || _lastmovedpoint != null & (position - (point)_lastmovedpoint).length >= 2))
    {
      _lastmovedpoint = position;
      if (_previewlineelement != null)
      {
        containercanvas.children.remove(_previewlineelement);
      }
      var mylineelement = new mylineelement();
      mylineelement.drawline((point)_startpoint, position);
      containercanvas.children.add(mylineelement);
      _previewlineelement = mylineelement;
    }
  }

波浪线控件及绘制

class mylineelement : frameworkelement
  {
    public mylineelement()
    {
      _visualshape = new visualcollection(this);
    }
    internal void drawline(point startpoint, point endpoint)
    {
      list<point> points = forgepoints(startpoint, endpoint);
      drawline(points);
    }
    private const int separatorpiexl = 4;
    private const int abundancepiexl = 3;
    private list<point> forgepoints(point startpoint, point endpoint)
    {
      var points = new list<point>();

      var linevector = endpoint - startpoint;
      var linedistance = linevector.length;
      var lineangle = math.atan2(-(endpoint.y - startpoint.y), endpoint.x - startpoint.x);

      points.add(startpoint);
      int index = 0;
      bool isabundanceupward = true;
      while (index * separatorpiexl < linedistance)
      {
        index++;
        //计算出间隔长度(模拟点到起始点)
        var separatordistance = index * separatorpiexl;
        var abundancepiexl = abundancepiexl;
        var distancetostartpoint = math.sqrt(math.pow(separatordistance, 2) + math.pow(abundancepiexl, 2));
        //计算出模拟点、起始点,与直线的角度
        var separatorangle = math.atan2(abundancepiexl, separatordistance);
        separatorangle = isabundanceupward ? separatorangle : -separatorangle;
        isabundanceupward = !isabundanceupward;
        //得到模拟点的水平角度
        var mockpointangle = lineangle + separatorangle;
        //计算出模拟点坐标
        var verticaldistance = distancetostartpoint * math.sin(mockpointangle);
        var horizontaldistance = distancetostartpoint * math.cos(mockpointangle);
        var mockpoint = new point(startpoint.x + horizontaldistance, startpoint.y - verticaldistance);
        points.add(mockpoint);
      }
      points.add(endpoint);
      return points;
    }

    private void drawline(list<point> points)
    {
      _visualshape.clear();

      var geometrytest = new streamgeometry();
      using (var ctx = geometrytest.open())
      {
        ctx.beginfigure(points[0], true, false);
        if (points.count % 2 == 0)
        {
          //绘制二阶贝塞尔函数,需要保证为偶数点
          ctx.polyquadraticbezierto(points, true, true);
        }
        else
        {
          //绘制二阶贝塞尔函数,需要保证为偶数点
          points.insert(0, points[0]);
          ctx.polyquadraticbezierto(points, true, true);
        }

        ctx.close();
      }

      var visual = new drawingvisual();
      using (var context = visual.renderopen())
      {
        context.drawgeometry(fillbrush, strokepen, geometrytest);
      }
      _visualshape.add(visual);
    }

    #region 内部方法

    [obsolete]
    protected override void onrender(drawingcontext drawingcontext)
    {
      //弃用,改为_visualshape填充实现
      //drawingcontext.drawgeometry(fillbrush, strokepen, basegeometry);
    }

    protected override int visualchildrencount => _visualshape.count;

    protected override visual getvisualchild(int index)
    {
      if (index < 0 || index >= _visualshape.count)
      {
        throw new argumentoutofrangeexception();
      }

      return _visualshape[index];
    }

    #endregion

    #region 曲线属性

    private readonly visualcollection _visualshape;
    protected brush fillbrush { get; set; } = brushes.transparent;
    public brush linebrush { get; set; } = brushes.darkseagreen;
    protected double borderthickness { get; set; } = 1.0;
    private pen _defaultpen = null;
    protected pen strokepen
    {
      get
      {
        if (_defaultpen == null)
        {
          _defaultpen = new pen(linebrush, borderthickness);
        }
        return _defaultpen;
      }
      set => _defaultpen = value;
    }

    #endregion
  }

github地址:https://github.com/kybs0/wavelinetextdemo

以上就是c# 实例——绘制波浪线(附源码)的详细内容,更多关于c# 绘制波浪线的资料请关注其它相关文章!