c# 實例——繪制波浪線(附源碼)
更新時間:2020年07月15日 10:34:13 作者:唐宋元明清2188
這篇文章主要介紹了c#如何繪制波浪線,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
效果圖
界面繪制操作
private Point? _startPoint = null; private void ContainerCanvas_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var position = e.GetPosition(ContainerCanvas); if (_startPoint == null) { _startPoint = position; } else { //刪除預(yù)覽 if (_previewLineElement != null) { ContainerCanvas.Children.Remove(_previewLineElement); _previewLineElement = null; _lastMovedPoint = null; } //確定結(jié)束點,繪制波浪線 var myLineElement = new MyLineElement(); myLineElement.DrawLine((Point)_startPoint, position); ContainerCanvas.Children.Add(myLineElement); _startPoint = null; } } private MyLineElement _previewLineElement = null; private Point? _lastMovedPoint = null; /// <summary> /// 波浪線繪制預(yù)覽 /// </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) { //繪制二階貝塞爾函數(shù),需要保證為偶數(shù)點 ctx.PolyQuadraticBezierTo(points, true, true); } else { //繪制二階貝塞爾函數(shù),需要保證為偶數(shù)點 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 內(nèi)部方法 [Obsolete] protected override void OnRender(DrawingContext drawingContext) { //棄用,改為_visualShape填充實現(xiàn) //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# 實例——繪制波浪線(附源碼)的詳細內(nèi)容,更多關(guān)于c# 繪制波浪線的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
unity自帶尋路(導航)系統(tǒng) Nav Mesh導航網(wǎng)格
這篇文章主要為大家詳細介紹了unity自帶尋路(導航)系統(tǒng),Nav Mesh導航網(wǎng)格,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11C#使用FtpWebRequest與FtpWebResponse完成FTP操作
這篇文章介紹了C#使用FtpWebRequest與FtpWebResponse完成FTP操作的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05探討:關(guān)閉瀏覽器后,php腳本會不會繼續(xù)運行
本篇文章是對關(guān)閉瀏覽器后,php腳本會不會繼續(xù)運行進行了詳細的分析介紹,需要的朋友參考下2013-06-06