转载请注明出处:https://blog.csdn.net/sunmmer123

正文开始前,先念叨几句,自2018年停博之后,再次提笔开始记录。
感谢时隔2年无更新的情况下,还未跑路的粉丝们!
感谢大家对我前俩篇关于音视频博文的支持!
希望这篇文章在自我复盘的同时也能帮助到大家!

看完这篇博客,诚邀感兴趣的各位参与脑暴,在评论区留言讨论,谈一谈你的想法方案或者问题。


1、功能需求

在画板上可以对铅笔图元进行圈选然后进行一系列操作
如下图,粗略的展示下这个功能:

2、功能分析

  • 对于这个问题,在处理一段完整的铅笔绘图的时候很简单
  • 对于被橡皮擦除了一部分铅笔图元来说,我们就需要把这段图元做拆解了,分成多段铅笔图元
  • 画满整个屏幕的时候,线段巨多,那么分解的工作就会沉重,效率就会低下,自然呈现的效果就是卡顿了

3、问题总结

那么如何将一个完整铅笔图元拆成多个,怎样拆能更快就是具体要思考和解决的问题了

4、我的实现方案

  • 将绘制的图元绑定相对应得矩阵,也就是说每一笔铅笔绘图或者擦除区域都有他们自己的一个二维数组,而这个二维数组就是一个矩阵
  • 这个二维数组里面存放的信息只有0和1,0未被占用,1占位标明该像素被占用
  • 当擦除区与铅笔绘图有相交时,遍历将铅笔绘制的这个图元的矩阵所对应的位置的信息改成0,表示已经被擦除了,像素没有被占用了
  • 最后遍历矩阵,每到为0的时候就说明是一段图元的结尾位置,这样就能将一个线段在经历擦除之后生成多段了

看到了这,已经是晕头转向了,我们具体看下代码

1、俩个对象

  • 铅笔
  • 橡皮擦
  • 对象里分别存放的信息就是画笔对象以及点数据和对应的矩阵对象

2、关于矩阵

  • 其实也就是一个二维数组,绘制的每一个图形都有他自己的所在的矩阵区域
  • 简单的理解就是你画了一条线,将这条线转换成一个矩阵
  • 矩阵对象里面存放的信息:顶点坐标,长宽、二维数组
  • 如图,也就是绿框这个区域:

3、将图元转成矩阵

在onTouchEvent中只有当up的时候,才去将生成对应得矩阵对象
具体流程如下:

  • 获取到绘制Path上所有的点,铅笔的就是拿这个铅笔path,橡皮擦的话就拿橡皮擦的path
  • 通过computeBounds方法获取path的闭合区域边界
  • 确定这个矩阵的顶点坐标以及宽高
  • 根据宽高初始化定义矩阵的二维数组
  • 循环所有的点,将点对应的二维数组索引的这个地方数据设置为1,表示该像素被占用

4、过滤线段(取出真正被擦除的线段)

当橡皮擦抬手,设置完橡皮擦的矩阵对象之后,就开始处理分段逻辑

  • 判断橡皮擦移动擦除的区域是否与铅笔图元(线段)相交
  • 取出相交的铅笔图元(线段)整理到一个几个中
  • 以上执行这种是否相交过滤取线段的方法属于一个小细节优化处,因为可能在屏幕上画了好多条线段,我擦除的可能只是一条线段的区域,那么去分段的时候遍历所有的线段集合就没有必要了,所以先把与擦除区域有相交的线段取出
  • 判断相交的主要逻辑就是通过computeBounds方法获取橡皮擦的区域和线段的区域,调用系统是否相交的方法判断

5、处理线段矩阵里的信息

  • 接着循环橡皮擦矩阵区域,当遇到像素点为1的时候,将相交的这笔线段对应的矩阵这个位置数据设置为0,表示已经被擦除了,没有像素被占用了

看到这,肯定一直疑惑这个矩阵他到底是用来干嘛的?用0,1具体是要做什么事?

  • 博文从标题开始就在围绕一个问题"如何将一条线段分成多段",那么分段分段,只有具体一个标识告诉我这里开始被截断了,我才能分
  • 所以这个矩阵的作用就当于帮助我分段的工作,0,1就是告诉我是否是截断了
  • 回顾下铅笔图元对象Pen,它里面有个点集合变量,一条线段就是由多个点组成的,这个点对象存放的x,y坐标和一个是否被擦除的标识布尔值
  • 接下去就把点里的这个是否擦除标识根据矩阵0,1做判断设置值,循环遍历所有点,获取矩阵索引,判断当前位置是否1,是的话标识该点没有被擦除,0的话就是这个点被擦除了

6、开始分段

经过一系列数据操作之后,开始真真实实的分段处理吧

  • 一条线段中所有点都知道是否是被截断得了,那么就循环遍历就好了,遇到标识了被擦除的点的时候,就生成一个新的铅笔对象吧

7、遗留问题

  • 当我画面整个屏幕的时候,此时这个线段中的点数据是很多的,同时他的整个矩阵区域也是很大的,当我擦除区域也很大的时候,分段过程繁重,整体给的一个效果就是慢下来了
  • 如下图,演示一下:

