导航:首页 > 源码编译 > convexhull算法

convexhull算法

发布时间:2022-06-19 12:58:02

① 求教convex hull 算法

网络浙大ACM模板,或者吉林大学ACM模板,里面应该有求凸包的算法代码。复杂度有nlogn的和n^2的。 或者直接网络凸包算法

② 算法里面凸包是什么东西

⒈对于一个集合D,D中任意有限个点的线性组合的全体称为D的凸包。
⒉对于一个集合D,所有包含D的凸集之交称为D的凸包。
可以证明,上述两种定义是等价的概念

1 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。右图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包。
2 一组平面上的点,求一个包含所有点的最小的凸多边形,这就是凸包问题了。这可以形象地想成这样:在地上放置一些不可移动的木桩,用一根绳子把他们尽量紧地圈起来,并且为凸边形,这就是凸包了。

③ 凸包的发展历史,急需,越详细越好,谢谢!!!!

⒈对于一个集合D,D中任意有限个点的线性组合的全体称为D的凸包。 ⒉对于一个集合D,所有包含D的凸集之交称为D的凸包。 可以证明,上述两种定义是等价的 概念
1 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。右图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包。 2 一组平面上的点,求一个包含所有点的最小的凸多边形,这就是凸包问题了。这可以形象地想成这样:在地上放置一些不可移动的木桩,用一根绳子把他们尽量紧地圈起来,并且为凸边形,这就是凸包了。编辑本段平面凸包求法常见求法
2.0 Graham's Scan法求解凸包问题
概念 凸包(Convex Hull)是一个计算几何(图形学)中的概念。用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有点的。严谨的定义和相关概念参见维基网络:凸包。 这个算法是由数学大师葛立恒(Graham)发明的,他曾经是美国数学学会(AMS)主席、AT&T首席科学家以及国际杂技师协会(IJA)主席。(太汗了,这位大牛还会玩杂技~) 问题 给定平面上的二维点集,求解其凸包。 过程 ⒈ 在所有点中选取y坐标最小的一点H,当作基点。如果存在多个点的y坐标都为最小值,则选取x坐标最小的一点。坐标相同的点应排除。然后按照其它各点p和基点构成的向量<H,p>;与x轴的夹角进行排序,夹角由大至小进行顺时针扫描,反之则进行逆时针扫描。实现中无需求得夹角,只需根据向量的内积公式求出向量的模即可。以下图为例,基点为H,根据夹角由小至大排序后依次为H,K,C,D,L,F,G,E,I,B,A,J。下面进行逆时针扫描。 ⒉ 线段<H,K>;一定在凸包上,接着加入C。假设线段<K,C>;也在凸包上,因为就H,K,C三点而言,它们的凸包就是由此三点所组成。但是接下来加入D时会发现,线段<K,D>;才会在凸包上,所以将线段<K,C>;排除,C点不可能是凸包。 ⒊ 即当加入一点时,必须考虑到前面的线段是否会出现在凸包上。从基点开始,凸包上每条相临的线段的旋转方向应该一致,并与扫描的方向相反。如果发现新加的点使得新线段与上线段的旋转方向发生变化,则可判定上一点必然不在凸包上。实现时可用向量叉积进行判断,设新加入的点为pn + 1,上一点为pn,再上一点为pn - 1。顺时针扫描时,如果向量<pn - 1,pn>;与<pn,pn + 1>;的叉积为正(逆时针扫描判断是否为负),则将上一点删除。删除过程需要回溯,将之前所有叉积符号相反的点都删除,然后将新点加入凸包。 在上图中,加入K点时,由于线段<H,K>;相对于<H,C>;为顺时针旋转,所以C点不在凸包上,应该删除,保留K点。接着加入D点,由于线段<K,D>;相对<H,K>;为逆时针旋转,故D点保留。按照上述步骤进行扫描,直到点集中所有的点都遍例完成,即得到凸包。 复杂度 这个算法可以直接在原数据上进行运算,因此空间复杂度为O⑴。但如果将凸包的结果存储到另一数组中,则可能在代码级别进行优化。由于在扫描凸包前要进行排序,因此时间复杂度至少为快速排序的O(nlgn)。后面的扫描过程复杂度为O(n),因此整个算法的复杂度为O(nlgn)。 ⒉1凸包最常用的凸包算法是Graham扫描法和Jarvis步进法。 对于一个有三个或以上点的点集Q,过程如下: 计算点集最右边的点为凸包的顶点的起点,如上图的P3点。 Do For i = 0 To 总顶点数 计算有向向量P3->Pi If 其余顶点全部在有向向量P3->Pi的左侧或右侧,则Pi点为凸包的下一顶点 Pi点加入凸包列表 GoTo 1 End If Next Exit Do 1: Loop 此过程执行后,点按极角自动顺时针或逆时针排序,只需要按任意两点的次序就可以了。而左侧或右侧的判断可以用前述的矢量点积性质实现。
特殊算法
⒉2求凸包有很多方法,不过最适合OIer和ACMer的估计还是Graham's Scan这个方法了。它的大致方法是这样的:首先,找到所有点中最左边的(y坐标最小的),如果y坐标相同,找x坐标最小的;以这个点为基准求所有点的极角(atan2(y-y0,x-x0)),并按照极角对这些点排序,前述基准点在最前面,设这些点为P[0]..P[n-1];建立一个栈,初始时P[0]、P[1]、P[2]进栈,对于P[3..n-1]的每个点,若栈顶的两个点与它不构成“向左转”的关系,则将栈顶的点出栈,直至没有点需要出栈以后将当前点进栈;所有点处理完之后栈中保存的点就是凸包了。 如何判断A、B、C构成的关系不是向左转呢?如果b-a与c-a的叉乘小于0就不是。a与b的叉乘就是a.x*b.y-a.y*b.x。 上面的这个Graham的实现比我原来按照USACO里的课文写得简单多了,主要是它通过简单的预处理保证了P[0]、P[1]以及P[n-1]肯定是凸包里的点,这样就可以避免在凸包“绕回来”的时候繁杂的处理。
中心法
先构造一个中心点,然后将它与各点连接起来,按斜率递增的方法,求出凸包上部;再按斜率递减的方法,求出凸包下部。
水平法
从最左边的点开始,按斜率递增的方法,求出凸包上部;再按斜率递减的方法,求出凸包下部。水平法较中心法减少了斜率无限大的可能,减少了代码的复杂度。编辑本段代码例代码一
(在编辑器中将"_ "(下划线+空格)替换成两个空格即可编译; 注意要去掉开通的双字节中文空格,蛋疼的网络。)

