算法-扫描线

目录

什么是扫描线算法?

扫描线简单应用

更多的扫描线


什么是扫描线算法?

        在计算几何中,扫描线算法(scan line algorithm)一般用来解决几何图形的面积交并,周长交并问题,扫描线算法的核心思想是利用扫描线(通常是水平线或垂直线)在几何空间中“扫描”对象,以确定哪些对象与扫描线相交。

        下面我们就来通过求矩形的面积并来介绍扫描线算法。先来看看怎么求下面图形的面积并:

        传统算法是两个矩形面积相加减去重合的面积:

(20−10)∗(20−10)+(25−15)∗(25.5−15)−(20−15)∗(20−15)=180.0

        但是这样算非常的耗费时间,因为每个矩形都需要两两配对,查看互相之间是否有交集。 

        那么我们接下来就想着把矩形分成三部分:

 

于是现在就变成了

( 20 − 10 ) ∗ ( 15 − 10 ) + ( 25.5 − 10 ) ∗ ( 20 − 15 ) + ( 25.5 − 15 ) ∗ ( 25 − 20 ) = 180 

        采取这个方法的好处就是只需要从左往右扫,一步一更新即可,而这个从左往右,或者从下往上扫的思想就是扫描线。


扫描线简单应用

        我们看看上面的图,显然,计算面积需要两个信息

  1.         每个新矩形的的高度。
  2.         每个新矩形的宽度。

        那么我们先从计算宽度说起,其实计算宽度很简单。我们把垂直于x的边单独挑出来然后按照x的大小排个序,隔位相减就可以得到。如kuan[0] = 15 - 10; kuan[1] = 20 -15;......

        然后来计算矩形的高度,这是整个扫描线最难理解的地方。

        首先思考一个问题:为什么二号矩形的高是(10+(25.5−10))呢?很直观的回答就是:那是因为得算上1号矩形高,再加上2号矩形多出来的部分

        那为什么三号矩形的高是(25.5−5)呢?那是因为得用2号矩形的高那部分减去,减掉2号矩形下面多出来的部分 

        那为什么有时候“多出来”是加上一个值,有时候“多出来”是减掉一个值呢?这个问题其实也是得到高度最核心的问题,就是“入边”和“出边”的问题。

        定义:在同一个矩形内,从左往右看,第一条看到的边为“入边”,第二条看到的边为“出边”其实所谓的从左往右(也可以是从上往下),就是扫描线的方向。当从左往右扫,遇到入边的线,则对入边区间扫到进行+1操作,遇到出边,那么对出边区间进行-1操作,这样子就可以解释“有时候“多出来”是加上一个值,有时候“多出来”是减掉一个值”这个问题了

        凭借这个知识,我们来思考步骤

  1. 第一条为入边,区间为[10,20],则区间[10,20] +1(此时区间[10,20] = 1)
  2. 查看整个域的区间,只有[10,20]有值,则Kuan[0]*10 = 50
  3. 第二条边为入边,区间为[15,25.5],则[15,25.5]+1(此时区间[10,15]=1,[15,20]=2,[20,25.5]=1)
  4. 查看整个域区间,从[10,25.5]有值,则Kuan[1]*(25.5-10) = 77.5
  5. 第三条边为出边,区间从[10,20],则[10,20]-1(此时区间为[15,25.5] = 1)
  6. 查看整个区间,从[15,25.5]有值,则Kuan[2]*(25.5-15) = 52.5
  7. 第四条边为出边,区间从[15,25.5],此时-1,区间值变为0
  8. 区间无值,遍历结束。

        这时候问题就来了,总所周知,下标可存不了25.5,而且它这个区间要是特别大,数组会存不下。这时候就可以用离散化来存放下标。

        我们把y坐标离散化用一个区间数组记录每个区间的值:于是现在[10,15]成为块1,[15,20]成为块2,[20,25.5]成为块3。则现在更新第一条入边[10,20]就变成更新[1,3],更新第二条边就变成更新[2,4],之后再查表全部乘起来即可。

        建立一个线段树,用一个cover表示区间[left,right]被覆盖的次数,用len表示这个区间的合法长度,那query(1到n)的合法长度,自然就能返回总共的区间长度了。

int cover[maxn];//存放i节点对应覆盖情况的值
double length[maxn];//存放区间i下的总长度
double yy[maxn];//存放离散后的y值

        仔细观察,这棵树似乎和之前的线段树不一样,它的叶子节点的[l,r]不相等,而是差别为1。
