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
{
//刪除預覽
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>
/// 波浪線繪制預覽
/// </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-11
C#使用FtpWebRequest與FtpWebResponse完成FTP操作
這篇文章介紹了C#使用FtpWebRequest與FtpWebResponse完成FTP操作的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05
探討:關(guān)閉瀏覽器后,php腳本會不會繼續(xù)運行
本篇文章是對關(guān)閉瀏覽器后,php腳本會不會繼續(xù)運行進行了詳細的分析介紹,需要的朋友參考下2013-06-06

