小編這次要給大家分享的是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;
/// <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
}看完這篇關于c#如何實現繪制波浪線的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。