求任意多边形直径算法设计
凸多边形 直径 叉积

凸多边形直径叉积凸多边形直径叉积是一个重要的几何概念,它可以帮助我们推导出多边形的一些性质和公式。
在本文中,我们将深入探讨这个概念,并介绍一些相关的定理和应用。
首先,我们来看一下什么是凸多边形直径。
凸多边形是指所有内角都小于180度的多边形,而直径是指连接凸多边形中任意两个点的最长线段。
因此,凸多边形直径就是凸多边形中最长的线段。
接下来,我们来介绍凸多边形直径叉积的概念。
凸多边形直径叉积是指将凸多边形沿着直径剖分成两个三角形,然后计算这两个三角形的面积乘积的和。
具体来说,假设凸多边形的直径长度为d,将其剖分成两个三角形ABC和ABD,其中AB是直径,C和D是凸多边形的两个顶点。
则凸多边形直径叉积为S(ABC)×S(ABD),其中S(ABC)和S(ABD)分别表示三角形ABC和ABD的面积。
那么凸多边形直径叉积有什么用处呢?它可以帮助我们推导出凸多边形的一些性质和公式。
下面我们来介绍一些相关的定理和应用。
定理1:凸多边形直径长度不超过多边形任意两点间的距离的最大值。
证明:假设凸多边形的直径长度为d,将其剖分成两个三角形ABC 和ABD。
由于AB是直径,所以AC和BD是多边形内任意两点间的最短路径。
因此,我们有AC+BD≥AB=d。
另一方面,根据三角形面积公式,S(ABC)×S(ABD)=d×h1/2×d×h2/2=d2×h1×h2/4,其中h1和h2分别是三角形ABC和ABD的高。
由于h1和h2都不超过多边形任意两点间的距离的最大值,所以S(ABC)×S(ABD)≤(d/2)2×(max distance)2。
因此,我们有d≤max distance。
定理2:凸多边形内任意两点间的最短路径一定在凸多边形的直径上。
证明:假设多边形内任意两点间的最短路径不在凸多边形的直径上,那么这两个点将被直径所分割成两个三角形。
scratch创意编程《画任意正多边形》的教学设计

scratch创意编程《画任意正多边形》的教学设计西南交通大学附属小学苏忠教学内容《Scratch趣味编程语言2.0》教学目标1.知识与技能:学会使用模块中的指令。
学会使用模块中的和指令。
学会使用模块中的指令。
2.过程与方法:培养学生“分析问题——抽象建模——算法设计——编程执行”的计算思维能力。
3.情感态度价值观:引导学生从实际生活中发现问题素材,培养学生的信息意识。
增强学生学习scratch编程语言的兴趣。
教学重点模块中的指令使用教学难点培养学生“分析问题——抽象建模——算法设计——编程执行”的计算思维能力。
教学准备Scratch编程语言2.0,卡搭云教室,画任意正多边形scratch程序范例教学过程一.创设现实问题情景情景描述:小明和小红在操场上玩游戏,小明说:“小红,你能按我的指令在地面上行走吗?”,小红说:“好啊!发指令吧?”,小明说:“走一个正三角形,走一个正方形,走一个正五边形……”,小红说:“等等,正五边形我不会走了!,告诉我该怎么走?”,小明说:“我也不太会,让我想想……”。
同学们,你能用我们学过的scratch编程帮他们解决怎么行走吗?师生共同分析情景得出问题:“小红怎样才能走出符合要求的形状?。
”二.分析界定问题根据问题情景,界定出需要scratch解决的问题:“从键盘给变量‘边数’赋值,根据‘边数’的值,画出对应的正多边形”分析舞台背景:由于只需要呈现出正多边形的图形,所以舞台背景没有特别要求,背景使用默认的白色背景。
分析角色:“小猫”,“画正几边形?,”“输入框”抽象建模师生共同用图形分析画正三角形和正方形的方法,如下图1、2:(抽象建模过程)师生共同用图表分析画正五边形和正六边形的方法,如下表1:(抽象建模过程)三.算法设计解决问题学生根据自己的分析结果,用流程图描述算法,如下图3:四.编写程序运行、调试教师运行示范程序,观察运行结果,如下图4:学生根据流程图完成自己程序的编写、调试,观察运行结果。
具有拓扑关系的任意多边形裁剪算法

