效果图
界面绘制操作
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# 绘制波浪线的资料请关注小牛知识库其它相关文章!
本文向大家介绍C# 绘制实时折线图,波形图,包括了C# 绘制实时折线图,波形图的使用技巧和注意事项,需要的朋友参考一下 此Demo是采用VS自带的Chart图表控件,制作实时动态显示的折线图,和波形图。本文仅供学习分享使用,如有不足之处,还请指正。 涉及知识点: Chart 控件,功能强大,可以绘制柱状图,折线图,波形图,饼状图,大大简化了对图的开发与定制。 Chart控件的相关概念: C
本文向大家介绍Android实现波浪线效果(xml bitmap),包括了Android实现波浪线效果(xml bitmap)的使用技巧和注意事项,需要的朋友参考一下 我们要实现的效果如下: 在这之前先带大家了解一下xml bitmap,何为XML Bitmap? XML Bitmap 是一个用XML定义的文件放在资源目录,定义的对象是图片,为bitmap定义别名,这个文件可以给bitmap定义一
本文向大家介绍jQuery插件HighCharts绘制简单2D折线图效果示例【附demo源码】,包括了jQuery插件HighCharts绘制简单2D折线图效果示例【附demo源码】的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了jQuery插件HighCharts绘制简单2D折线图效果。分享给大家供大家参考,具体如下: 1、实例代码: 2、运行效果图如下: 附:完整实例代码点击此处本站下
盖伊的,我需要帮助...我得在控制台上画一个正弦波给我上大学课。但我有点纠结于如果..为什么第二个if语句不从第一个if/else语句中取新的“y_1”?也许有人能解释一下,我错在想^^多谢
本文向大家介绍iOS实现波浪效果,包括了iOS实现波浪效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了iOS实现波浪效果的具体代码,供大家参考,具体内容如下 代码: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍Python绘制3d螺旋曲线图实例代码,包括了Python绘制3d螺旋曲线图实例代码的使用技巧和注意事项,需要的朋友参考一下 Line plots 绘制2D或3D数据 参数 描述 xs, ys X轴,Y轴坐标定点 zs Z值,每一个点的值都是1 zdir 绘制2D集合时使用z的方向 其他的参数:plot() Python代码: 效果图: 总结 以上就是本文关于Python绘制3d螺旋