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>(不可协变) ...
随机推荐
- 并发QPS公式估算
一.经典公式1: 一般来说,利用以下经验公式进行估算系统的平均并发用户数和峰值数据 1)平均并发用户数为 C = nL/T 2)并发用户数峰值 C' = C + 3*根号C C是平均并发用户数,n是l ...
- MonGdb#Mac安装
1.下载 # 进入 /usr/local cd /usr/local # 下载 sudo curl -O https://fastdl.mongodb.org/osx/mongodb-osx-ssl- ...
- 记我的第一个UVM项目
没有天天写博客的习惯,后果就是老是忘记自己的排版风格.为了追求统一还要翻一下之前是怎么写的.这也算是意料之外的发现吧. 说实话,没人教的话从零开始学一个新的东西实在是太难了.即使互联网的存在已经大幅降 ...
- MYSQL DUAL(伪表)
#DUAL是一个伪表,不存在的表. SELECT 8*9 FROM DUAL #输出72
- python的elasticsearch模块
参考 https://www.cnblogs.com/tianzhh/articles/13542239.html
- WEB/H5测试标准
- Mongodb between 时间范围
db.getCollection("Order").find({ "Supplier.ServiceCode": "CNI", " ...
- windows下使用Wireshark调试chrome浏览器的HTTP/2流量
1.在Wireshark官网(https://www.wireshark.org/#download)下载对应的Wireshark安装包,进行安装 2.增加系统环境变量设置(计算机 -- 右键 -- ...
- 局部异常因子(Local Outlier Factor, LOF)算法详解及实验
局部异常因子(Local Outlier Factor, LOF)通过计算样本点的局部相对密度来衡量这个样本点的异常情况,可以算是一类无监督学习算法.下面首先对算法的进行介绍,然后进行实验. LOF算 ...
- 加密脚本分析—evil.py
加密脚本分析-evil.py 1.题目 源文件 一共两个文件 enc_flag.txt evil.py(原文件无注释) 1 # coding: utf-8 2 3 import base64 4 im ...