具有拓扑关系的任意多边形裁剪算法拓扑关系是指在空间中,几何对象之间的相对位置和连接关系。
任意多边形裁剪算法是指对于两个多边形A和B,确定A相对于B的位置关系,并将A裁剪成相对于B的部分。
常用的具有拓扑关系的任意多边形裁剪算法有Sutherland-Hodgman算法和Weiler-Atherton算法。
Sutherland-Hodgman算法是一种简单而直观的裁剪算法,它以多边形A为基础,对多边形A的每条边进行裁剪,最终得到所需的裁剪结果。
算法步骤如下:1.对于裁剪窗口的每条边界,确定其相对于多边形A的左侧。
2.对多边形A的每条边进行裁剪处理,生成新的顶点序列。
3.重复步骤2,直到对所有的边界完成处理。
4.返回裁剪结果。
其中,对于多边形A的每条边进行裁剪处理的具体步骤如下:1.对于多边形A的每条边,判断边的起点和终点是否在裁剪窗口内。
2.如果起点和终点都在窗口内,则将边加入新的顶点序列。
3.如果起点在窗口内,而终点在窗口外,则计算边与窗口边界的交点,并将交点加入新的顶点序列。
4.如果起点在窗口外,而终点在窗口内,则计算边与窗口边界的交点,并将交点作为起点加入新的顶点序列。
5.如果起点和终点都在窗口外,则忽略这条边。
Sutherland-Hodgman算法的优点在于简单易懂,对于凸多边形和凹多边形都适用,但由于其每条边都需要进行裁剪处理,效率较低。
Weiler-Atherton算法是一种基于点集的裁剪算法,它将两个多边形视为点的集合,并通过点集之间的拓扑关系进行裁剪操作。
算法步骤如下:1.对于多边形A和多边形B,找到它们的交点。
2.根据交点和各自的顺时针或逆时针顺序,将交点按序列分别加入多边形A和多边形B的顶点序列。
3.对多边形A和多边形B的顶点序列进行裁剪处理,得到裁剪结果。
Weiler-Atherton算法的优点在于避免了对每条边进行裁剪的操作,对于复杂多边形的裁剪效果好,但实现较为复杂。
以上是具有拓扑关系的任意多边形裁剪算法的简要介绍。
如何计算任意多边形的面积和周长

如何计算任意多边形的面积和周长计算任意多边形的面积和周长是一个常见的数学问题,它在各个领域中都有广泛的应用。
本文将介绍几种常见的计算方法,并探讨它们的优缺点。
一、面积的计算方法1.1 面积的基本原理任意多边形的面积可以通过将其分割成若干个三角形,再计算每个三角形的面积,最后将所有三角形的面积相加得到。
这是计算多边形面积的基本原理。
1.2 面积的计算公式对于任意多边形,可以使用海伦公式或矢量叉积公式来计算其面积。
海伦公式是一种基于多边形的边长和角度的计算方法。
它的公式为:面积= √(s * (s - a) * (s - b) * (s - c))其中,s是多边形的半周长,a、b、c是多边形的边长。
矢量叉积公式是一种基于多边形的顶点坐标的计算方法。
它的公式为:面积 = 0.5 * |(x1 * y2 - x2 * y1) + (x2 * y3 - x3 * y2) + ... + (xn * y1 - x1 * yn)|其中,(x1, y1)、(x2, y2)、...、(xn, yn)是多边形的顶点坐标。
1.3 面积计算方法的比较海伦公式适用于计算任意多边形的面积,但需要知道多边形的边长和角度。
而矢量叉积公式适用于计算任意多边形的面积,只需要知道多边形的顶点坐标。
因此,在实际应用中,根据已知的数据选择合适的计算方法。
二、周长的计算方法2.1 周长的基本原理任意多边形的周长可以通过将其所有边长相加得到。
这是计算多边形周长的基本原理。
2.2 周长的计算公式对于任意多边形,可以直接将其所有边长相加来计算周长。
2.3 周长计算方法的比较计算多边形周长的方法相对简单,只需要将所有边长相加即可。
无论多边形的形状如何,都可以使用这种方法来计算周长。
三、计算方法的应用3.1 地理测量在地理测量中,计算任意多边形的面积和周长是非常重要的。
例如,在土地测量中,需要计算土地的面积和周长来确定其价值和使用限制。
3.2 工程设计在工程设计中,计算任意多边形的面积和周长是常见的任务。
具有拓扑关系的任意多边形裁剪算法