总结

至此,整个流程实现方案就说完了,不知道大家有没有看懂呢。如果你有兴趣,或者遇到类似功能需要完成以及有更好的实现方案,可以下方评论区留言讨论,需要源码研究的小伙伴也可留言私信我!!

如何将一条线段分成多段相关推荐

  1. cad2017单段线_CAD将线段分成多段线的方法步骤

    很多CAD里面的线段都是一条线的,所以我们有时候需要用到多段线时直接将线段分解.那么大家知道CAD如何将线段分成多段线吗?预支详细操作步骤,欢迎点击以下教程! CAD将线段分成多段线的方法1 步骤一: ...

  2. ArcEngine编辑模块——将线段按距离、按比例分割成N条线段

    1.前言 前面一篇博客介绍了如何按距离或按比例将1条线段分成2条线段的方法,核心就是利用IFeatureEdit接口的Split方法进行分割.但就像之前说的,该方法只适用于将1条线段分成2条线段,如果 ...

  3. arcgis将直线等分_如何快速定数等分一条线段?

    在日常的CAD绘图工作中,我们常常需要对精准的等分各种线段线条.现在已知线段等分主要是分为定数和定距等分.其中定数等分的命令是:DIVIDE.,快捷键是 div.那么我们该如何快速定数等分一条线段呢? ...

  4. 两条线段的夹角 cesium_《原本》命题1.10 一条线段可以被分成两条相等的线段

    命题1.10 一条线段可以被分成两条相等的线段 设:AB为一条直线. 求作:平分为两条相等的线段. 作等边三角形ABC(命题1.1) 命题1.1已知一条线段可作一个等边三角形. 作∠ACB的角平分线C ...

  5. Java黑皮书课后题第9章:**9.12(几何:交点)假设两条线段相交。第一条线段的两个端点是(x1, y1)和(x2, y2),第二条线段的两个端点是(x3, y3)和(x4, y4)

    Java黑皮书课后题第9章:**9.12(几何:交点)假设两条线段相交.第一条线段的两个端点是(x1, y1)和(x2, y2),第二条线段的两个端点是(x3, y3)和(x4, y4) 题目 破题 ...

  6. 平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。

    题目:平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小. 源码如下: 1 #include <iostream> 2 #include <string.h> 3 ...

  7. 三行九个点,用4条线段连接(扩展,用3条,用1条)

    题目:请使用4条线段连接以下9个点 .   .    . .   .    . .   .    . 答案: o ━━o ━o━━ ┃\ / ┃ \ / o o o ┃ \ / ┃ /\ o o o ...

  8. N条线段求交的扫描线算法

    转载自:http://johnhany.net/2013/11/sweep-algorithm-for-segments-intersection/ N条线段求交的扫描线算法 在对图进行计算时,很常用 ...

  9. Bentley-Ottmann算法:求N条线段的交点

    Bentley-Ottmann算法:求N条线段的交点 Bentley-Ottmann算法 算法复杂度 1. 使用暴力求解,遍历每一条线段 i ,固定 i 遍历 j 与 i 是否存在交点: 2. 此时我 ...

最新文章

  1. 在java的实现栈的插入数据_Java实现数据结构栈stack和队列Queue
  2. 朴素贝叶斯法分类器的Python3 实现
  3. 【学习笔记】分析函数(开窗函数)
  4. 前端实习生笔试_2016春网易前端暑期实习生笔试面经(二面已挂)
  5. LTE各场景下的密钥处理
  6. Android应用程序请求SurfaceFlinger服务创建Surface的过程分析
  7. jeecg下实现自动默认模糊查询
  8. Anaconda jupyter-notebook 添加kernel
  9. 你的公司,远程办公多久了?
  10. JS 语法糖 0 —— 解构
  11. DataNode 运行状况
  12. php解析mht,php解析mht文件转换成html的实例详解
  13. Emulex:融合是一切发展的基础
  14. 荣耀A55高调上市只为孤独求败?
  15. 《死神》现队长、原队长和假面的对照
  16. WIN 10关闭更新
  17. 使用metalink批量下载sentinel数据
  18. 重装VS6时,弹出Setup Was Unable to Create a DCOM User Account错误的解决方法
  19. spss/amos评价分类(问卷调查)matlab(模糊综合评价+AHP层次分析法模型)
  20. mysql主从复制mmm_MMM+MYSQL主从同步

热门文章

  1. 手机网页设置摇一摇效果
  2. 2021实施工程师面试记录(一) oracle,tomcat,Linux
  3. 58同城网站的一些想法
  4. 这些年我用过的 6个API 接口文档平台,真的好用
  5. 【八】 H.266/vvc中对称MVD模式(SMVD)
  6. Spark实现WordCount的11种方式,你知道的有哪些?
  7. idc运维怎么转linux运维,IDC运维怎么便捷配置机房交换机
  8. MDM经理如何为主要利益相关方加速创造价值 - 第一部分:消除重复的客户信息
  9. 前端页面几种常见的布局方式
  10. MAVLink协议详解