導航:首頁 > 源碼編譯 > 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演算法相關的資料

熱點內容
安卓libcurl編譯64 瀏覽:899
手機app怎麼測速 瀏覽:271
中興gpon命令 瀏覽:881
python中取出字典key值 瀏覽:676
Linux目錄inode 瀏覽:142
手機上如何用文件夾發郵件 瀏覽:424
暢課app密碼忘了怎麼找回 瀏覽:75
怎麼編譯idea 瀏覽:229
如何查看伺服器是否做了熱備 瀏覽:999
硬碟同名文件夾病毒 瀏覽:727
百度雲不解壓下載 瀏覽:560
新冠疫情app怎麼用 瀏覽:971
拆二代程序員 瀏覽:398
河北壓縮空氣冷干機生產廠家 瀏覽:580
圖論與java 瀏覽:577
程序員寫代碼告白初音 瀏覽:740
sshpdf 瀏覽:539
windows調用linux 瀏覽:594
如何查找本地伺服器名稱 瀏覽:820
linux文件只讀屬性 瀏覽:586