④ 能不能解释一下包围盒技术的概念和用法

包围盒层次的基本思想是通过建立对象的包围盒层次来逐渐逼近对象的几何模型,从而用体积略大而形状简单的包围盒代替复杂的几何对象参加碰撞检测,通过包围盒间的相交测试快速地排除不相交的基本几何元素对,以减少相交测试的次数.对用于碰撞检测的包围盒有以下两方面的约束:(1)简单性:包围盒应该是简单的几何体,至少应该比被包围的几何对象简单.简单性不仅表现为几何形状简单、易于计算,而且包括相交测试算法的快速简单.(2)紧密性:包围盒应该尽可能地贴近被包围的几何对象.紧密性可以用包围盒B与被包围对象G间的Hausdorff距离τ来衡(τ=maxb∈Bming∈Gdist(b,g)).τ越小,紧密性越好.紧密性直接关系到需要进行相交测试的包围盒的数目.传统的包围盒类型有沿坐标轴的包围盒AABB(axis-aligned bounding boxes)[1,2]和球形包围盒(spheres).一个给定对象的AABB被定义为包含该对象且边平行于坐标轴的最小的正六面体,球形包围盒被定义为包含该对象的最小的球体.这两类包围盒的相交测试都是十分简单的,但它们的紧密性相对较差.近年来,
比较着名的包围盒是带方向的包围盒OBB(oriented bounding box)[4].一个给定对象的OBB被定
义为包含该对象且相对于坐标轴方向任意的最小的正六面体.OBB最大的特点是其方向的任意
性,这使得它可以根据被包围对象的形状特点尽可能紧密地包围对象,但同时也使得它的相交测试
变得复杂.紧密性最好的包围盒应该是对象的凸包(convex hull).凸包的定义保证它是包围对象的
最小的凸多面体,但凸包自身的计算复杂性及其相交测试的困难使其难以用于碰撞检测.

