GIS算法的计算几何基础

合集下载

GIS算法基础 3

GIS算法基础 3
8
1.5 对称变换
a d 0
x * y * 1 x y 1 b e 0 ax by dx eyy 1
0 0 1
当b=d=0,a=-1,e=1时,有x*=-x,y*=y,产生与y轴对称的反 射图形,如图 (f)所示;
当b=d=0,a=1,e=-1时,有x*=x,y*=-y,产生与x轴对称的反 射图形,如图 (g)所示;
❖ 下面为求定过北京、巴黎两点的大圆 的天顶Q (Q1)坐标φ0与λ0的算例 (表 3.1)。
26
2.2.2.新极通过投影区域中部大圆的天顶
27
2.2.2.新极通过投影区域中部大圆的天顶
❖ 故Q点坐标φ0=-28°37′,λ0=53°44′ ❖ Q1点坐标φ0=28°37′,λ0=126°16′ ❖ 特例,当大圆与赤道垂直,大圆亦即经线圈,如其经度为λc,
❖ 这样,要用球面极坐标计算地图投影,仅需将GIS数据区域 内各经纬线交点的坐标φ、λ用式(3.1)换算成新坐标系中的极 坐标a、z,然后把a视为λ ,把90°-z视为φ应用现成的正轴 投影公式进行计算而无须另行推导横轴与斜轴的投影公式。
❖ 下面需要解决的是如何确定一个GIS数据区域中的新极Q以 及如何把GIS 数据区域内各点的φ、λ换算为a、z的问题。
0 1 x f y f 1
cos
sin
0
sin
cos
0
(1 cos )x f y f sin (1 cos )x f x f sin 1
15
1.10 几点说明
❖ 平移变换只改变图形的位置,不改变图形的大小和形状; ❖ 旋转变换仍保持图形各部分间的线性关系和角度关系,变
换后直线的长 度不变; ❖ 比例变换可改变图形的大小和形状; ❖ 错切变换引起图形角度关系的改变,甚至导致图形发生畸

GIS算法的计算几何基础

GIS算法的计算几何基础

GIS算法的计算几何基础矢量的概念:如果一条线段的端点是有次序之分的,我们把这种线段成为有向线段(directed segment)。

如果有向线段p1p2的起点p1在坐标原点,我们可以把它称为矢量(vector)p2。

矢量加减法:设二维矢量P = ( x1, y1 ),Q = ( x2 , y2 ),则矢量加法定义为: P + Q = ( x1 + x2 , y1 + y2 ),矢量减法定义为: P - Q = ( x1 - x2 , y1 - y2 )。

显然有性质 P + Q = Q + P,P - Q = - ( Q - P )。

矢量叉积:计算矢量叉积是与直线和线段相关算法的核心部分。

设矢量P = ( x1, y1 ),Q = ( x2, y2 ),则矢量叉积定义为由(0,0)、p1、p2和p1+p2所组成的平行四边形的带符号的面积,即:P × Q = x1*y2 - x2*y1,其结果是一个标量。

显然有性质P × Q = - ( Q × P ) 和P × ( - Q ) = - ( P × Q )。

两点的加减法就是矢量相加减,而点的乘法则看作矢量叉积。

叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:若P × Q > 0 , 则P在Q的顺时针方向。

若P × Q < 0 , 则P在Q的逆时针方向。

若P × Q = 0 , 则P与Q共线,但可能同向也可能反向。

折线段的拐向判断:折线段的拐向判断方法可以直接由矢量叉积的性质推出。

对于有公共端点的线段p0p1和p1p2,通过计算(p2 - p0) × (p1 - p0)的符号便可以确定折线段的拐向:若(p2 - p0) × (p1 - p0) > 0,则p0p1在p1点拐向右侧后得到p1p2。

若(p2 - p0) × (p1 - p0) < 0,则p0p1在p1点拐向左侧后得到p1p2。

GIS算法原理知识点总结

GIS算法原理知识点总结

GIS算法原理知识点总结GIS(地理信息系统)算法为处理地理信息数据提供了基础和方法。