具有拓扑关系的任意多边形裁剪算法中国的地理空间数据处理发展迅速,形状分析技术受到技术界的广泛应用。
多边形裁剪是一种常见的形状分析技术,它可以用来从空间数据集中提取出多边形范围内的空间对象,以便进行深入分析和分类处理,同时也可以用来测量多边形的面积和周长等。
具有拓扑关系的多边形裁剪算法是多边形裁剪的一种,它可以从拓扑关系的多边形中提取出正确的多边形边界,而不用考虑多边形的内部点和边的连接关系。
这种算法的特点是,可以对多边形的边缘点和其他类型的点进行分类,考虑到其它多边形的拓扑关系,分析出能够完整描述多边形的边界,从而为后续空间数据处理提供了一种有效的算法。
具有拓扑关系的多边形裁剪算法的基本原理是:首先通过计算多边形内部点和边缘点之间的拓扑关系,对所有多边形内点进行分类;然后针对每个分类,采用多边形切割算法,将一个多边形分割成多个小的多边形,每个小的多边形的定义由多边形的点和边组成;最后,根据分类后的多边形点和边之间的拓扑关系,对经过分割的多个多边形边界重新进行切割,完成裁剪。
该算法与其他常见的多边形裁剪算法相比,有着明显的优势。
第一,由于该算法采用多边形分割算法和拓扑关系分析算法相结合,它能够有效地处理多边形内部点和边缘点之间的拓扑关系,从而达到较高的准确性和可靠性;第二,该算法的实现不需要大量的预处理,复杂度较低,从而大大减少了算法执行时间;第三,该算法能够有效处理多边形中出现的不闭合、重叠等异常状况,从而得到更加准确的结果。
实际应用中,该算法可以用来自动提取多边形边界,从而检测出满足特定要求的多边形,从而为后续多边形分析和处理提供可靠的基础数据。
此外,该算法也可以用来检测多边形的内部是否存在大量的噪声,以便及时采取措施将其消除,保证多边形的精确性和准确性。
总之,具有拓扑关系的多边形裁剪算法是一种有效而可靠的多边形裁剪算法,可以有效地从复杂的多边形中提取出正确的多边形边界,为地理空间数据处理提供有效的技术支持。
中轴求凸多边形直径算法

