栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C# > C#教程

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

C#教程 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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;

  /// 
  /// 波浪线绘制预览
  /// 
  /// 
  /// 
  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 points = ForgePoints(startPoint, endPoint);
      DrawLine(points);
    }
    private const int SeparatorPiexl = 4;
    private const int AbundancePiexl = 3;
    private List ForgePoints(Point startPoint, Point endPoint)
    {
      var points = new List();

      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 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# 绘制波浪线的资料请关注考高分网其它相关文章!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/121924.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号