它包括了各种空间数据处理、地理数据分析和地图制图的算法。

下面是GIS算法原理的一些常见知识点总结:1.空间数据结构:GIS算法的基础是对空间数据进行表示和存储。

常见的空间数据结构包括点、线、面和多面体等。

其中,最常用的数据结构是网格索引、四叉树和R树等。

2.空间查询:空间查询是GIS中常见的操作,包括点查询、范围查询、最近邻查询、交叉查询等。

常用的查询算法有线性扫描、空间分解和定向等。

3.空间关系和拓扑关系:空间关系用于描述不同空间对象之间的相互关系,包括相等、接触、包含、相交等。

拓扑关系用于表示空间对象之间的连接和依赖关系,包括相邻、相连、邻近等。

4.空间缓冲区分析:空间缓冲区分析用于生成空间对象的缓冲区,即在给定距离内生成一个区域。

常用的方法有固定距离缓冲区、变距离缓冲区和多边形缓冲区等。

5.空间插值:空间插值用于根据已知的数据点推断出未知点的值。

常用的插值方法有逆距离权重插值、克里金插值和三角网插值等。

6.空间分析:空间分析用于对空间数据进行统计和分析。

常见的空间分析包括空间聚类、空间相似性分析、空间揭示和空间推理等。

7. 空间路径分析:空间路径分析用于计算最佳路径,包括最短路径、最优路径和网络路径等。

常用的算法有Dijkstra算法、A*算法和Floyd-Warshall算法等。

8.空间建模和模拟:空间建模用于构建地理现象的模型,模拟用于模拟地理现象的发展和演变。

常见的方法有决策树、蒙特卡洛模拟和细胞自动机等。

9.地图制图:地图制图用于将地理信息数据可视化为地图。

常见的制图算法有点符号化、线符号化和面符号化等。

10. 空间统计:空间统计用于对空间数据进行统计分析,包括点模式分析、面模式分析和空间相关性分析等。

常见的方法有Moran's I指数、Geary's C指数和Getis-Ord Gi*指数等。

GIS算法的计算几何基础2

GIS算法的计算几何基础2

都要好写且不易出错。
24
弧长法

将坐标原点平移到被测点P,这个新坐标系将平面划分 为4个象限,对每个多边形顶点P ,只考虑其所在的象 限,然后按邻接顺序访问多边形的各个顶点P[i],分析 P[i]和P[i+1],有下列三种情况: (1)P[i+1]在P[i]的下一象限。此时弧长和加π/2; (2)P[i+1]在P[i]的上一象限。此时弧长和减π/2; (3)P[i+1]在P[i]的相对象限。 首先计算f=y[i+1]*x-x[i+1]*y(叉积), 若f=0,则点在多边形上; 若f<0,弧长和减π; 若f>0,弧长和加π。 最后对算出的代数和和上述的情况一样判断即可。


1 1 wn d 2 2
(u)du
0
16
1
5.2 转角法

若曲线C是由顶点V0,V1,…,Vn=V0构成的多边形,那么积分可 以简化为计算带符号的角度的总和。这些角PVi与PVi+1的夹 角。因此,如果i=angle(PVi,PVi+1),则
1 wn 2 1 i 2 i 0
《GIS算法基础》第二章
GIS算法的计算几何基础(2)
1

1 判断矩形是否包含点 2 判断线段、折线、多边形是否在矩形中
本 讲 内 容


3 判断矩形是否在矩形中
4 判断圆是否在矩形中
5 判断点是否在多边形内 6 判断线段是否在多边形内 7 判断折线是否在多边形内 8 判断多边形是否在多边形内 9 判断矩形是否在多边形内 10 判断圆是否在断点是否在多边形内

两种方法比较:

上图中,重叠区域的点被环绕两次,证明点在多边形内 部两次,但射线法测试的结果为点在多边形外。环绕法 的结果更加合理。

GIS常见的基本算法

GIS常见的基本算法

GIS常见的基本算法GIS(地理信息系统)领域中使用的基本算法非常多样化,可以分为数据处理算法、空间分析算法和地理可视化算法等方面。