⑤ 凸包 支撑线

点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。下图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包。
为了解决分治算法、插入算法和生长算法都要求在构网之前给出所有点数据这个问题,实时三角网剖分算法先利用部分离散点生成一个外轮廓为凸包的初始三角网.然后将点加入到既有三角网中,如点落在既有三角网的某一三角形中,将该点与三角形的顶点相连构建新的三角网;如点落在既有三角网外,找出该点向既有三角网外轮廓围成的凸包发出的两条支撑线,这两条支撑线与既有凸包围成了一个多边形,再将这个多边形剖分成三角网即可.最后利用局部优化算法对所生成的三角网进行优化,使之成为Delaunay三角网.该算法构网时无需预先给定所有数据点,可用于实时生成三角网;此外,通过对凸包进行分区管理,在搜寻凸包支撑线时,能预先确定出支撑点的范围,减少了搜索工作量,提高了三角网的生成速度.

⑥ 怎样用动态规划算法解决24点问题,稍详细些,谢谢


枚举法: Enumeration

排序:Sort

贪心法:Greedy algorithm

递归:Recursion

分治:Divide and Rule

深度优先搜索:Depth First Search(DFS)

宽(广)度优先搜索:Breadth First Search(BFS)

动态规划:Dynamic Programming(DP) 也有人叫它 Dynamic Process

离散化:Discretization

栈:Stack Last in First out (LIFO)

队列:Queue First in First out(FIFO)

顺序表:Array Array-Based List

链表:Chain Linked List

广义表:Lists

串:String

集合:Set

树:Tree

二叉树:Binary Tree

完全二叉树:Complete Binary Tree

二叉搜索树:Binary Search Tree(BST)

堆:Heap

图:Graph

哈希表:Hash Table

并查集:Union-Find Sets 或 Disjoint Sets

最大匹配:maximal matching

线段树:Segment Tree

树状数组:Binary Indexed Tree

伸展树:Splay Tree

左偏树:Leftist Tree 或 Leftist Heap

斐波那契堆:Fibonacci Heap

后缀树:Suffix Tree

网络流:Network Flows

凸包:Convex Hull

叉积:Cross Function

高斯消元:Gaussian Elimination

匹配:Matching

矩阵:Matrix