这是因为点对于求面积的题目毫无意义,我们最需要的是它每一个基础的“块”。

        1.第一条为入边,区间为[1,3],则区间cover[1,3] +1(此时区间[1,3] = 1)

        2.query整个域的区间,得到len=10,则sum += Kuan[0]*10 = 50,消去len

        3.第二条边为入边,区间为[2,4],则cover[2,4]+1(注意:这里只需要上推len,不需要下推cover至[2,3]和[3,4],也不需要上推cover至[1,4]。只要找到对应结点的区间能完全覆盖当前线段区间就可以回溯统计了,并不需要更新到叶子节点,这是线段树为什么效率高的原因)

        4.query整个区间,得到len = 15.5,则sum += Kuan[1]*(25.5-10) = 77.5,消去len

        5.第三条边为出边,区间从[1,3],则[1,3]-1

        6.query整个区间,得到10.5,则sum += Kuan[2]*10.5 = 52.5,消去len

        7.第四条边为出边,区间从[15,25.5],此时-1,整个区间没掉

        8.query整个区间,值为0,遍历结束。

        此时sum = 50 + 77.5 + 52.5 = 180,答案正确,这就是线段树用来解决矩形面积并的基本思路了。


更多的扫描线

        除了矩形,三角形,梯形,圆这些几何图形的面积并也可以用扫描线求出。因为扫描线算法的思想其实接近于微积分,即求出每个单位内的微分作积,而求任何几何图形的面积,在数学里我们使用的最多的就是微积分的方法,计算几何中,我们也常常使用自适应辛普森积分公式,格林公式等微积分的方法来求相关值,所以扫描线算法这种模拟微分也是可以的,并且精度方面占点优势:

        等腰三角形的扫描线模型:

        圆离散后的扫描线模型:

        辛普森公式:

        格林公式:

        辛普森积分:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/664831.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day 8:1461. 检查一个字符串是否包含所有长度为 K 的二进制子串

Leetcode 1461. 检查一个字符串是否包含所有长度为 K 的二进制子串 给你一个二进制字符串 s 和一个整数 k 。如果所有长度为 k 的二进制字符串都是 s 的子串,请返回 true ,否则请返回 false 。 截取每个长度为 k 的字符串,加入 Set 中&#x…

wpf listbox实现选中动画

效果如下&#xff1a; 参考&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers/blob/master/src/WPFDevelopers.Samples.Shared/Controls/NavigateMenu/NavigateMenu.xaml 实现上述效果的前台代码&#xff1a; <Windowx:Class"ListBox.MainWindow"…

数据隐私新篇章:Facebook如何保护用户信息

随着数字化时代的到来&#xff0c;数据隐私保护成为了社交媒体平台和用户共同关注的焦点。作为全球最大的社交网络之一&#xff0c;Facebook一直致力于保护用户的隐私和数据安全。本文将深入探讨Facebook在数据隐私保护方面的措施和实践&#xff0c;以及其如何开启数据隐私的新…