以下是一些常见的基本算法:1.地图投影算法:地图投影是将地球表面上的经纬度坐标映射到平面坐标系上的过程。

常见的地图投影算法包括经纬度转换为平面坐标的算法,如墨卡托投影、等距圆柱投影、兰勃托投影等。

2.空间索引算法:空间索引算法是对空间数据进行高效存储和检索的关键。

常见的空间索引算法包括四叉树、R树、k-d树等。

这些算法能够将空间数据分割成多个子区域,并建立索引结构,以便在查询时快速定位目标数据。

3.空间插值算法:空间插值算法用于在已知或有限的观测点上估算未知点的值。

常见的空间插值算法包括反距离加权插值(IDW)、克里金插值和径向基函数插值等。

4.空间分析算法:空间分析算法用于研究地理现象之间的空间关系。

常见的空间分析算法包括缓冲区分析、空间叠置分析、网络分析、空间聚类分析等。

5.地图匹配算法:地图匹配是将实际观测点与地理信息数据库中的地理对象进行匹配的过程。

常见的地图匹配算法包括最短路径算法、马尔可夫链算法、HMM(隐马尔可夫模型)等。

6.空间平滑算法:空间平滑算法用于消除地理数据中的噪声和不规则性。

常见的空间平滑算法包括高斯滤波、均值滤波、中值滤波等。

7.空间插值算法:空间插值算法用于对连续型地理现象进行预测和估计。

常见的空间插值算法包括反距离加权插值(IDW)、克里金插值和径向基函数插值等。

8.地理网络算法:地理网络算法用于在地理网络上找到最短路径、最小生成树等。

常见的地理网络算法包括迪杰斯特拉算法、弗洛伊德算法等。

9.地理可视化算法:地理可视化算法用于将地理信息以可视化的形式展现出来。

常见的地理可视化算法包括等值线绘制算法、色彩映射算法、3D可视化算法等。

10.遥感图像分类算法:遥感图像分类是将遥感图像中的像素分配到不同的类别中的过程。

常见的遥感图像分类算法包括最大似然分类、支持向量机(SVM)分类、随机森林分类等。

GIS中的计算几何

GIS中的计算几何

GIS中的计算几何GIS是一个图形系统,必然会涉及到几何学上理论应用,比如,图形的可视化,空间拓扑分析,GIS图形编辑等都需要借助几何。

向量几何是用代数的方法来研究几何问题,首先,请大家翻一翻高等数学里有关向量的章节,熟悉一下几个重要的概念:向量、向量的模、向量的坐标表示、向量的加减运算、向量的点积、向量的叉积...下面我们将用这些基本概念来解答GIS中一些几何问题。

一,点和线的关系。

点是否在线段上,这样的判断在图形编辑,拓扑判断(比如,GPS跟踪判断是否跑在线上)需要用到这样的判断。

通常的想法是:先求线段的直线方程,再判断点是否符合这条直线方程,如果符合,还要判断点是否在线段所在的矩形区域(MBR)内,以排除延长线上的可能性,如果不符合,则点不在线段上。

这种思路是可行的,但效率不高,涉及到建立方程,解方程。

借助向量的叉积(也叫向量的向量积,结果还是向量,有方向的)可以很容易的判断。

设向量a=(Xa,Ya,Za) b=(Xb,Yb,Zb) 向量叉积a X b如下:二维向量叉积的模|a X b|=|a|*|b|*sinα=|Xa*Yb-Ya*Xb| (α是向量a,b之间的夹角),向量叉积模的几何意义是以向量a,b为邻边的平行四边形的面积。

可以推测:如果两向量共线,向量叉积模(所代表的平行四边形的面积为零) 则|a X b|=|a|*|b|*sinα=|Xa*Yb-Ya*Xb|=0,否则不共线,叉积的模为非零,根据这样条件可以很轻松的判断点和线的关系,避免了建立方程和解方程的麻烦。

向量叉积的模|AB X AC|=0即可判断C点在AB所确定的直线上,再结合C点是否在AB所在的MBR范围内,就可以最终确定C是否在AB线段上。

