擦除区域与橡皮大小不一致

测试反馈,擦除区域与真实的橡皮大小不一致:

上图中,橡皮显示是圆形的,但擦除效果是一个“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边形的更多相关文章

  1. JDK5.0新特性(静态导入、自动装箱/拆箱、增强for循环、可变参数、枚举、泛形)

    JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效.清晰,安全的代码. 这些新特性主要有:1.静态导入2.自动装箱/拆箱3.增强for循环4.可变参数5.枚举6.泛型7 ...

  2. JavaBean 内省API BeanUtils工具 泛型 xml xml约束

    1 什么是JavaBean?有何特征? 1)符合特定规则的类    2)JavaBean分二类:     a)侠义的JavaBean         .私有的字段(Field)         .对私 ...

  3. 五、Java基础加强

    Java基础加强 1.MyEclipse的使用工作空间(workspace).工程(project)在eclipse下Java程序的编写和运行,及java运行环境的配置.快捷键的配置,常用快捷键:内容 ...

  4. javase(14)_java基础增强

    一.Eclipse的使用 1.在eclipse下Java程序的编写和run as,debug as,及java运行环境的配置. 2.快捷键的配置,常用快捷键: •内容提示:Alt + / •快速修复: ...

  5. Java泛型-类型擦除

    一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变 ...

  6. Java泛型:类型擦除

    类型擦除 代码片段一 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String& ...

  7. java之集合类框架的简要知识点:泛型的类型擦除

    这里想说一下在集合框架前需要理解的小知识点,也是个人的肤浅理解,不知道理解的正不正确,请大家多多指教.这里必须谈一下java的泛型,因为它们联系紧密,我们先看一下这几行代码: Class c1 = n ...

  8. JAVA类型擦除

    Java泛型-类型擦除 一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Num ...

  9. Java擦除

    概述: Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变) ...

随机推荐

  1. 并发QPS公式估算

    一.经典公式1: 一般来说,利用以下经验公式进行估算系统的平均并发用户数和峰值数据 1)平均并发用户数为 C = nL/T 2)并发用户数峰值 C' = C + 3*根号C C是平均并发用户数,n是l ...

  2. MonGdb#Mac安装

    1.下载 # 进入 /usr/local cd /usr/local # 下载 sudo curl -O https://fastdl.mongodb.org/osx/mongodb-osx-ssl- ...

  3. 记我的第一个UVM项目

    没有天天写博客的习惯,后果就是老是忘记自己的排版风格.为了追求统一还要翻一下之前是怎么写的.这也算是意料之外的发现吧. 说实话,没人教的话从零开始学一个新的东西实在是太难了.即使互联网的存在已经大幅降 ...

  4. MYSQL DUAL(伪表)

    #DUAL是一个伪表,不存在的表. SELECT 8*9 FROM DUAL #输出72

  5. python的elasticsearch模块

    参考 https://www.cnblogs.com/tianzhh/articles/13542239.html

  6. WEB/H5测试标准

  7. Mongodb between 时间范围

    db.getCollection("Order").find({ "Supplier.ServiceCode": "CNI", " ...

  8. windows下使用Wireshark调试chrome浏览器的HTTP/2流量

    1.在Wireshark官网(https://www.wireshark.org/#download)下载对应的Wireshark安装包,进行安装 2.增加系统环境变量设置(计算机 -- 右键 -- ...

  9. 局部异常因子(Local Outlier Factor, LOF)算法详解及实验

    局部异常因子(Local Outlier Factor, LOF)通过计算样本点的局部相对密度来衡量这个样本点的异常情况,可以算是一类无监督学习算法.下面首先对算法的进行介绍,然后进行实验. LOF算 ...

  10. 加密脚本分析—evil.py

    加密脚本分析-evil.py 1.题目 源文件 一共两个文件 enc_flag.txt evil.py(原文件无注释) 1 # coding: utf-8 2 3 import base64 4 im ...