⑦ 离散点外包凸多边形生成算法(C#或者C++),要有详细代码和说明,最好有可运行的样例程序好的另外加分,急

find&&find_if
临时对象——构造函数的调用.根据若干个离散点创建最大外包凸多边形图形算法
//卷包裹法---创建最大外包凸多边形

//stdafx.h

#define PI 3.1415926
#define NULL 0
#define LEN sizeof(struct XYpoint)

long pointSum;

struct XYpoint
{
double x;
double y;
struct XYpoint *next;
};

XYpoint *creat(void);

struct XYpoint *insert(struct XYpoint *head2,struct XYpoint *p);

struct XYpoint *del(struct XYpoint *head,struct XYpoint *p);

struct XYpoint *miny(struct XYpoint *head);

double angle(struct XYpoint *a,struct XYpoint *b,struct XYpoint *c);

double dis(struct XYpoint *a,struct XYpoint *b);

struct XYpoint *tank( struct XYpoint *head ,struct XYpoint *head2);

struct XYpoint *convexHull( struct XYpoint *head ,struct XYpoint *head2);

void print(struct XYpoint *head2);

//stdafx.cpp
#include "stdafx.h"
#include <math.h>
#include <vector>

//using namespace std;

struct XYpoint *creat(void)
{
struct XYpoint *head;
struct XYpoint *p1,*p2;
FILE *fp;
if((fp=fopen("in_put.txt","r"))==NULL)
{
printf("can not open the file\n");
exit(0);
}
pointSum=0;
p1=p2=(struct XYpoint *)malloc(LEN);
fscanf(fp,"%lf,%lf",&p1->x,&p1->y);
head=NULL;
while(!feof(fp))
{
pointSum=pointSum+1;
if(pointSum==1)
head=p1;
else
p2->next=p1;
p2=p1;
p1=(struct XYpoint *)malloc(LEN);
fscanf(fp,"%lf,%lf",&p1->x,&p1->y);
}
p2->next=NULL;
fclose(fp);
return(head);
}

struct XYpoint *insert(struct XYpoint *head2,struct XYpoint *p)
{
struct XYpoint *p1,*p0;
p0=p;
p1=head2;
while(p1->next!=NULL)
{
p1=p1->next;
}
p1->next=p0;
p0->next=NULL;
if (head2->next==NULL)
printf("not been insert!\n");
return (head2);
}

struct XYpoint *del(struct XYpoint *head,struct XYpoint *p)
{
struct XYpoint *p0,*p1;
if(head==NULL)
{
printf("\nlist null\n");
goto end;
}
p0=head;
while((p->x!=p0->x||p->y!=p0->y)&&p0->next!=NULL)
{
p1=p0;
p0=p0->next;
}
if(p->x==p0->x&&p->y==p0->y)
{
if(p0==head)
head=p0->next;
else
p1->next=p0->next;
}
else
printf("not been found!\n");

end:
return (head);
}

struct XYpoint *miny(struct XYpoint *head)
{
double min;
struct XYpoint *p,*p1;
p=head;
min=p->y;
p1=p;
p=p->next;
while (p!=NULL)
{
if (min>p->y)
{min=p->y,p1=p;}
else if(min==p->y&&p1->x>p->x)
{min=p->y,p1=p;}
else p=p->next;
}
return(p1);

}

double angle(struct XYpoint *a,struct XYpoint *b,struct XYpoint *c)
{
struct XYpoint *p0,*p1,*p2;
double dsx,dsy,dex,dey,cosfi,norm,fi;
p0=a;
p1=b;
p2=c;
dsx=p1->x-p0->x;
dsy=p1->y-p0->y;
dex=p2->x-p1->x;
dey=p2->y-p1->y;

cosfi=dsx*dex+dsy*dey;
norm=(dsx*dsx+dsy*dsy)*(dex*dex+dey*dey);
cosfi/=sqrt( norm );
fi=acos(cosfi);
if(cosfi<=-1) fi=PI;
if(cosfi>=1) fi=0;
return(fi);
}

double dis(struct XYpoint *a,struct XYpoint *b)
{
struct XYpoint *p1,*p2;
double dsx,dsy,dx;
p1=a;
p2=b;
dsx=p2->x-p1->x;
dsy=p2->y-p1->y;
dx=sqrt(dsx*dsx+dsy*dsy);

return(dx);
}

struct XYpoint *tank( struct XYpoint *head ,struct XYpoint *head2)
{
double minfi,fi;
double dx,dy;
struct XYpoint *p,*p1,*p2;

p2=p=head;
p1=head2;
minfi=PI;
while(p!=NULL)
{
dx=p->x-p1->x;
dy=p->y-p1->y;
if(dx!=0)
{
fi=atan(dy/dx);
if(fi<0)
fi=fi+PI;
}
else if(dx==0&&dy==0) fi=PI;
else fi=PI/2.0;
if(minfi>=fi)
{
minfi=fi;p2=p;
}
p=p->next;
}

return (p2);
}

struct XYpoint *convexHull( struct XYpoint *head ,struct XYpoint *head2)
{

double min;
double tempAngle;
struct XYpoint *lastP,*nowP,*p,*p1,*p2;
p=head;
nowP=p1=head2;
lastP=nowP;
p1=p1->next;
nowP=p1;

while(p1->next!=NULL)
{
p1=p1->next;
lastP=nowP;
nowP=p1;
}

min=angle(lastP,nowP,p);
p2=p;
p=p->next;
while(p!=NULL)
{
tempAngle=angle(lastP,nowP,p);
if (min>tempAngle)
{
min=tempAngle;
p2=p;
p=p->next;
}
else if(min==tempAngle)
{
if(dis(nowP,p2)<dis(nowP,p))
p2=p;
p=p->next;
}
else
{
p=p->next;
}
}

return(p2);
}

void print(struct XYpoint *head2)
{
FILE *fp;
struct XYpoint *p;
p=head2;

if((fp=fopen("out_put.txt","w"))==NULL)
{
printf("can not open the file\n");
exit(0);
}
fprintf(fp,"%ld",pointSum);
fprintf(fp,"\n");
while(p!=NULL)
{
fprintf(fp,"%lf,%lf",p->x,p->y);
fprintf(fp,"\n");
p=p->next;
}
fclose(fp);
}

/*
int _tmain(int argc, _TCHAR* argv[])
{
struct XYpoint *head ,*head2,*pp,*qq;
head=creat();
pp=miny(head);
head2=(struct XYpoint *)malloc(LEN);
head2->x=pp->x;
head2->y=pp->y;
head2->next=NULL;
pp=tank(head,head2);
qq=(struct XYpoint *)malloc(LEN);
qq->x=pp->x;
qq->y=pp->y;
qq->next=NULL;
head2=insert(head2,qq);
head=del(head,pp);
pp=convexHull(head,head2);
do
{
qq=(struct XYpoint *)malloc(LEN);
qq->x=pp->x;
qq->y=pp->y;
qq->next=NULL;
head2=insert(head2,qq);
head=del(head,pp);
pp=convexHull(head,head2);
}while(!(head2->x==pp->x&&head2->y==pp->y));

print(head2);

return 0;
}
*/

//view.h
class CCreateHullView : public CView
{
private:
int m_nPtnum;
XYpoint *m_pPtHead;
XYpoint *m_pHullHead;
};

//view.cpp
CCreateHullView::CCreateHullView()
{
// TODO: add construction code here
m_nPtnum = 0;
m_pPtHead = NULL;
m_pHullHead = NULL;
}

CCreateHullView::~CCreateHullView()
{
if (m_nPtnum > 0)
{
XYpoint *p = m_pPtHead;
while (NULL != p)
{
m_pPtHead = p->next;
p->next = NULL;
delete p;
p = m_pPtHead;
}
m_pPtHead = NULL;
m_nPtnum = 0;

p = m_pHullHead;
while (NULL != p)
{
m_pHullHead = p->next;
p->next = NULL;
delete p;
p = m_pHullHead;
}
m_pHullHead = NULL;
}
}

void CCreateHullView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (0 == m_nPtnum)
{
m_pPtHead = new XYpoint;
m_pPtHead->x = point.x;
m_pPtHead->y = point.y;
m_pPtHead->next = NULL;
m_nPtnum++;
}
XYpoint *p = new XYpoint;
p->x = point.x;
p->y = point.y;
p->next = m_pPtHead;
m_pPtHead = p;
m_nPtnum++;

Invalidate();
CView::OnLButtonDown(nFlags, point);
}