关于点和线段的其他关系,都可以通过叉积的求得,比如判断点在线的哪一侧,右手法则,可以通过 a X b=(Xa*Yb-Ya*Xb)*k中的(Xa*Yb-Ya*Xb)正负来判断。

留给大家思考,很简单的,呵呵…二,线和线的关系判断两条线段是否相交,在很多拓扑判断和图形编辑(比如,线的打断来构建拓扑,编辑线对象,叠置分析,面与面关系的判断等) 中都需要用到线线相交的判断,如果两条线段相交,一条线段的两端点必然位于另一条线段的两侧(不考虑退化情况,也就是一条线段的端点在另一条线段上,这个很容易判断)两向量的叉积a X b= (Xa*Yb-Ya*Xb)*k ,分别判断AB X AC的方向与AB X AD的方向是否异号,再判断CD X CA 的方向与CD X CB的方向是否异号即可判断两线段是否相交。

GIS算法基础——计算点到直线、射线、线段的距离

GIS算法基础——计算点到直线、射线、线段的距离

点到线距离的计算1、作业说明1.1 任务点到线距离的计算(包括直线、射线、线段)1.2 要求人机交互,鼠标屏幕取点进行计算,输出计算结果2、程序说明2.1 大体上分三步进行:2.1.1 首先进行画线操作:鼠标在屏幕上取两点(鼠标左键两点)1、画线段直接利用DrawLine函数,将在屏幕上获取的两点坐标传递给函数的参数即可。

2、画直线由于直线是无限的,所以此时要借助于屏幕上所取两点的直线方程,通过求出与所在容器边缘的交点,结合具体情况,将求出的交点的坐标传递给DrawLine函数的参数,即可画出当前范围内的直线形状。

3、画射线画射线与画直线的思路大致相同,不过需判断射线的方向,此处借助所取的第二个点和第一个点的位置关系判断方向,最后再将所取的第一个点和求得的射线方向与容器边缘的交点坐标传递给DrawLine函数的参数即可。

