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 >= ))
{
_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 = ;
private const int AbundancePiexl = ;
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 = ;
bool isAbundanceUpward = true;
while (index * SeparatorPiexl < lineDistance)
{
index++;
//计算出间隔长度(模拟点到起始点)
var separatorDistance = index * SeparatorPiexl;
var abundancePiexl = AbundancePiexl;
var distanceToStartPoint = Math.Sqrt(Math.Pow(separatorDistance, ) + Math.Pow(abundancePiexl, ));
//计算出模拟点、起始点,与直线的角度
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[], true, false);
if (points.Count % == )
{
//绘制二阶贝塞尔函数,需要保证为偶数点
ctx.PolyQuadraticBezierTo(points, true, true);
}
else
{
//绘制二阶贝塞尔函数,需要保证为偶数点
points.Insert(, points[]);
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 < || 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# 波浪线绘制的更多相关文章
- 2019-6-27-WPF-如何给定两个点画出一条波浪线
title author date CreateTime categories WPF 如何给定两个点画出一条波浪线 lindexi 2019-6-27 10:17:6 +0800 2019-6-26 ...
- Coreldraw绘制标准波浪线
Coreldraw中如何绘制标准波浪线? 先画一根直线,单击工具栏中的“互动式工具组”,选择“互动式变形工具”, 再在弹出的属性栏中选择“拉链变形”,在幅度和频率中分别输入波形的波峰 到波底的值.波浪 ...
- VC++ GetModuleFileName()获取路径字符串中带波浪线~
GetModuleFileName()获取的字符串中带波浪线,不是完整的路径显示. 原因:获取的是短路径,进行了缩写 解决:还原长路径 TCHAR }; GetLongPathName( strTem ...
- Mac 不能输入波浪线?
当你发现你的Mac或者mbp不能输入波浪线 , 输出的都是的时候,检查一下这个选项(如下图所示)有没有选中. 如果没有,就勾上它!
- 消除PyCharm中满屏的波浪线
PyCharm使用了较为严格的PEP8的检查规则,如果代码命名不规范,甚至多出的空格都会被波浪线标识出来,导致整个编辑器里铺满了波浪线,右边的滚动条也全是黄色或灰色的标记线,很是影响编辑. 在网上看了 ...
- VS中的波浪线
绿色波浪线: 如果你的代码中出现了绿色的波浪线,说明你的代码语法并没有错误, 只不过提示你有可能会出现错误,但是不一定会出现错误.警告线 红色波浪线: 如果你的代码中出现了红色的波浪线,意味着你的代码 ...
- sql server 2008 查询语句的红色波浪线
在 Microsoft sql server management studio 里点击“编辑”——“IntelliSense”——“刷新本地缓存” 就会发现红色波浪线没了(前提是你的代码没错)
- 去掉Visual Studio 编辑器里中文注释的红色波浪线 转载
我们通常用visual studio进行开发的时候,我们通常会用到一款比较流行比较方便的插件,那就是Visual Assist X,它可以增强Microsoft开发环境下的编辑能力,支持C/C++,C ...
- 002-python书写规范--消去提示波浪线
强迫症患者面对PyCharm的波浪线是很难受的,针对如下代码去除PyCharm中的波浪线: # _*_coding:utf-8_*_ # /usr/bin/env python3 A_user = & ...
随机推荐
- Spring Boot 外部化配置(二) - @ConfigurationProperties 、@EnableConfigurationProperties
目录 3.外部化配置的核心 3.2 @ConfigurationProperties 3.2.1 注册 Properties 配置类 3.2.2 绑定配置属性 3.1.3 ConfigurationP ...
- VScode安装golang插件详细教程
可能是由于非科班自学编程,所以在安装插件的时候虽然参考了很多人写的教程,但是总安装不成功,在综合各位大牛的教程之后进行总结,并且亲自实践安装成功,希望能给初学编程的人一些帮助,如果有不对的地方还希望大 ...
- 如何下载Vimeo视频
MediaHuman YouTube Downloader是应用在Mac上的一款非常优秀的YouTube视频下载工具,YouTube Downloader破解版将帮助你快速完成视频下载,而不会挂断.您 ...
- 转自自己的关于落谷计数器【p1239】的题解
本蒟蒻写这道题用了两天半里大概五六个小时.(我太弱了) 然后这篇题解将写写我经历的沟沟坎坎,详细的分析一下, 但是由于它很长,因此一定还有多余的地方,比如说我的 预处理,可能比较多余.但是我觉得,信息 ...
- ELK查询命令详解
目录 ELK查询命令详解 倒排索引 使用ElasticSearch API 实现CRUD 批量获取文档 使用Bulk API 实现批量操作 版本控制 什么是Mapping? 基本查询(Query查询) ...
- Spring Boot 设置项目名后静态文件相对路径问题
出现问题的原因 server.servlet.context-path=testDemospring.mvc.static-path-pattern=/static/**定义项目名和静态资源路径后发现 ...
- Aery的UE4 C++游戏开发之旅(3)蓝图
目录 蓝图 蓝图命名规范 蓝图优化 暴露C++至蓝图 暴露C++类 暴露C++属性 暴露C++函数 暴露C++结构体/枚举 暴露C++接口 蓝图和C++的结合方案 使用继承重写蓝图 使用组合重写蓝图 ...
- 2019蚂蚁金服中高级Java工程师面试题及答案
面试基础 谈谈一致hash算法? 按照hash算法来将对应的key哈希到一个具有2^32次方个桶的空间中,即0~(2^32)-1的数字空间.将这些数字头尾相连,想象成一个闭合的环形.如果集群中加入新的 ...
- js实现常见排序算法
电脑配置 CPU:AMD X4 640 内存: 宏想 DDR3 1600MHz 8g 主板:华擎 980DE3/U3S3 R2.0 浏览器:chrome 79.0.3945.88(正式版本) (64 ...
- Java开发之使用websocket实现web客户端与服务器之间的实时通讯
使用websocket实现web客户端与服务器之间的实时通讯.以下是个简单的demo. 前端页面 <%@ page language="java" contentType=& ...