C++系列-类模板

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 类模板的定义格式&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; template<class T> class Stack { public:Stack(size_…

u盘文件保密的方法有哪些?关于U盘的使用你要知道这些!

U盘作为便携式的存储设备&#xff0c;被广泛应用于日常工作和生活中。 然而&#xff0c;U盘的丢失或被盗可能导致敏感数据泄露&#xff0c;因此&#xff0c;掌握U盘文件保密的方法至关重要。 本文将介绍几种有效的U盘文件保密方法&#xff0c;并分享关于U盘使用的关键知识&…

BioVendor—Surfactant Protein D Human ELISA

人表面活性剂蛋白D是糖蛋白和钙依赖凝集素胶原亚家族的一员。SP-D是一种同源三聚体蛋白&#xff0c;由三个43kDa单元组成&#xff0c;这些单元在它们的中间结合。大多数SP-D主要含有十二聚体(四个三聚体亚单位)&#xff0c;但也观察到更高的多聚体。每个单元由至少四个离散的结…

旧衣回收小程序带来的收益优势,小程序有哪些功能?

随着互联网的快速发展&#xff0c;大众对旧衣回收市场也越来越了解&#xff0c;对于闲置的旧衣物也有了适合的处理方式。旧衣回收也符合了当下资源回收利用&#xff0c;因此&#xff0c;旧衣回收市场获得了爆发式增长&#xff0c;市场规模不断扩大。同时市场中还吸引了越来越多…

记录岁月云明细账excel导出的性能优化

财务软件报表还是非常麻烦&#xff0c;因为使用excel最好的就是财务&#xff0c;但是通过java导出excel&#xff0c;使用easyexcel不用报表工具&#xff0c;不是这么容易。采用jprofile对一个导出操作进行监控&#xff0c;其中一家零售企业导出当月全部明细账&#xff0c;检测到…

MySQL数据库--从创建数据库到删库跑路

目录 MySQL安装: 1. 数据库基本操作1.1 创建数据库1.2 显示当前数据库1.3 删除数据库1.4 使用数据库/选中数据库 2. SQL中的数据类型2.1 数值类型2.2 字符串类型2.3 时间类型 3. 表的操作3.2 创建表3.1 显示数据库中的表3.3 查看表的详细情况3.4 删除表3.5 注释3. 修改列(了解即…

dubbo复习:(18)服务端Filter

用来在服务响应返回到客户端之前进行额外处理。 一、定义Filter package cn.edu.tju.config;import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Invocation; import org.apache.du…

检定记录内容解析:非红外二氧化硫气体检测仪的维护与验证

在工业生产与环境保护中&#xff0c;二氧化硫作为一种常见的有害气体&#xff0c;其浓度的监测和控制显得尤为重要。 非红外二氧化硫气体检测仪以其独特的检测原理和高灵敏度&#xff0c;在二氧化硫监测领域发挥着不可或缺的作用。 在这篇文章中&#xff0c;佰德将详细介绍非…

神经网络与深度学习——第4章 前馈神经网络

本文讨论的内容参考自《神经网络与深度学习》https://nndl.github.io/ 第4章 前馈神经网络 前馈神经网络 神经元 Sigmoid型函数 Hard-Logistic函数和Hard-Tanh函数 ReLU函数 带泄露的ReLU 带参数的ReLU ELU函数 Softplus函数 Swish函数 GELU函数 Maxout单元 网络结构 前馈网络…

CentOS 7基础操作02_优化Linux操作系统中的服务

1、实验环境 公司在文件服务器中新安装了CentOS系统.由于默认启动的服务程序较多&#xff0c;系统运行缓慢。现需要对系绞服务进行适当优化&#xff0c;减少一些不必要的自启动服务.并设置系统在开机后直接进入字符模式。 2、需求描述 根据实际使用需求对CentOS 7操作系统中的…

PLC无线通讯模块

在工业自动化日益深入的今天&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;作为工业控制的核心大脑&#xff0c;其功能的扩展和智能化水平直接影响着整个生产线的效率和安全性。而PLC无线通讯模块&#xff0c;作为连接PLC与外界信息世界的桥梁&#xff0c;其重要性不…

揭秘Python:下划线的特殊用法,你绝对想不到!

在Python编程中&#xff0c;下划线&#xff08;underscore&#xff09;是一个常见而又强大的工具。它不仅仅是一个普通的字符&#xff0c;而是具有特殊含义和用法的符号。今天&#xff0c;我们就来揭开Python下划线的神秘面纱&#xff0c;探索它的各种妙用。 下划线的基本用法…

前端html-docx实现html转word,并导出文件,文字+图片

前端html-docx实现html转word&#xff0c;并导出文件 前端web页面 有文字&#xff0c;有图片&#xff0c;保存web的css效果 使用工具&#xff1a;html-docx 官方网址&#xff1a;http://docs.asprain.cn/html-docx/readme.html 步骤&#xff1a; 1 npm install html-docx-js…

边缘网关在数据采集方面发挥的作用-天拓四方

随着物联网技术的快速发展&#xff0c;边缘网关作为连接物理世界与数字世界的桥梁&#xff0c;其重要性日益凸显。特别是在数据采集方面&#xff0c;边缘网关以其独特的优势&#xff0c;为物联网系统的运行和管理提供了强大的支持。本文将从边缘网关的基本概念、数据采集流程、…

vcruntime140_1.dll在哪个文件夹?详细修复vcruntime140_1.dll缺失的方法

vcruntime140_1.dll文件是什么&#xff1f;相信很多人都对它很陌生吧&#xff1f;毕竟大部分人对于dll文件还是了解得太少了&#xff0c;当突发情况出现vcruntime140_1.dll文件丢失&#xff1f;你要怎么办&#xff1f;不要担心&#xff0c;下面我们就来给大家详细的讲解一下修复…

记一次netty客户端的开发

背景 近日要开发一个tcp客户端程序去对接上游厂商的数据源&#xff0c;决定使用netty去处理&#xff0c;由于很久没有开发过netty了&#xff0c;顺便学习记录下 netty搭建 考虑到我们需要多个client去对接server服务&#xff0c;所以我们定义一个公共的AbstractNettyClient父…

2024最新智能优化算法:常春藤算法(Ivy algorithm,LVYA)求解23个函数,提供MATLAB代码

一、常春藤算法 常春藤算法&#xff08;Ivy algorithm&#xff0c;LVYA&#xff09;是Mojtaba Ghasemi 等人于2024年提出智能优化算法。该算法模拟了常春藤植物的生长模式&#xff0c;通过协调有序的种群增长以及常春藤植物的扩散和演化来实现。常春藤植物的生长速率是通过微分…