2.1.2 开始绘制第三个点(鼠标右键取该点)借助于DrawEllipse函数(详情参见代码部分)2.1.3 线和点绘制完成后,开始进行距离的计算1、点到直线的距离:可直接利用点到线之间的距离公式2、点到线段的距离:由于点在线段上的投影可能不在线段上,故还需要求出点到线段两端点坐标的距离,再将最小值作为结果输出3、点到射线的距离:同理,若点的投影不在射线上,则其最小距离为点到射线起始端点的距离2.2 窗体界面介绍首先是ComeBox,对其添加三项:计算点到线段的距离、计算点到直线的距离、计算点到射线的距离在PictureBox里进行点和线的绘制,在TextBox里显示点到线的距离值3、源代码using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace me{public partial class Form1 : Form{public Form1(){InitializeComponent();}//首先定义两个变量:屏幕上所取的两个点private Point m_ptStart; private Point m_ptEnd;//定义两个集合:myplist存放用于画线的两个点,pt存放第三个点List<Point> myplist = new List<Point>();List<Point> pt = new List<Point>();//result用来存放点到线的距离值double result;//自定义方法:两点之间的距离double ptdis(Point p0, Point p1){return System.Math.Sqrt((p1.X - p0.X) * (p1.X - p0.X) + (p1.Y - p0.Y) * (p1.Y - p0.Y));}//自定义最大最小值函数double max(double x, double y){return x > y ? x : y;}double min(double x, double y){return x > y ? y : x;}//自定义方法:点和线之间的距离double pldis(Point p0, Point p1, Point p2){double result;double A = p2.Y - p1.Y;double B = p1.X - p2.X;double C = p2.X * p1.Y - p1.X * p2.Y;result = System.Math.Abs(A * p0.X + B * p0.Y + C) /System.Math.Sqrt(A * A + B * B);return result;}//自定义方法:获取点在线上的投影Point GetProjectPt(Point p0, Point p1, Point p2){Point ProjectPt=new Point();if (p2.X == p1.X){ProjectPt.X = p1.X;ProjectPt.Y = p0.Y;}else{double k = (p2.Y - p1.Y) / (p2.X - p1.X);ProjectPt.X = (int)((k * p1.X + p0.X / k + p0.Y - p1.Y)/(k+1/k));ProjectPt.Y = (int)(-1 / k * (ProjectPt.X - p0.X) + p0.Y);}return ProjectPt;}/*当comboBox1里面的项改变时,清除之前的所有数据比如计算点到直线的距离时,清除点到线段的距离*/private void comboBox1_SelectedIndexChanged(object sender, EventArgs e){myplist.Clear();textBox1.Text = "";Graphics g = pictureBox1.CreateGraphics();g.Clear(Color.White);}// 对pictureBox1的MouseDown事件进行编辑,当鼠标按下时,会产生哪些操作private void pictureBox1_MouseDown(object sender, MouseEventArgs e){Pen blue = new Pen(Color.Blue, 3);Graphics g = pictureBox1.CreateGraphics();//当按下鼠标左键时,在屏幕上取两点画线if (e.Button == MouseButtons.Left){Point p = new Point(e.X, e.Y);myplist.Add(p);}//当按下鼠标右键时,在屏幕上取第三个点if (e.Button == MouseButtons.Right){Point p = new Point(e.X, e.Y);pt.Clear();//改变所取的第三个点时,清除上一次的数据(距离)和图形(点)g.Clear(Color.White);pt.Add(p);//此处将第三个点画成椭圆形式g.DrawEllipse(blue, pt[0].X, pt[0].Y, 1, 1);//在取点的同时,进行点到线距离的计算,并将结果值显示在textBox1上Point p3 = new Point();p3 = GetProjectPt(pt[0], m_ptStart,m_ptEnd);//获取点在线上的投影点//分情况讨论if(comboBox1.Text=="计算点到线段的距离"){if (p3.X >max(m_ptStart.X,m_ptEnd.X ) || p3.X < min( m_ptStart.Y,m_ptEnd.Y)){//点在线段上的投影不在线段上double dis1 = ptdis(pt[0], m_ptStart);double dis2 =ptdis(pt[0], m_ptEnd);result = min(dis1, dis2);}elseresult = pldis(pt[0], m_ptStart, m_ptEnd);}if(comboBox1.Text=="计算点到射线的距离"){if (p3.X < myplist[0].X) //点在射线上的投影不在射线上result = ptdis(pt[0], m_ptStart);elseresult = pldis(pt[0], m_ptStart, m_ptEnd);}if (comboBox1.Text == "计算点到直线的距离")result = pldis(pt[0], m_ptStart, m_ptEnd);textBox1.Text = result.ToString(); //将结果显示在textBox1上}//开始画线if (myplist.Count > 1){//A、B、C分别是直线一般方程中的三和参数,即A*x+B*y+C=0double A = myplist[1].Y - myplist[0].Y;double B = myplist[0].X - myplist[1].X;double C = myplist[1].X * myplist[0].Y - myplist[0].X * myplist[1].Y; //通过switch语句,输入comboBox1的文本内容,判断将要进行哪一种操作switch (comboBox1.Text){case"计算点到线段的距离":{ //起点和终点即为屏幕上所取的两个点m_ptStart = myplist[0];m_ptEnd = myplist[1];break;}case"计算点到直线的距离"://画直线时,需要将起始点和pictureBox1容器边缘交点联系起来{ //起点坐标m_ptStart.Y = 0;m_ptStart.X = (int)(-C / A);//终点坐标m_ptEnd.Y = pictureBox1.Height;m_ptEnd.X = (int)(-(C + B * m_ptEnd.Y) / A);break;}case"计算点到射线的距离"://画射线时同样要考虑到线与pictureBox容器边缘的交点,比较困难的是判断射线方向(借助于所取两点的位置关系){Point p0 = new Point();Point p1 = new Point();//起点坐标if (myplist[1].Y == myplist[0].Y){p0.Y = myplist[0].Y; p0.X = 0;p1.Y = myplist[0].Y; p1.X = pictureBox1.Width;}else{p0.Y = 0;p0.X = (int)(-C / A);//终点坐标p1.Y = pictureBox1.Height;p1.X = (int)(-(C + B * p1.Y) / A);}//结合所取两点的位置关系确定最终传递给DrawLine的是哪两点if (myplist[1].Y >= myplist[0].Y){m_ptEnd.X = p1.X;m_ptEnd.Y = p1.Y;}else{m_ptEnd.X = p0.X;m_ptEnd.Y = p0.Y;}m_ptStart = myplist[0];break;}}g.DrawLine(blue, m_ptStart, m_ptEnd);//画线}}}}4、结果展示实现功能:首先在下拉列表中选择将要计算点到哪种线的距离,选择好后,鼠标左键取两点自动画线,之后鼠标右键取点,在取点的同时,会自动显示距离值,并且在选取下一个点时,上一组的数据自动清除4.1 计算点到线段的距离4.2 计算点到直线的距离:4.3 计算点到射线的距离。

GIS算法的计算几何基础

GIS算法的计算几何基础

GIS算法的计算几何基础GIS(地理信息系统)中的算法主要应用于计算几何基础。

计算几何是数学的分支,研究由数学对象(如点、线、多边形等)组成的空间结构和它们之间的相互关系。

在GIS中,计算几何的目标是研究和解决地理空间数据的几何问题,例如地图投影、数据集成、空间分析等。

1.点线面的表示与计算在GIS中,地理实体通常用点、线、面的集合表示。

计算几何算法中,点线面的表示与计算是基础操作。

点的坐标通常用笛卡尔坐标系表示,计算中常涉及到点之间的距离、方位角等。

线段可以用两个端点表示,计算中常涉及到线段之间的相交、距离等。

面由闭合的多边形表示,计算中常涉及到面之间的包含关系、交集等。

2.地图投影地图投影是将地球表面上的经纬度坐标(球面坐标)映射到平面坐标系统上的过程。

在GIS中,地图投影的目标是保持地理对象的相对形状、方位和距离关系。

常见的地图投影算法包括:等角圆柱投影、等距圆锥投影、墨卡托投影等。

这些算法涉及到大量的地球几何学和空间计算,以及数学中的变换和变形理论。

3.空间索引空间索引是用于加速地理空间数据查询的技术。

在GIS中,空间索引的目标是通过将地理空间数据分组和排序,推断地理特征对象之间的关系。

常见的空间索引算法包括:R树、四叉树、格网索引等。

这些算法利用空间分区和思维策略,在空间数据集查询中实现高效的和过滤。

4.空间缓冲区空间缓冲区是定义在地理空间对象周围的区域。

在GIS中,空间缓冲区的目标是通过定义对象的半径或厚度,生成包围对象的区域。

常见的空间缓冲区算法包括:欧几里得缓冲区、高级缓冲区等。

这些算法通常利用计算几何学中的距离计算、区域计算和曲线生成等技术。

5.空间分析空间分析是对地理空间数据进行操作和运算的过程。

在GIS中,空间分析的目标是通过计算和模拟地理特征对象之间的空间关系,揭示地理现象的模式和规律。

常见的空间分析算法包括:最近邻查询、空间插值、地图代数等。

这些算法涉及到距离计算、交叉分析、拓扑关系等计算几何基础。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

GIS算法的计算几何基础矢量的概念:如果一条线段的端点是有次序之分的,我们把这种线段成为有向线段(directed segment)。

如果有向线段p1p2的起点p1在坐标原点,我们可以把它称为矢量(vector)p2。

矢量加减法:设二维矢量P = ( x1, y1 ),Q = ( x2 , y2 ),则矢量加法定义为: P + Q = ( x1 + x2 , y1 + y2 ),矢量减法定义为: P - Q = ( x1 - x2 , y1 - y2 )。

显然有性质 P + Q = Q + P,P - Q = - ( Q - P )。

矢量叉积:计算矢量叉积是与直线和线段相关算法的核心部分。

设矢量P = ( x1, y1 ),Q = ( x2, y2 ),则矢量叉积定义为由(0,0)、p1、p2和p1+p2所组成的平行四边形的带符号的面积,即:P × Q = x1*y2 - x2*y1,其结果是一个标量。

显然有性质P × Q = - ( Q × P ) 和P × ( - Q ) = - ( P × Q )。

两点的加减法就是矢量相加减,而点的乘法则看作矢量叉积。

叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:若P × Q > 0 , 则P在Q的顺时针方向。

若P × Q < 0 , 则P在Q的逆时针方向。

若P × Q = 0 , 则P与Q共线,但可能同向也可能反向。

折线段的拐向判断:折线段的拐向判断方法可以直接由矢量叉积的性质推出。

对于有公共端点的线段p0p1和p1p2,通过计算(p2 - p0) × (p1 - p0)的符号便可以确定折线段的拐向:若(p2 - p0) × (p1 - p0) > 0,则p0p1在p1点拐向右侧后得到p1p2。

若(p2 - p0) × (p1 - p0) < 0,则p0p1在p1点拐向左侧后得到p1p2。

若(p2 - p0) × (p1 - p0) = 0,则p0、p1、p2三点共线。

具体情况可参照下图:判断点是否在线段上:设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 且 Q 在以 P1,P2为对角顶点的矩形内。

前者保证Q点在直线P1P2上,后者是保证Q点不在线段P1P2的延长线或反向延长线上,对于这一步骤的判断可以用以下过程实现:if min(Xp1,Xp2) <= Xq <= max(Xp1,Xp2) and min(Yp1,Yp2) <= Yq <=max(Yp1,Yp2){ return true};else{return false;}特别要注意的是,由于需要考虑水平线段和垂直线段两种特殊情况,min(xi,xj)<=xk<=max(xi,xj)和min(yi,yj)<=yk<=max(yi,yj)两个条件必须同时满足才能返回真值。

判断两线段是否相交:我们分两步确定两条线段是否相交:(1)快速排斥试验设以线段 P1P2 为对角线的矩形为R,设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。

(2)跨立试验如果两线段相交,则两线段必然相互跨立对方。

若P1P2跨立Q1Q2 ,则矢量 ( P1 - Q1 ) 和( P2 - Q1 )位于矢量( Q2 - Q1 ) 的两侧,即( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) < 0。

上式可改写成( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) > 0。

当 ( P1 - Q1 ) × ( Q2 - Q1 ) = 0 时,说明 ( P1 - Q1 ) 和 ( Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,( Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。

所以判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。

同理判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0。

判断线段和直线是否相交:如果线段P1P2和直线Q1Q2相交,则P1P2跨立Q1Q2,即:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。

判断矩形是否包含点:只要判断该点的横坐标和纵坐标是否夹在矩形的左右边和上下边之间。

判断线段、折线、多边形是否在矩形中:因为矩形是个凸集,所以只要判断所有端点是否都在矩形中就可以了。

判断矩形是否在矩形中:只要比较左右边界和上下边界就可以了。

判断圆是否在矩形中:很容易证明,圆在矩形中的充要条件是:圆心在矩形中且圆的半径小于等于圆心到矩形四边的距离的最小值。

判断点是否在多边形中:判断点P是否在多边形中是计算几何中一个非常基本但是十分重要的算法。

以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外,考虑沿着L从无穷远处开始自左向右移动,遇到和多边形的第一个交点的时候,进入到了多边形的内部,遇到第二个交点的时候,离开了多边形,……所以很容易看出当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。

但是有些特殊情况要加以考虑。

如图下图(a)(b)(c)(d)所示。

在图(a)中,L和多边形的顶点相交,这时候交点只能计算一个;在图(b)中,L和多边形顶点的交点不应被计算;在图(c)和(d) 中,L和多边形的一条边重合,这条边应该被忽略不计。

如果L和多边形的一条边重合,这条边应该被忽略不计。

为了统一起见,我们在计算射线L和多边形的交点的时候,1。

对于多边形的水平边不作考虑;2。

对于多边形的顶点和L相交的情况,如果该顶点是其所属的边上纵坐标较大的顶点,则计数,否则忽略;3。

对于P在多边形边上的情形,直接可判断P属于多边行。

由此得出算法的伪代码如下:count ← 0;以P为端点,作从右向左的射线L;for 多边形的每条边sdo if P在边s上then return true;if s不是水平的then if s的一个端点在L上if 该端点是s两端点中纵坐标较大的端点then count ← count+1else if s和L相交then count ← count+1;if count mod 2 = 1then return true;else return false;其中做射线L的方法是:设P'的纵坐标和P相同,横坐标为正无穷大(很大的一个正数),则P和P'就确定了射线L。

判断点是否在多边形中的这个算法的时间复杂度为O(n)。

另外还有一种算法是用带符号的三角形面积之和与多边形面积进行比较,这种算法由于使用浮点数运算所以会带来一定误差,不推荐大家使用。

判断线段是否在多边形内:线段在多边形内的一个必要条件是线段的两个端点都在多边形内,但由于多边形可能为凹,所以这不能成为判断的充分条件。

如果线段和多边形的某条边内交(两线段内交是指两线段相交且交点不在两线段的端点),因为多边形的边的左右两侧分属多边形内外不同部分,所以线段一定会有一部分在多边形外(见图a)。

于是我们得到线段在多边形内的第二个必要条件:线段和多边形的所有边都不内交。

线段和多边形交于线段的两端点并不会影响线段是否在多边形内;但是如果多边形的某个顶点和线段相交,还必须判断两相邻交点之间的线段是否包含于多边形内部(反例见图b)。

因此我们可以先求出所有和线段相交的多边形的顶点,然后按照X-Y坐标排序(X坐标小的排在前面,对于X坐标相同的点,Y坐标小的排在前面,这种排序准则也是为了保证水平和垂直情况的判断正确),这样相邻的两个点就是在线段上相邻的两交点,如果任意相邻两点的中点也在多边形内,则该线段一定在多边形内。

证明如下:命题1:如果线段和多边形的两相邻交点P1 ,P2的中点P' 也在多边形内,则P1, P2之间的所有点都在多边形内。

证明:假设P1,P2之间含有不在多边形内的点,不妨设该点为Q,在P1, P'之间,因为多边形是闭合曲线,所以其内外部之间有界,而P1属于多边行内部,Q属于多边性外部,P'属于多边性内部,P1-Q-P'完全连续,所以P1Q和QP'一定跨越多边形的边界,因此在P1,P'之间至少还有两个该线段和多边形的交点,这和P1P2是相邻两交点矛盾,故命题成立。

证毕。

由命题1直接可得出推论:推论2:设多边形和线段PQ的交点依次为P1,P2,……Pn,其中Pi和Pi+1是相邻两交点,线段PQ在多边形内的充要条件是:P,Q在多边形内且对于i =1, 2,……, n-1,Pi ,Pi+1的中点也在多边形内。

在实际编程中,没有必要计算所有的交点,首先应判断线段和多边形的边是否内交,倘若线段和多边形的某条边内交则线段一定在多边形外;如果线段和多边形的每一条边都不内交,则线段和多边形的交点一定是线段的端点或者多边形的顶点,只要判断点是否在线段上就可以了。

至此我们得出算法如下:if 线端PQ的端点不都在多边形内then return false;点集pointSet初始化为空;for 多边形的每条边sdo if 线段的某个端点在s上then 将该端点加入pointSet;else if s的某个端点在线段PQ上then 将该端点加入pointSet;else if s和线段PQ相交 // 这时候已经可以肯定是内交了then return false;将pointSet中的点按照X-Y坐标排序;for pointSet中每两个相邻点 pointSet[i] , pointSet[ i+1]do if pointSet[i] , pointSet[ i+1] 的中点不在多边形中then return false;return true;这个过程中的排序因为交点数目肯定远小于多边形的顶点数目n,所以最多是常数级的复杂度,几乎可以忽略不计。

相关文档
最新文档