void CCreateHullView::OnCreateHull()
{
// TODO: Add your command handler code here
if (0 < m_nPtnum)
{
struct XYpoint *head ,*head2,*pp,*qq;
head = m_pPtHead;
pp = miny(head);
head2=(struct XYpoint *)malloc(LEN);
head2->x=pp->x;
head2->y=pp->y;
head2->next=NULL;
pp=tank(head,head2);
qq=(struct XYpoint *)malloc(LEN);
qq->x=pp->x;
qq->y=pp->y;
qq->next=NULL;
head2=insert(head2,qq);
head=del(head,pp);
pp=convexHull(head,head2);
do
{
qq=(struct XYpoint *)malloc(LEN);
qq->x=pp->x;
qq->y=pp->y;
qq->next=NULL;
head2=insert(head2,qq);
head=del(head,pp);
pp=convexHull(head,head2);
}while(!(head2->x==pp->x&&head2->y==pp->y));

//print(head2);
m_pHullHead = head2;
Invalidate();
}
}

void CCreateHullView::OnDraw(CDC* pDC)
{
CCreateHullDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

XYpoint *p = NULL;
if (0 < m_pHullHead)
{
p = m_pHullHead;
pDC->Rectangle((int)(m_pHullHead->x) - 2, (int)(m_pHullHead->y) - 2, (int)(m_pHullHead->x) + 2, (int)(m_pHullHead->y) + 2);
pDC->MoveTo((int)(m_pHullHead->x), (int)(m_pHullHead->y));
p = m_pHullHead->next;
while (NULL != p)
{
pDC->Rectangle(
(int)(p->x) - 2,
(int)(p->y) - 2,
(int)(p->x) + 2,
(int)(p->y) + 2
);
pDC->LineTo(CPoint((int)p->x, (int)p->y));
p = p->next;
}
p = m_pHullHead;
pDC->LineTo(CPoint((int)p->x, (int)p->y));

}

p = m_pPtHead;
while (NULL != p)
{
pDC->Rectangle(
(int)(p->x) - 2,
(int)(p->y) - 2,
(int)(p->x) + 2,
(int)(p->y) + 2
);
// pDC->FillSolidRect(
// (int)(p->x) - 2,
// (int)(p->y) - 2,
// (int)(p->x) + 2,
// (int)(p->y) + 2,
// RGB(225, 0, 0)
// );
p = p->next;
}

}
不知道可以不,应该可以运行吧,你先试试

