算法-扫描线

news2024/11/24 0:20:29

目录

什么是扫描线算法?

扫描线简单应用

更多的扫描线


什么是扫描线算法?

        在计算几何中,扫描线算法(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,答案正确,这就是线段树用来解决矩形面积并的基本思路了。


更多的扫描线

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

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

        圆离散后的扫描线模型:

        辛普森公式:

        格林公式:

        辛普森积分:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AC/DC电源模块:应用于工业自动化领域

BOSHIDA AC/DC电源模块:应用于工业自动化领域 AC/DC电源模块是一种用来将交流电转换为直流电的电源模块。它在工业自动化领域有着广泛的应用,可以为各种设备和系统提供稳定可靠的电力供应。 一,AC/DC电源模块在工业自动化领域中起到了稳定…

洞察全球商机:精细化策略引领海外营销平台对接

随着全球市场的不断融合和互联网技术的飞速发展,企业越来越意识到海外营销与客服系统对接的重要性。 NetFarmer,作为一家专注于服务企业数字化出海的公司,对于海外市场的洞察和对接策略有着独特的见解。今天运营坛将深入探讨海外营销平台对接…

上市医疗巨头构建330+项自动化场景,实在Agent驱动效率与效益双重飞跃

历经二十年的快速发展,中国医疗信息化已迈入一个崭新阶段,其特征是产业链的高度集成、跨部门协同作业以及信息化的深度渗透。这一阶段不仅要求医护人员聚焦于以患者为中心的高质量服务,还提出了新挑战,即如何高效处理信息化系统伴…

Linux —— MySQL操作(1)

一、用户与权限管理 1.1 创建与赋予权限 create user peter% identified by 123465 # 创建用户 peter,# %:允许所有用户登录这个用户访问数据库 刚创建的新用户是什么权限都没有,需要赋予权限 grant select on mysql.* to peter%; # 赋予…

LeetCode2542最大子序列的分数

题目描述 给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,两者长度都是 n ,再给你一个正整数 k 。你必须从 nums1 中选一个长度为 k 的 子序列 对应的下标。 对于选择的下标 i0 ,i1 ,…, ik - 1 ,你的 …

微信小程序区分运行环境

wx.getAccountInfoSync() 是微信小程序的一个 API,它可以同步获取当前账号信息。返回对象中包含小程序 AppID、插件的 AppID、小程序/插件版本等信息。 返回的对象结构如下: 小程序运行环境,可选值有:develop(开发版&…

java实现地形dem产汇流流场数据提取解析

一、基础概念 在GIS和气象学、海洋学、大气科学、水文学等领域,"提取流场"通常指的是从数据集中识别和分析流体(如水流、风场、洋流、大气流)的运动模式和流向的过程。这个过程涉及数据处理、可视化和分析技术,下面是提…

【计算机网络】——概述(图文并茂)

概述 一.信息时代的计算机网络二.互联网概述1.网络,互连网,互联网(因特网)1.网络2.互连网3.互联网(因特网) 2.互联网简介1.互联网发展的三个阶段2.互联网服务提供者(ISP)3.互联网的组…

知了汇智携手川农大,为计算机学子打造实战型综合项目实训

随着数字化产业的迅猛发展和产业数字化转型的不断深入,产业对数字人才的需求也在发生变化。为了培养适应市场需求的高素质应用型人才,5月24日,知了汇智携手四川农业大学,为信息工程学院计算机科学与技术专业22级学子带来一场兼具实…

JDK JRE JVM 三者的关系

总结: 1. jdk 中 的 javac 编译器将 .java 文件编译为 .class 字节码文件 (编译) 2. jre 执行 .class 字节码文件 (运行) 3. jre 通过 jvm 运行程序,确保程序能够在不同平台上正确执行(实现跨平…

Operation not allowed when innodb_forced_recovery > 0.

到mysql的配置文件中 把这行注释掉

第N3周:Pytorch文本分类入门

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 这里借用K同学的一张图片大致说明本次任务流程。 1.本次所用AG News数据集介绍 AG…

医院内跌倒的预测模型构建(Boruta+lightgbm+DCA分析)

医院内跌倒的预测模型构建(BorutalightgbmDCA分析) 跌倒有时候是很严重的事情,常常听说骨质疏松的老年人跌倒后造成髋骨骨折,导致长期卧床,进而导致肌肉萎缩、肺炎等等并发症,最终导致不良预后。医院内的跌…

AWS中国峰会2024 半日游

亚马逊云科技中国峰会于2024年5月29-30日在上海举办 今年就去了半天,去年也是去过的,不过今年的活动个人感觉比去年略微凌乱了一点。 今年的峰会方向和去年一致,均是AI方向的各项内容(基础架构、安全、服务、游戏、驾驶、各行各…

node版本切换

vue项目,有的项目需要低版本,有的又需要高版本,不能每次都卸载安装之类的吧,就想着怎么能切换版本使用,搜索资料最终使用nvm来进行node版本管理,下面是使用方法: 1.下载node版本管理器NVM 下载…

【Linux】多线程——线程概念|进程VS线程|线程控制

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:理解【Linux】多线程——线程概念|进程VS线程|线程控制 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! &…

msf攻击windows实例

环境:攻击机kali(192.168.129.139),目标机windows10(192.168.129.132) 方法一:通过web站点,使用无文件的方式攻击利用执行(命令执行漏洞) 方法二&#xff1…

Android 开机动画的启动过程BootAnimation(基于Android10.0.0-r41)

文章目录 Android 开机动画的启动过程BootAnimation(基于Android10.0.0-r41)1.开机动画的启动过程概述2.为什么设置了属性之后就会播放? Android 开机动画的启动过程BootAnimation(基于Android10.0.0-r41) 1.开机动画的启动过程概述 下面就是BootAnimation的重要部…

香橙派开发板测评:探索创新的嵌入式解决方案

嵌入式系统在当今科技领域中扮演着越来越重要的角色,而开发板作为嵌入式系统设计的核心工具,不断推动着创新的边界。在众多开发板中,香橙派(Orange Pi)系列以其出色的性能和丰富的接口,备受开发者的青睐。本…

xss漏洞学习(题解)

1.简单知识点回顾 XSS允许恶意web用户将代码植入到提供给其它用户使用的页面中。 特点:能注入恶意的HTML/JavaScript代码到用户浏览器网址上,从而劫持会话 类型: DOM型:属于反射型的一种,利用非法输入来闭合对应的h…