C# 笔迹擦除8边形
擦除区域与橡皮大小不一致
测试反馈,擦除区域与真实的橡皮大小不一致:

上图中,橡皮显示是圆形的,但擦除效果是一个“8边形”区域。
找了一台8K屏,确实是能复现的:

看到这个诡异的8边形,一开始我是以为是逗逼小伙伴在手势识别模块写出来的BUG
但开发肯定不会弄这么规整的形状出来,所以还是要看下擦除模块、看下具体问题在哪
擦除模块流程&定位
StrokeCollection类下面,有个GetIncrementalStrokeHitTester方法,根据擦除图形来创建擦除命中测试的处理类

所以我们创建了一个100*100大小的圆形 ,用于擦除操作
1 var stylusShape = new EllipseStylusShape(100,100);
2 var hitTester = InkStrokes.GetIncrementalStrokeHitTester(stylusShape);
既然是Ellipse,那肯定不存在8边形。
我们再看看具体的擦除操作:
1 private void CreateStrokeHitTester()
2 {
3 var stylusShape = new EllipseStylusShape(100, 100);
4 var hitTester = InkStrokes.GetIncrementalStrokeHitTester(stylusShape);
5 hitTester.AddPoints(points);
6 hitTester.StrokeHit += StrokeHitTester;
7 }
8 private void StrokeHitTester1(object sender, StrokeHitEventArgs e)
9 {
10 var hitStroke = e.HitStroke;
11 var eraseResults = e.GetPointEraseResults();
12 }
hitTester.AddPoints(points) -- 为命中测试处理类,添加点集。
hitTester.StrokeHit += StrokeHitTester -- 添加点集时,hitTester内部会根据点集形成一条路径,然后获取路径对应的矩形Bounds。
使用路径Bounds与笔迹Strokes做相交判断,确认相交的话,触发StrokeHit命中事件并生成擦除后的Strokes:

可以看到StrokeHitEventArgs构造有俩个参数,一个是HitStroke(擦除操作命中的笔迹),另一个是擦除后的笔迹集合(可能是一个stroke,也可能是多个)
我们回到擦除8边形的问题上。所以,上面擦除操作中的代码并没有所谓的”8边形“相关异常,我们去看看其它的代码
上图中有个参数_erasingStroke,_erasingStroke = new ErasingStroke(eraserShape),而eraserShape就是我们上面说的擦除形状。
我们一步步跟下去,可以看到StrokeNodeOperations初始化时,去调用了StylusShape抽象类的内部方法GetVerticesAsVectors():

而StylusShape内部,如果是矩形形状则直接在构造函数初始化形状的顶点数据。如果是圆形则会延迟初始化,在有需要时获取顶点数据_vertices:
1 Point[] bezierControlPoints = this.GetBezierControlPoints();
2 vertices = new Vector[bezierControlPoints.Length];
3 for (int index = 0; index < vertices.Length; ++index)
4 vertices[index] = (Vector) bezierControlPoints[index];
圆形是通过执行GetBezierControlPoints来获取内部的点集,我们来看GetBezierControlPoints函数:

如上图所标示,顶点一共12个,其实应该叫”12边形“,只不过因为上下左右的折角是180度,所以看起来是8边形。
0.552284749830793这个系数是8边形折线的水平/竖直位置计算系数。
根据这12个点,生成12个向量。然后以12个向量组合为Bounds,这个Bounds就是擦除命中测试的图形。
根据上面描述,我们可以确定,8边形问题源头就是这个StylusShape类,源码设计如此。
至于为何是8边形,而不是其它的形状。应该是不想用太复杂的图形去做计算,毕竟真要实现完整的圆形,数学几何里圆也是多边形,所以要用N多边形的话性能会有影响。
而在一个正方形的基础上,搞四个边角,能实现擦除功能也能保障擦除性能。这个设计没毛病。
以WPF为框架的白板/批注等应用,都有这个BUG。所以,测试同学有给你报这个BUG没?
C# 笔迹擦除8边形的更多相关文章
- JDK5.0新特性(静态导入、自动装箱/拆箱、增强for循环、可变参数、枚举、泛形)
JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效.清晰,安全的代码. 这些新特性主要有:1.静态导入2.自动装箱/拆箱3.增强for循环4.可变参数5.枚举6.泛型7 ...
- JavaBean 内省API BeanUtils工具 泛型 xml xml约束
1 什么是JavaBean?有何特征? 1)符合特定规则的类 2)JavaBean分二类: a)侠义的JavaBean .私有的字段(Field) .对私 ...
- 五、Java基础加强
Java基础加强 1.MyEclipse的使用工作空间(workspace).工程(project)在eclipse下Java程序的编写和运行,及java运行环境的配置.快捷键的配置,常用快捷键:内容 ...
- javase(14)_java基础增强
一.Eclipse的使用 1.在eclipse下Java程序的编写和run as,debug as,及java运行环境的配置. 2.快捷键的配置,常用快捷键: •内容提示:Alt + / •快速修复: ...
- Java泛型-类型擦除
一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变 ...
- Java泛型:类型擦除
类型擦除 代码片段一 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String& ...
- java之集合类框架的简要知识点:泛型的类型擦除
这里想说一下在集合框架前需要理解的小知识点,也是个人的肤浅理解,不知道理解的正不正确,请大家多多指教.这里必须谈一下java的泛型,因为它们联系紧密,我们先看一下这几行代码: Class c1 = n ...
- JAVA类型擦除
Java泛型-类型擦除 一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Num ...
- Java擦除
概述: Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变) ...
随机推荐
- Laravel自定义JSON错误消息 The given data was invalid.
Laravel自定义错误消息 在Laravel验证请求时出现错误,默认会返回如下的错误: 可以看到JSO结构中的message为The given data was invalid.而并非是我们具体自 ...
- Python第八章实验报告
一.实验对象:<零基础学Python>第八章的3道实例和4道实战 二.实验环境:IDLE Shell 3.9.7 三.实验要求:学习使用标准模块和第三方模块 四.实验过程: 实例01 创建 ...
- Navicat Premium 12安装包下载及安装
Navicat Premium 12安装包下载及安装 安装成功了 前提:这个好像是64位的,32位的电脑 我不知道行不行没有试过 1.发邮件17673114272@163.com获取资源后 解压 ...
- 实验九 团队作业6:团队项目编码与Alpha冲刺
项目 内容 课程班级博客链接 2018级卓越班 这个作业要求链接 实验九-团队作业6 团队名称 零基础619 团队成员分工描述 任务1:荣娟,鑫任务2:亚楠,桂婷任务3:亚楠,桂婷任务4:荣娟,鑫任务 ...
- 推荐2020年最好用的JavaScript代码压缩工具
今天就为大家分享一篇关于推荐2020年最好用的JavaScript代码压缩工具,觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随来看看吧 JavaScript 代码压缩是指去除 ...
- 对于利用js实现表单的验证问题--其实菜鸟教程都有啦,但还是想要记录一下
关于利用js实现表单的验证的实现 在jsp页面里面加上名为的标签,然后将以下代码跟奴自己的变量放进去: 记得要放在function的方法里面!!! 之后就需要在form标签里面加上onsubmit=& ...
- Kubecost - Kubernetes 开支监控和管理
️URL: https://www.kubecost.com/ Description: Kubeccost 为使用 Kubernetes 的团队提供实时成本可视化和洞察,帮助您持续降低云成本. 昨天 ...
- DSC:数仓SQL脚本迁移的神奇工具
摘要:本文介绍的DSC工具是针对数据库切换时面临的迁移任务而开发的免安装命令行工具.目的是提供简单.快速.可靠的SQL脚本迁移服务. 本文分享自华为云社区<GaussDB(DWS)DSC工具系列 ...
- MasaFramework入门第二篇,安装MasaFramework了解各个模板
安装MasaFramework模板 执行以下命令安装最新Masa的模板 dotnet new --install Masa.Template 安装完成将出现四个模板 Masa Blazor App: ...
- 学习ASP.NET Core Blazor编程系列三十——JWT登录(4)
学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...