⑧ 如何判断一个区域是否是连通的 matlab

matlab函数_连通区域

1、 matlab函数bwareaopen──删除小面积对象
格式:BW2 = bwareaopen(BW,P,conn)
作用:删除二值图像BW中面积小于P的对象,默认情况下使用8邻域。
算法:
(1)Determine the connected components.
L = bwlabeln(BW, conn);
(2)Compute the area of each component.
S = regionprops(L, 'Area');
(3)Remove small objects.
bw2 = ismember(L, find([S.Area] >= P));

2、matlab函数bwarea──计算对象面积
格式:total = bwarea(BW)
作用:估计二值图像中对象的面积。
注:该面积和二值图像中对象的像素数目不一定相等。

3、matlab函数imclearborder──边界对象抑制
格式:IM2 = imclearborder(IM,conn)
作用:抑制和图像边界相连的亮对象。若IM是二值图,imclearborder将删除和图像边界相连的对象。默认情况conn=8。
注:For grayscale images, imclearborder tends to rece the overall intensity level in addition to suppressing border structures.
算法:
(1)Mask image is the input image.
(2)Marker image is zero everywhere except along the border, where it equals the mask image.

4、matlab函数bwboundaries──获取对象轮廓
格式:B = bwboundaries(BW,conn)(基本格式)
作用:获取二值图中对象的轮廓,和OpenCV中cvFindContours函数功能类似。B是一个P×1的cell数组,P为对象个数,每个cell 是Q×2的矩阵,对应于对象轮廓像素的坐标。

5、matlab函数imregionalmin──获取极小值区域
格式:BW = imregionalmin(I,conn)
作用:寻找图像I的极小值区域(regional maxima),默认情况conn=8。
Regional minima are connected components of pixels with a constant intensity value, and whose external boundary pixels all have a higher value.

6、matlab函数bwulterode──距离变换的极大值
格式:BW2 = bwulterode(BW,method,conn)
作用:终极腐蚀。寻找二值图像BW的距离变换图的区域极大值(regional maxima)。用于距离变换的距离默认为euclidean,连通性为8邻域。

7、regionprops统计被标记的区域的面积分布,显示区域总数。
函数regionprops语法规则为:STATS = regionprops(L,properties)
该函数用来测量标注矩阵L中每一个标注区域的一系列属性。
L中不同的正整数元素对应不同的区域,例如:L中等于整数1的元素对应区域1;L中等于整数2的元素对应区域2;以此类推。

返回值STATS是一个 长度为max(L(:))的结构数组,结构数组的相应域定义了每一个区域相应属性下的度量。

Properties可以是由逗号分割的字符串行表、包含字符 串的单元数组、单个字符串'all'或者'basic'。如果properties等于字符串'all',则表4.1中的度量数据都将被计算;如果properties等于字符串'basic',则属性:'Area','Centroid'和'BoundingBox'将被计算。表1就是所有有效的属性字符串。