t o lxt s n . i c mpe i i me y 0( )
Ke wor : c n e poy o d a tr mi d e xs; an xs y ds ovx lg n; i mee ; d l a i m i a i
摘 要: 在研 究中轴性质的基础上 , 出了一种全新的求解 凸多边形直径算法。 给 该算法首先求出凸多边形的中轴 , 再根据 中轴的两
VB B B 。 =B = 》 B
小凸多边形[ 2 1 。因此平面点集直径 问题也就转 化成凸多边形 直 径问题 。点集 凸壳问题 时间复杂度为 0 non 。 (lg ) 给定 凸多边形 P定 点序 列 P, …, 求 P的直径 , 。 , P, P 即求
1 引言
平面点集直径问题是计算机几何中的基本 问题 , 在计算机
利 用“ 草火 ” 来描述 : 设想一块与对象形状完全相 同的草地 , 在 边缘外 同时点火 , 势向内蔓延 , 火 向前推进 的火线相遇 的轨迹
就是 中轴 。C lb 在 16 aai 9 6年基于最大圆概念给 中轴下了更为
C m ue ni e n n p l aos o p trE gn r g adA pi t n 计算机工程与应用 ei ci
2 0 ,4 3 ) 0 84 (2
5 1
中轴求 凸多边形直径算法
董秀 山 1刘 润涛 ,
DONG Xi —s a L U Ru —to u hn .I n a
个端点确定直径。算法简单 , 并在无预处理 的情况 下达到 了 O n 。 ( )
关键 词 : 多边 形 ; 凸 直径 ; 中轴 ; 主轴
DO :03 7 /i n10 — 3 1 0 8 20 5 文章编号 :0 2 8 3 ( 0 8 3 — 0 1 0 文献标识码 : 中图分类号 :P 9 I 1.7 8 .s. 2 83 . 0 . .1 js 0 2 3 1 0— 3 1 20 )2 0 5 — 2 A T 31
求任意多边形直径算法设计
数字媒体综合设计结题报告求任意多边形直径算法的研究与实现学院:计算机学院班级:指导教师:学号:姓名:2017年9月1.选题的目的、意义关于本次数字媒体综合设计选择以求任意多边形直径算法的研究与实现为主题的目的和意义:a)目的:通过本次实验去初步研究计算几何算法,其中包括:—线段相交的判断、多边形面积的计算、内点外点的判断、凸包等等问题,并且能够根据实际情况改进算法,使其能更有效的解决实际问题。
b)意义:计算几何是在以计算机为载体的数字化环境下研究几何问题的几何学分支学科。
它是数学与计算机科学的一门交叉学科。
它不仅研究相关的几何不变量等基础理论,还研究几何图形的逼近、显示、传输以及重构等理论和方法。
计算几何不仅为其他几何分支学科提供了新的视角和出发点。
同时在数学理论、科学工程计算、计算机科学等方面有着重要的意义。
所以希望通过这次实验对计算几何有一个初步的认识,且掌握一些解决基本问题的解决思路与算法。
2.选题的基本内容a)选题背景平面点集直径问题是计算几何中的基本问题,在计算机图形学、模式识别、图像处理等众多领域上都有具体应用,下面就以机场跑道建设问题为例进行研究。
热带岛屿Piconesia希望开发旅游业,但是岛屿所处地理位置使得交通十分不方便,所以决定修建机场。
由于较长的着陆条可以容纳较大的飞机,为了满足各种飞机的需求,Piconesia希望在岛上修建竟可能长的跑道,为了解决这个问题,我们可以将岛屿边界建模为多边形,采用合适的算法,计算出跑道的长度。
b)测试数据图A.1:岛被建模为多边形。
最长的着陆带显示为粗线。
输入输入以包含指定顶点数的整数n(3≤n≤200)的行开始多边形。
之后是n行,每行包含两个整数x和y(| x |,| y |≤10 6),给出多边形顶点的坐标(x,y)按逆时针顺序排列。
多边形是简单的,即它的顶点是不同的,除了连续的边缘之外,多边形的两个边不相交或相交在它们的共同顶点。
另外,没有两个连续的边缘是共线的。
(完整版)Weiler-Atherton任意多边形裁剪算法
Weiler-Atherton任意多边形裁剪Sutherland-Hodgeman算法解决了裁剪窗口为凸多边形窗口的问题,但一些应用需要涉及任意多边形窗口(含凹多边形窗口)的裁剪。
Weiler-Atherton多边形裁剪算法正是满足这种要求的算法。
一、Weiler-Atherton任意多边形裁剪算法描述:在算法中,裁剪窗口、被裁剪多边形可以是任意多边形:凸的、凹的(内角大于180o)、甚至是带有内环的(子区),见下图。
裁剪窗口和被裁剪多边形处于完全对等的地位,这里我们称:1、被裁剪多边形为主多边形,记为A;2、裁剪窗口为裁剪多边形,记为B。
主多边形A和裁剪多边形B的边界将整个二维平面分成了四个区域:1、A∩B(交:属于A且属于B);2、A-B(差:属于A不属于B);3、B-A(差:属于B不属于A);4、A∪B(并:属于A或属于B,取反;即:不属于A且不属于B)。
内裁剪即通常意义上的裁剪,取图元位于窗口之内的部分,结果为A∩B。
外裁剪取图元位于窗口之外的部分,结果为A-B。
观察右图不难发现裁剪结果区域的边界由被裁剪多边形的部分边界和裁剪窗口的部分边界两部分构成,并且在交点处边界发生交替,即由被裁剪多边形的边界转至裁剪窗口的边界,或者反之。
由于多边形构成一个封闭的区域,所以,如果被裁剪多边形和裁剪窗口有交点,则交点成对出现。
这些交点分成两类:一类称“入”点,即被裁剪多边形由此点进入裁剪窗口,如图中a、c、e;一类称“出”点,即被裁剪多边形由此点离开裁剪窗口,如图中b、d、f。
二、Weiler-Atherton任意多边形裁剪算法思想:假设被裁剪多边形和裁剪窗口的顶点序列都按顺时针方向排列。
当两个多边形相交时,交点必然成对出现,其中一个是从被裁剪多边形进入裁剪窗口的交点,称为“入点”,另一个是从被裁剪多边形离开裁剪窗口的交点,称为“出点”。
算法从被裁剪多边形的一个入点开始,碰到入点,沿着被裁剪多边形按顺时针方向搜集顶点序列;而当遇到出点时,则沿着裁剪窗口按顺时针方向搜集顶点序列。
六边形直径计算公式文
六边形直径计算公式文六边形直径计算公式。
六边形是一种常见的几何图形,它具有六条边和六个角。
在实际生活中,我们经常需要计算六边形的直径,以便进行相关的计算和应用。
本文将介绍六边形直径的计算公式,并通过实例进行说明。
六边形直径的定义。
在几何学中,六边形是一个有六个边的多边形。
它具有六个顶点和六条边。
六边形的直径是指通过六边形中心的两个相对顶点之间的直线段。
直径是一个重要的几何概念,它可以帮助我们计算六边形的面积、周长等重要参数。
六边形直径的计算公式。
要计算六边形的直径,我们可以使用以下公式:直径 = 2 边长。
其中,直径表示六边形的直径,边长表示六边形的边长。
这个公式非常简单,只需要将六边形的边长乘以2即可得到直径的值。
实例演示。
为了更好地理解六边形直径的计算方法,我们可以通过一个实例进行演示。
假设有一个六边形,其边长为5厘米,我们需要计算这个六边形的直径。
根据上面的公式,我们可以进行如下计算:直径 = 2 5 = 10厘米。
因此,这个六边形的直径为10厘米。
六边形直径的应用。
六边形直径的计算不仅仅是一种几何学上的知识,它还具有广泛的应用。
在工程、建筑、地理等领域,我们经常需要计算六边形的直径,以便进行相关的设计和规划工作。
例如,在建筑设计中,我们需要计算房间的六边形地板的直径,以确定地板的尺寸和材料的使用量。
在地理测量中,我们也需要计算六边形地块的直径,以确定地块的面积和边界。
总结。
六边形直径的计算公式是直径 = 2 边长,通过这个简单的公式,我们可以轻松地计算六边形的直径。
六边形直径的计算不仅仅是一种几何学上的知识,它还具有广泛的应用。
希望本文能够帮助读者更好地理解六边形直径的计算方法,并在实际生活中应用这个知识。
学习简单的正多边形的计算
学习简单的正多边形的计算正多边形是指所有边相等、所有角也相等的多边形。
在几何学中,正多边形有着重要的地位,并且对于计算其各种属性的方法也有特定的公式和规律。
在本文中,我们将探讨如何计算正多边形的边长、周长、面积和内角。
一、计算正多边形的边长正多边形的边长可以通过以下公式计算:边长 = 周长 ÷边数其中,周长是正多边形所有边的长度之和,边数则代表正多边形的边的数量。
通过这个公式,我们可以轻松地求得正多边形的边长。
举个例子,假设一个正五边形的周长为15厘米,我们可以使用上述公式计算其边长:边长 = 15厘米 ÷ 5 = 3厘米所以,该正五边形的边长为3厘米。
二、计算正多边形的周长正多边形的周长是指所有边的长度之和。
对于一个正多边形来说,由于所有边的长度相等,所以周长可以通过以下公式计算:周长 = 边长 ×边数其中,边长代表正多边形的边长,边数则是正多边形的边的数量。
通过这个公式,我们可以轻松地求得正多边形的周长。
比如,一个正六边形的边长为4厘米,我们可以使用上述公式计算其周长:周长 = 4厘米 × 6 = 24厘米所以,该正六边形的周长为24厘米。
三、计算正多边形的面积正多边形的面积可以通过以下公式计算:面积 = 0.5 ×边长 ×边长 ×边数 × cot(180° ÷边数)其中,边长是正多边形的边长,边数是正多边形的边的数量,cot(180° ÷边数)表示正多边形内角的余切值。
让我们举个例子,假设一个正四边形的边长为6厘米。
现在,我们将使用上述公式计算其面积:面积 = 0.5 × 6厘米 × 6厘米 × 4 × cot(180° ÷ 4)我们需要先计算cot(180° ÷ 4)的值,cot(180° ÷ 4) ≈ 1,所以我们可以继续计算面积:面积 = 0.5 × 6厘米 × 6厘米 × 4 × 1 = 72厘米²所以,该正四边形的面积为72厘米²。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字媒体综合设计结题报告求任意多边形直径算法的研究与实现学院:计算机学院班级:指导教师:学号:姓名:2017年9月1.选题的目的、意义关于本次数字媒体综合设计选择以求任意多边形直径算法的研究与实现为主题的目的和意义:a)目的:通过本次实验去初步研究计算几何算法,其中包括:—线段相交的判断、多边形面积的计算、内点外点的判断、凸包等等问题,并且能够根据实际情况改进算法,使其能更有效的解决实际问题。
b)意义:计算几何是在以计算机为载体的数字化环境下研究几何问题的几何学分支学科。
它是数学与计算机科学的一门交叉学科。
它不仅研究相关的几何不变量等基础理论,还研究几何图形的逼近、显示、传输以及重构等理论和方法。
计算几何不仅为其他几何分支学科提供了新的视角和出发点。
同时在数学理论、科学工程计算、计算机科学等方面有着重要的意义。
所以希望通过这次实验对计算几何有一个初步的认识,且掌握一些解决基本问题的解决思路与算法。
2.选题的基本内容a)选题背景平面点集直径问题是计算几何中的基本问题,在计算机图形学、模式识别、图像处理等众多领域上都有具体应用,下面就以机场跑道建设问题为例进行研究。
热带岛屿Piconesia希望开发旅游业,但是岛屿所处地理位置使得交通十分不方便,所以决定修建机场。
由于较长的着陆条可以容纳较大的飞机,为了满足各种飞机的需求,Piconesia希望在岛上修建竟可能长的跑道,为了解决这个问题,我们可以将岛屿边界建模为多边形,采用合适的算法,计算出跑道的长度。
b)测试数据图A.1:岛被建模为多边形。
最长的着陆带显示为粗线。
输入输入以包含指定顶点数的整数n(3≤n≤200)的行开始多边形。
之后是n行,每行包含两个整数x和y(| x |,| y |≤10 6),给出多边形顶点的坐标(x,y)按逆时针顺序排列。
多边形是简单的,即它的顶点是不同的,除了连续的边缘之外,多边形的两个边不相交或相交在它们的共同顶点。
另外,没有两个连续的边缘是共线的。
测试数据1:70 2040 040 2070 5050 7030 500 50测试数据2:30 2017-2017 -20172017 0c)输出要求输出多边形的最大直线的长度,绝对相对的误差在10 -6以下3.预期达到的目标a)实现算法,并且满足以下输出测试数据1输出结果:76.157731059测试数据2输出结果:4510.149110617b)并通过可视化的方式展示c)通过这次实验总结出类似计算几何问题的固定解决思路4.关键技术研究4.1. 算法关键技术[1]最长线段计算公式:L1 L2 L3与p1p2的交点ip———pa(a)——————pb(b)———与p1p2的交点ipa)共线情况L2*L2 = dotP(a - b, pa- a) + dotP(b - a, pb - a)b)相交情况L1*L2 = dotP(a - b, ip - a)(L2+L3)*L2 = dotP(b - a, ip - a)c)通式[L1*L2 +L2*( L2 + L3)]/L2即```java(alen + blen) / minusPoint(b, a).len()```[2]用跨立实验判断两直线是共线还相交原理:向量的叉积性质,当其中一条线段的两个端点在另一条线段的同一侧时,不相交。
否则,相交。
```javaPublic Boolean isIntersect(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4) {double v1=(x2-x1)*(y4-y1) - (y2-y1)*(x4-x1);double v2=(x2-x1)*(y3-y1) - (y2-y1)*(x3-x1);if(v1*v2 >= 0) {return false;}double v3=(x4-x3)*(y2-y3) - (y4-y3)*(x2-x3);double v4=(x4-x3)*(y1-y3) - (y4-y3)*(x1-x3);if(v3*v4 >= 0) {return false;}return true;}```根据原理和结合题目,循环取出a、b点,再逆时针取四个辅助点p0、p1、p2、p3来确认ab连线和延长线与边界的关系。
p1p2作为比较目标,判断其与ab是共线还是相交关系。
p0,p3点用于确定经过分类选出的交点ip或者p1、p2是pa还是pb,根据情况使用公式。
a)共线情况根据公式L2*L2 = dotP(a - b, pa - a) + dotP(b - a, pb - a),确定出pm,pn点即可求出此类情况的结果。
由于逆时针选取四个点时会出现两种情况,p1对应a点,p2对应b点,或者是p2对应a点,p1对应b点。
根据不同的情况取出对应的pa,pb即可。
b)相交情况可分为两种情况讨论:1)与向量ab反向相交于边界p1p2当满足“crossP(b -a, p2 -a) > 0 && crossP(b -a, p1 -a) < 0(crossP 代表叉乘)”这个条件时代表直线ab与直线p1p2相交于ip。
根据交点坐标公式求出ip,在用公式(L2+L3)*L2 = dotP(b - a, ip - a)求出用于计算结果的中间量。
2)与向量ab同向相交于边界p1p2同理当满足“crossP(b - a, p2 - a) < 0 && crossP(b - a, p1 - a) > 0(crossP代表叉乘)”这个条件时代表直线ab与直线p1p2相交于ip。
根据交点坐标公式求出ip,在用公式“L1*L2 = dotP(a - b, ip - a)”求出用于计算结果的中间量。
[3]交点坐标公式用向量法求出两直线交点坐标公式v1 = crossP(b2 - b1, a1 - b1); (crossP代表叉乘)v2 = crossP(b2 - b1, a2 - b1);(a1*v2 - a2*v1) / (v2 - v1);4.2. 界面关键技术[1] 双缓冲刷新技术在Java编写具有连贯变化的窗口程序时,通常的办法是在子类中覆盖父类的paint(Graphics)方法,在方法中使用GUI函数实现窗口重绘的过程。
连贯变换的窗口会不断地调用update(Graphics)函数,该函数自动的调用paint(Graphics)函数。
这样就会出现闪烁的情况。
为了解决这一问题,可以应用双缓冲技术。
可以通过截取上述过程,覆盖update(Graphics)函数,在内存中创建一个与窗口大小相同的图形,并获得该图形的图形上下文(Graphics),再将图片的图形上下文作为参数调用paint(Graphics)函数(paint(Graphics)中的GUI函数会在图片上画图),再在update(Graphics)函数调用drawImage函数将创建的图形直接画在窗口上。
[2] MVC模式尝试使用mvc的结构去编写界面版的程序,视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码。
5.已经实现的目标及结果5.1. 纯算法版:输入数据后,能计算出正确结果1)输入:输出:2)输入:输出:5.2. 带操作界面的展示版本:6.完成任务收获与得失7.主要参考文献8.附录:算法主要代码import util.Point;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Scanner;import static ng.Math.max;import static ng.Math.min;import static util.Point.*;public class Arithmetic {private List<Point> points = new ArrayList<Point>();int N = 0;public Arithmetic(){input();N = points.size();calculateAll();}public void input(){int n;Scanner scanner = new Scanner(System.in);n = scanner.nextInt();for (int i = 0; i < n; i++) {int x = scanner.nextInt();int y = scanner.nextInt();Point p = new Point(x, y);points.add(p);}}public void makeCCLOrder() {//顺时针计算会出问题double ar = 0.0;for (int i = 0; i < points.size(); i++) {ar += crossP(points.get(i), points.get((i + 1) % points.size()));}if (ar < 0) {Collections.reverse(points);points.forEach(point -> {System.out.println("倒序x: " + point.getX() + " y: " + point.getY());});}}public void calculateAll() {makeCCLOrder();double ret = 0.0;for (int i = 0; i < N; i++) {for (int j = i + 1; j < N; j++) {Point a = points.get(i);Point b = points.get(j);if (crossP(minusPoint(b, a), minusPoint(points.get((i + N - 1) % N), a)) *crossP(minusPoint(b, a), minusPoint(points.get((i + 1) % N), a)) > 0 &&crossP(minusPoint(a, points.get((i + N - 1) % N)), minusPoint(points.get((i + 1) % N), a)) > 0) {continue;}double alen = 1e50, blen = 1e50;System.out.println("a: (" + a.getX() + "," + a.getY() + ") - b: (" + b.getX() + "," + b.getY() + ")");for (int k = 0; k < N; k++) {Point p0 = points.get((k + N - 1) % N);Point p1 = points.get(k);Point p2 = points.get((k + 1) % N);Point p3 = points.get((k + 2) % N);if (crossP(minusPoint(b, a), minusPoint(p1, a)) == 0 &&crossP(minusPoint(b, a), minusPoint(p2, a)) == 0) {//平行||共线System.out.println("平行||共线");double dp1 = dotP(minusPoint(b, a), minusPoint(p1, a));double dp2 = dotP(minusPoint(b, a), minusPoint(p2, a));if (dp2 <= 0 && dp2 <= dp1 && crossP(minusPoint(b, a), minusPoint(p3, a)) < 0) {System.out.println(" alen p2: " + p2.getX() + "," + p2.getY());alen = min(alen, dotP(minusPoint(a, b), minusPoint(p2, a)));}if (dp1 <= 0 && dp1 <= dp2 && crossP(minusPoint(b, a), minusPoint(p0, a)) > 0) {System.out.println(" alen p1: " + p1.getX() + "," + p1.getY());alen = min(alen, dotP(minusPoint(a, b), minusPoint(p1, a)));}if (dp2 >= 0 && dp2 >= dp1 && crossP(minusPoint(b, a), minusPoint(p3, a)) > 0) {System.out.println(" blen p2: " + p2.getX() + "," + p2.getY());blen = min(blen, dotP(minusPoint(b, a), minusPoint(p2, a)));}if (dp1 >= 0 && dp1 >= dp2 && crossP(minusPoint(b, a), minusPoint(p0, a)) < 0) {System.out.println(" blen p1: " + p1.getX() + "," + p1.getY());blen = min(blen, dotP(minusPoint(b, a), minusPoint(p1, a)));}} else if (crossP(minusPoint(p2, p1), minusPoint(a, p1)) >= 0 &&crossP(minusPoint(b, a), minusPoint(p2, a)) < 0 &&(crossP(minusPoint(b, a), minusPoint(p1, a)) > 0 ||crossP(minusPoint(b, a), minusPoint(p1, a)) == 0 &&crossP(minusPoint(b, a), minusPoint(p0, a)) > 0)) {System.out.println(">0");Point ip = Intersection(p1, p2, a, b);System.out.println(" Intersection alen ip: " + ip.getX() + "," + ip.getY());alen = min(alen, dotP(minusPoint(a, b), minusPoint(ip, a)));} else if (crossP(minusPoint(p2, p1), minusPoint(a, p1)) >= 0 &&crossP(minusPoint(b, a), minusPoint(p2, a)) > 0 &&(crossP(minusPoint(b, a), minusPoint(p1, a)) < 0 ||crossP(minusPoint(b, a), minusPoint(p1, a)) == 0 &&crossP(minusPoint(b, a), minusPoint(p0, a)) < 0)) {System.out.println("<0");Point ip = Intersection(p1, p2, a, b);System.out.println(" Intersection alen ip: " + ip.getX() + "," + ip.getY());blen = min(blen, dotP(minusPoint(b, a), minusPoint(ip, a)));}}System.out.println(" ret: " + (alen + blen) / minusPoint(b, a).len());ret = max(ret, (alen + blen) / minusPoint(b, a).len());System.out.println("");}System.out.println("---------------------------------------------------------");}System.out.println("" + ret);}public static void main(String[] args) {new Arithmetic();}}package util;import static ng.Math.hypot;public class Point {private double x;private double y;public Point(){}public Point(double x, double y) {this.x = x;this.y = y;}public void setX(double x) {this.x = x;}public void setY(double y) {this.y = y;}public double getX() {return x;}public double getY() {return y;}public double calculateDistance(Point p2) {double d;d = Math.sqrt(Math.abs((getX() - p2.getX())* (getX() - p2.getX())+(getY() - p2.getY())* (getY() - p2.getY())));return d;}public static Point additionPoint(Point a, Point b) {return new Point(a.getX() + b.getX(), a.getY() + b.getY());}public static Point minusPoint(Point a, Point b) {return new Point(a.getX() - b.getX(), a.getY() - b.getY());}public static Point multiplicationPoint(Point a, double c) {return new Point(a.getX() * c, a.getY() * c);}public static Point divisionOperationPoint(Point a, double c) {return new Point(a.getX() / c, a.getY() / c);}public static double crossP(Point a, Point b) {return a.getX() * b.getY() - a.getY() * b.getX();}public static double dotP(Point a, Point b) {return a.getX() * b.getX() + a.getY() * b.getY();}public static Point Intersection(Point a1, Point a2, Point b1, Point b2) {double v1 = crossP(minusPoint(b2, b1), minusPoint(a1, b1));double v2 = crossP(minusPoint(b2, b1), minusPoint(a2, b1));Point point = minusPoint(multiplicationPoint(a1, v2), multiplicationPoint(a2, v1));return divisionOperationPoint(point,(v2 - v1));//(a1*v2 - a2*v1) / (v2 - v1);}public double len(){return hypot(x,y);}}。