博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 波浪线绘制
阅读量:5098 次
发布时间:2019-06-13

本文共 6548 字,大约阅读时间需要 21 分钟。

波浪线效果如上

界面绘制操作

1     private Point? _startPoint = null; 2     private void ContainerCanvas_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 3     { 4         var position = e.GetPosition(ContainerCanvas); 5         if (_startPoint == null) 6         { 7             _startPoint = position; 8         } 9         else10         {11             //删除预览12             if (_previewLineElement != null)13             {14                 ContainerCanvas.Children.Remove(_previewLineElement);15                 _previewLineElement = null;16                 _lastMovedPoint = null;17             }18             //确定结束点,绘制波浪线19             var myLineElement = new MyLineElement();20             myLineElement.DrawLine((Point)_startPoint, position);21             ContainerCanvas.Children.Add(myLineElement);22             _startPoint = null;23         }24     }25 26     private MyLineElement _previewLineElement = null;27     private Point? _lastMovedPoint = null;28 29     /// 30     /// 波浪线绘制预览31     /// 32     /// 33     /// 34     private void ContainerCanvas_OnMouseMove(object sender, MouseEventArgs e)35     {36         var position = e.GetPosition(ContainerCanvas);37         if (_startPoint != null && (_lastMovedPoint == null || _lastMovedPoint != null & (position - (Point)_lastMovedPoint).Length >= 2))38         {39             _lastMovedPoint = position;40             if (_previewLineElement != null)41             {42                 ContainerCanvas.Children.Remove(_previewLineElement);43             }44             var myLineElement = new MyLineElement();45             myLineElement.DrawLine((Point)_startPoint, position);46             ContainerCanvas.Children.Add(myLineElement);47             _previewLineElement = myLineElement;48         }49     }

波浪线控件及绘制

1     class MyLineElement : FrameworkElement  2     {  3         public MyLineElement()  4         {  5             _visualShape = new VisualCollection(this);  6         }  7         internal void DrawLine(Point startPoint, Point endPoint)  8         {  9             List
points = ForgePoints(startPoint, endPoint); 10 DrawLine(points); 11 } 12 private const int SeparatorPiexl = 4; 13 private const int AbundancePiexl = 3; 14 private List
ForgePoints(Point startPoint, Point endPoint) 15 { 16 var points = new List
(); 17 18 var lineVector = endPoint - startPoint; 19 var lineDistance = lineVector.Length; 20 var lineAngle = Math.Atan2(-(endPoint.Y - startPoint.Y), endPoint.X - startPoint.X); 21 22 points.Add(startPoint); 23 int index = 0; 24 bool isAbundanceUpward = true; 25 while (index * SeparatorPiexl < lineDistance) 26 { 27 index++; 28 //计算出间隔长度(模拟点到起始点) 29 var separatorDistance = index * SeparatorPiexl; 30 var abundancePiexl = AbundancePiexl; 31 var distanceToStartPoint = Math.Sqrt(Math.Pow(separatorDistance, 2) + Math.Pow(abundancePiexl, 2)); 32 //计算出模拟点、起始点,与直线的角度 33 var separatorAngle = Math.Atan2(AbundancePiexl, separatorDistance); 34 separatorAngle = isAbundanceUpward ? separatorAngle : -separatorAngle; 35 isAbundanceUpward = !isAbundanceUpward; 36 //得到模拟点的水平角度 37 var mockPointAngle = lineAngle + separatorAngle; 38 //计算出模拟点坐标 39 var verticalDistance = distanceToStartPoint * Math.Sin(mockPointAngle); 40 var horizontalDistance = distanceToStartPoint * Math.Cos(mockPointAngle); 41 var mockPoint = new Point(startPoint.X + horizontalDistance, startPoint.Y - verticalDistance); 42 points.Add(mockPoint); 43 } 44 points.Add(endPoint); 45 return points; 46 } 47 48 private void DrawLine(List
points) 49 { 50 _visualShape.Clear(); 51 52 var geometryTest = new StreamGeometry(); 53 using (var ctx = geometryTest.Open()) 54 { 55 ctx.BeginFigure(points[0], true, false); 56 if (points.Count % 2 == 0) 57 { 58 //绘制二阶贝塞尔函数,需要保证为偶数点 59 ctx.PolyQuadraticBezierTo(points, true, true); 60 } 61 else 62 { 63 //绘制二阶贝塞尔函数,需要保证为偶数点 64 points.Insert(0, points[0]); 65 ctx.PolyQuadraticBezierTo(points, true, true); 66 } 67 68 ctx.Close(); 69 } 70 71 var visual = new DrawingVisual(); 72 using (var context = visual.RenderOpen()) 73 { 74 context.DrawGeometry(FillBrush, StrokePen, geometryTest); 75 } 76 _visualShape.Add(visual); 77 } 78 79 #region 内部方法 80 81 [Obsolete] 82 protected override void OnRender(DrawingContext drawingContext) 83 { 84 //弃用,改为_visualShape填充实现 85 //drawingContext.DrawGeometry(FillBrush, StrokePen, BaseGeometry); 86 } 87 88 protected override int VisualChildrenCount => _visualShape.Count; 89 90 protected override Visual GetVisualChild(int index) 91 { 92 if (index < 0 || index >= _visualShape.Count) 93 { 94 throw new ArgumentOutOfRangeException(); 95 } 96 97 return _visualShape[index]; 98 } 99 100 #endregion101 102 #region 曲线属性103 104 private readonly VisualCollection _visualShape;105 protected Brush FillBrush { get; set; } = Brushes.Transparent;106 public Brush LineBrush { get; set; } = Brushes.DarkSeaGreen;107 protected double BorderThickness { get; set; } = 1.0;108 private Pen _defaultPen = null;109 protected Pen StrokePen110 {111 get112 {113 if (_defaultPen == null)114 {115 _defaultPen = new Pen(LineBrush, BorderThickness);116 }117 return _defaultPen;118 }119 set => _defaultPen = value;120 }121 122 #endregion123 }

 

Github地址:

转载于:https://www.cnblogs.com/kybs0/p/11141190.html

你可能感兴趣的文章
msf中的情报搜集
查看>>
数据抓包分析基础
查看>>
HTML学习笔记一
查看>>
Google在情报搜集中的基础技巧
查看>>
CSS学习笔记一
查看>>
DDoS的攻击方法
查看>>
51Nod - 1629 B君的圆锥
查看>>
poj-1195-Mobile Phones
查看>>
Js封装焦点轮换图
查看>>
时区和时间戳
查看>>
月薪3万的程序员都避开了哪些坑?
查看>>
ubuntu装个nginx
查看>>
swift中Range的使用书名
查看>>
慎用dictionaryWithObjectsAndKeys方法
查看>>
js_jquery单机事件不起作用
查看>>
NOIP的基本模板进阶
查看>>
学习进度条
查看>>
python练习七十:图片生成
查看>>
hdu 4609 3-idiots
查看>>
Bitbucket免费的私有仓库
查看>>