表1 属性字符串行表----度量图像区域的属性或功能
'Area' 图像各个区域中像素总个数
'BoundingBox' 包含相应区域的最小矩形
'Centroid' 每个区域的质心(重心)
'MajorAxisLength' 与区域具有相同标准二阶中心矩的椭圆的长轴长度(像素意义下)
'MinorAxisLength' 与区域具有相同标准二阶中心矩的椭圆的短轴长度(像素意义下)
'Eccentricity' 与区域具有相同标准二阶中心矩的椭圆的离心率(可作为特征)
'Orientation' 与区域具有相同标准二阶中心矩的椭圆的长轴与x轴的交角(度)
'Image' 与某区域具有相同大小的逻辑矩阵
'FilledImage' 与某区域具有相同大小的填充逻辑矩阵
'FilledArea' 填充区域图像中的on像素个数
'ConvexHull' 包含某区域的最小凸多边形
'ConvexImage' 画出上述区域最小凸多边形
'ConvexArea' 填充区域凸多边形图像中的on像素个数
'EulerNumber' 几何拓扑中的一个拓扑不变量——欧拉数
'Extrema' 八方向区域极值点
'EquivDiameter' 与区域具有相同面积的圆的直径
'Solidity' 同时在区域和其最小凸多边形中的像素比例
'Extent' 同时在区域和其最小边界矩形中的像素比例
'PixelIdxList' 存储区域像素的索引下标
'PixelList' 存储上述索引对应的像素坐标

⑨ 如何用matlab做convex hull 基于不同分组的点

凸包上的顶点们有顺序的沿着外围绕行一圈。若能照此顺序来包,就不必以穷举所有点的方式来寻找最外围的点。Graham's Scan即是尝试将所有点按照顺序排好,再来做绕一圈的动作。

顺序该如何决定呢?只要能确保凸包各顶点的前后顺序是正确的,那便不会包错。一个简单的想法是依角度排序──只要将中心点设定在凸包内部或设定在凸包上面,便可以确保凸包各顶点的前后顺序必定正确(读者可自行证明此说)。

除了凸包各顶点的前后顺序要正确,另外还要限制所有点依照前后顺序连线起来后,不会绕成超过一个的圈圈,也不会有任何边重叠。更精准的说法是:会形成简单多边形(simple polygon),不会有边相交。如此一来,便不必理会那些不在凸包上面的点的前后顺序,因为那些点会在找最外围的点的时候被淘汰掉(读者可自行证明此说)。
一般来说,选择凸包上面的端点当作排序角度时的中心点是比较好的,因为最大的夹角必会小于180度,而可以使用外积运算来排序。(外积在大于180度时会得负值、等于180度时会等于零,导致排序错误。)
如果凸包各顶点的前后顺序是错误的,或者所有点依照前后顺序连线后产生了很多圈圈,就会发生惨剧。有时甚至会找出凹的形状。
其他细节在算法书籍上面皆可找到,故不细讲。时间复杂度为O(NlogN),主要取决于排序的时间;若用Counting Sort之类的排序方法便可达到O(N);若已知这些点构成的简单多边形之后,便不需排序,就只需O(N)。
若要连凸包上面共线的点都找出来,便要小心处理刚开始包、快要包好时产生共线的情形,这些点的先后顺序决不能乱。
有一个解决方法是分做左右两边包,当排序时遇到角度相同的情况时,令距离离中心点较短的顺序较高。总之相当麻烦,就不细讲了。下面这段程式码写出一些特别要注意的地方:

阅读全文

与convexhull算法相关的资料

热点内容
远程命令阻塞 浏览:728
有网页源码怎么查数据 浏览:99
win10下make编译速度过慢 浏览:864
微机原理编译环境 浏览:17
怎么把图纸转换成pdf 浏览:539
安卓libcurl编译64 浏览:903
手机app怎么测速 浏览:275
中兴gpon命令 浏览:885
python中取出字典key值 浏览:680
Linux目录inode 浏览:146
手机上如何用文件夹发邮件 浏览:428
畅课app密码忘了怎么找回 浏览:79
怎么编译idea 浏览:231
如何查看服务器是否做了热备 浏览:1001
硬盘同名文件夹病毒 浏览:729
百度云不解压下载 浏览:563
新冠疫情app怎么用 浏览:973
拆二代程序员 浏览:400
河北压缩空气冷干机生产厂家 浏览:582
图论与java 浏览:579