www.pudn.com > VoronoiDAC.rar > ConvexHull.cpp, change:2007-01-09,size:12572b
#include "StdAfx.h"
#include "iostream.h"
#include "stdio.h"
#include "conio.h"
#include "malloc.h"
#include "ConvexHull.h"
//struct edge;
//struct site;
//struct vertex;
//struct face ;
//判断(x3,y3)是不是在(x1,y1)(x2,y2)连线的左边.以(x1,y1)为出发点.
int ToLeft(double x1 , double y1, double x2, double y2, double x3, double y3)
{
/*
(
a.x * b.y - a.y * b.x
+ b.x * c.y - b.y * c.x
+ c.x * a.y - c.y * a.x);
*/
double itemp = x1 * y2 - y1 * x2
+ x2 * y3 - y2 * x3
+ x3 * y1 - y3 * x1;
return itemp = 0 ;
}
convex::convex()
{
m_pFirstPoint = NULL;
m_iCount = 0;
m_pLeftMostPoint = NULL;
m_pRightMostPoint = NULL;
}
convex::convex( int iCount)
{
//为点分配空间
m_pFirstPoint = (point_chain *)malloc(iCount * sizeof(point_chain));
m_iCount = 0;
//初始化,最右边和最左边的点为空
m_pLeftMostPoint = NULL;
m_pRightMostPoint = NULL;
}
//用三个点构造一个凸包
convex::convex( site * pFirstSite , site * pSecondSite , site * pThirdSite)
{
//生成三个元素
point_chain * pFirstChain = new point_chain;
point_chain * pSecondChain = new point_chain;
point_chain * pThirdChain = new point_chain;
// site * pLeftSite ;
// site * pMidSite ;
// site * pRightSite;
pFirstChain->pSite = pFirstSite;
pSecondChain->pSite = pSecondSite;
pThirdChain->pSite = pThirdSite;
if (ToLeft(pFirstSite->x,pFirstSite->y,pSecondSite->x,pSecondSite->y,pThirdSite->x,pThirdSite->y) > 0)
{
pThirdChain->next = pSecondChain;
pSecondChain->next = pFirstChain;
pFirstChain->next = pThirdChain;
pFirstChain->previous = pSecondChain;
pSecondChain->previous = pThirdChain;
pThirdChain->previous = pFirstChain;
}
else
{
pThirdChain->next = pFirstChain;
pSecondChain->next = pThirdChain;
pFirstChain->next = pSecondChain;
pFirstChain->previous = pThirdChain;
pSecondChain->previous = pFirstChain;
pThirdChain->previous = pSecondChain;
}
if (pFirstSite->x pSecondSite->x ||( pFirstSite->x == pSecondSite->x && pFirstSite->y pSecondSite->y))
{
m_pLeftMostPoint = pFirstChain;
}
else
{
m_pLeftMostPoint = pSecondChain;
}
if (m_pLeftMostPoint->pSite->x > pThirdSite->x || (m_pLeftMostPoint->pSite->x == pThirdSite->x) && m_pLeftMostPoint->pSite->y > pThirdSite->y)
{
m_pLeftMostPoint = pThirdChain;
}
//最右边
if (pFirstSite->x > pSecondSite->x ||( pFirstSite->x == pSecondSite->x && pFirstSite->y > pSecondSite->y))
{
m_pRightMostPoint = pFirstChain;
}
else
{
m_pRightMostPoint = pSecondChain;
}
if (m_pRightMostPoint->pSite->x pThirdSite->x || (m_pRightMostPoint->pSite->x == pThirdSite->x) && m_pRightMostPoint->pSite->y pThirdSite->y)
{
m_pRightMostPoint = pThirdChain;
}
m_pFirstPoint = pFirstChain;
m_iCount = 3;//三个元素
}
//用两个点构造一个凸包
convex::convex( site * pFirstSite , site * pSecondSite)
{
point_chain * pFirstChain = new point_chain;
point_chain * pSecondChain = new point_chain;
if(pFirstSite->x == pSecondSite->x && pFirstSite->y == pSecondSite->y)
{
printf("wrong input ,the two Sites are the same.\n\n");
return;
}
//选取位置在左边的点作为第一个点,如果x坐标一样,选择坐标靠上的点为第一个点.
if ( (pFirstSite->x pSecondSite->x) ||
(pFirstSite->x == pSecondSite->x && pFirstSite->y pSecondSite->y)
)
{
pFirstChain->pSite = pFirstSite;
pSecondChain->pSite = pSecondSite;
}
else
{
pFirstChain->pSite = pSecondSite;
pSecondChain->pSite = pFirstSite;
}
//形成链表
pFirstChain->next = pSecondChain;
pFirstChain->previous = pSecondChain;
pSecondChain->next = pFirstChain;
pSecondChain->previous = pFirstChain;
m_pFirstPoint = pFirstChain;
m_pLeftMostPoint = pFirstChain;
m_pRightMostPoint = pSecondChain;
m_iCount = 2;//两个元素
}
//返回点数
int convex::GetCount()
{
return m_iCount;
}
void convex::GetFirstPoint(point_chain * * pstruFirstPoint)
{
* pstruFirstPoint = m_pFirstPoint;
}
void convex::GetLeftMostPoint(point_chain * * pLeftMostPoint)
{
* pLeftMostPoint = m_pLeftMostPoint;
}
void convex::GetRightMostPoint(point_chain * * pRightMostPoint)
{
* pRightMostPoint = m_pRightMostPoint;
}
void convex::GetFourMergePoint(const convex * pRightConvex , point_chain * * ppLeftUpSite , point_chain * * ppLeftDownSite , point_chain * * ppRightUpSite , point_chain * * ppRightDownSite)
{
point_chain * pLeftUpSite = new point_chain;
point_chain * pLeftDownSite = new point_chain;
point_chain * pRightDownSite = new point_chain;
point_chain * pRightUpSite = new point_chain;
//初值
pLeftUpSite = m_pRightMostPoint;
pLeftDownSite = m_pRightMostPoint;
pRightUpSite = pRightConvex->m_pLeftMostPoint;
pRightDownSite = pRightConvex->m_pLeftMostPoint;
bool bBreakTag = true;
bool bInsideBreakTag1 = true;
bool bInsideBreakTag2 = true;
//上连线
while(bBreakTag)
{
while(bInsideBreakTag1)
{
int j = ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y,pLeftUpSite->pSite->x,pLeftUpSite->pSite->y,pLeftUpSite->next->pSite->x,pLeftUpSite->next->pSite->y);
//往上移动左边的点,知道左边的闭包已经在上连线的(左边),也就是下面
if (( ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y,pLeftUpSite->pSite->x,pLeftUpSite->pSite->y,pLeftUpSite->next->pSite->x,pLeftUpSite->next->pSite->y) != 1)
|| (ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y,pLeftUpSite->pSite->x,pLeftUpSite->pSite->y,pLeftUpSite->previous->pSite->x,pLeftUpSite->previous->pSite->y) != 1)
)
{
pLeftUpSite = pLeftUpSite->next;
}
//满足条件,不再移动
else
{
bInsideBreakTag1 = false;
}
}//while(bInsideBreakTag1)
while(bInsideBreakTag2)
{
//往上移动右边的点,知道右边的闭包都在上连线的下面
if ( (ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y, pLeftUpSite->pSite->x, pLeftUpSite->pSite->y,pRightUpSite->next->pSite->x, pRightUpSite->next->pSite->y)!=1)
||(ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y, pLeftUpSite->pSite->x, pLeftUpSite->pSite->y,pRightUpSite->previous->pSite->x, pRightUpSite->previous->pSite->y)!=1)
)
{
pRightUpSite = pRightUpSite->previous;
}
else
{
bInsideBreakTag2 = false;
}
}//while(bInsideBreakTag2)
//是否已经满足了两个闭包都在上连线的下面?不是的话就再循环
if( (ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y,pLeftUpSite->pSite->x,pLeftUpSite->pSite->y,pLeftUpSite->next->pSite->x,pLeftUpSite->next->pSite->y) != 1)
|| (ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y,pLeftUpSite->pSite->x,pLeftUpSite->pSite->y,pLeftUpSite->previous->pSite->x,pLeftUpSite->previous->pSite->y) != 1)
|| (ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y, pLeftUpSite->pSite->x, pLeftUpSite->pSite->y,pRightUpSite->next->pSite->x, pRightUpSite->next->pSite->y)!=1)
|| (ToLeft(pRightUpSite->pSite->x, pRightUpSite->pSite->y, pLeftUpSite->pSite->x, pLeftUpSite->pSite->y,pRightUpSite->previous->pSite->x, pRightUpSite->previous->pSite->y)!=1)
)
{
bInsideBreakTag1 = true;
bInsideBreakTag2 = true;
}
//已经找到了上连线.
else
{
bBreakTag = false;
}
}//while(bBreakTag)
bBreakTag =true;
//下连线
while(bBreakTag)
{
while(bInsideBreakTag1)
{
//往下移动左边的点,知道左边的闭包已经在上连线的(左边),也就是下面
if (( ToLeft(pLeftDownSite->pSite->x, pLeftDownSite->pSite->y,pRightDownSite->pSite->x,pRightDownSite->pSite->y,pLeftDownSite->next->pSite->x,pLeftDownSite->next->pSite->y) != 1)
|| (ToLeft(pLeftDownSite->pSite->x, pLeftDownSite->pSite->y,pRightDownSite->pSite->x,pRightDownSite->pSite->y,pLeftDownSite->previous->pSite->x,pLeftDownSite->previous->pSite->y) != 1)
)
{
pLeftDownSite = pLeftDownSite->previous;
}
//满足条件,不再移动
else
{
bInsideBreakTag1 = false;
}
}//while(bInsideBreakTag1)
while(bInsideBreakTag2)
{
//往上移动右边的点,知道右边的闭包都在上连线的下面
if ( (ToLeft(pLeftDownSite->pSite->x, pLeftDownSite->pSite->y, pRightDownSite->pSite->x, pRightDownSite->pSite->y,pRightDownSite->next->pSite->x, pRightDownSite->next->pSite->y)!=1)
||(ToLeft(pLeftDownSite->pSite->x, pLeftDownSite->pSite->y, pRightDownSite->pSite->x, pRightDownSite->pSite->y,pRightDownSite->previous->pSite->x, pRightDownSite->previous->pSite->y)!=1)
)
{
pRightDownSite = pRightDownSite->next;
}
else
{
bInsideBreakTag2 = false;
}
}//while(bInsideBreakTag2)
//是否已经满足了两个闭包都在下连线的上面?不是的话就再循环
if( (ToLeft(pLeftDownSite->pSite->x, pLeftDownSite->pSite->y,pRightDownSite->pSite->x, pRightDownSite->pSite->y,pLeftDownSite->next->pSite->x,pLeftDownSite->next->pSite->y) != 1)
|| (ToLeft(pLeftDownSite->pSite->x, pLeftDownSite->pSite->y,pRightDownSite->pSite->x, pRightDownSite->pSite->y,pLeftDownSite->previous->pSite->x,pLeftDownSite->previous->pSite->y) != 1)
|| (ToLeft(pLeftDownSite->pSite->x, pLeftDownSite->pSite->y, pRightDownSite->pSite->x, pRightDownSite->pSite->y,pRightDownSite->next->pSite->x, pRightDownSite->next->pSite->y)!=1)
|| (ToLeft(pLeftDownSite->pSite->x, pLeftDownSite->pSite->y, pRightDownSite->pSite->x, pRightDownSite->pSite->y,pRightDownSite->previous->pSite->x, pRightDownSite->previous->pSite->y)!=1)
)
{
bInsideBreakTag1 = true;
bInsideBreakTag2 = true;
}
//已经找到了上连线.
else
{
bBreakTag = false;
* ppLeftDownSite = pLeftDownSite;
* ppLeftUpSite = pLeftUpSite;
* ppRightUpSite = pRightUpSite;
* ppRightDownSite= pRightDownSite;
}
}//while(bBreakTag)
}
// NewConvex 开始为空的,立面的元素都是默认值
void convex::MergeWithRightConvex(convex * pRightConvex ,convex * NewConvex)
{
point_chain * pLeftUpPoint ;
point_chain * pLeftDownPoint;
point_chain * pRightDownPoint;
point_chain * pRightUpPoint;
GetFourMergePoint(pRightConvex,&pLeftUpPoint,&pLeftDownPoint,&pRightUpPoint,&pRightDownPoint);
point_chain * ptmpChain;
/* point_chain * ptmpToBeDeletedChain;
ptmpChain = pLeftUpPoint;
while (ptmpChain!=pLeftDownPoint)
{
ptmpToBeDeletedChain = ptmpChain->next;
free(ptmpToBeDeletedChain);
}
ptmpChain = pRightDownPoint;
while (ptmpChain!=pRightUpPoint)
{
ptmpToBeDeletedChain = ptmpChain->next;
free(ptmpToBeDeletedChain);
}
*/
pLeftUpPoint->next = pRightUpPoint;
pRightUpPoint->previous = pLeftUpPoint;
pRightDownPoint->next = pLeftDownPoint;
pLeftDownPoint->previous = pRightDownPoint;
int iNewCount = 0;
ptmpChain = m_pFirstPoint->next;
iNewCount = 1;//已经有一个确定的元素,当前指向的元素还没有检验是不是重复的.
while(ptmpChain!=m_pFirstPoint)
{
iNewCount++;
ptmpChain = ptmpChain->next;
}
NewConvex->m_iCount = iNewCount;
NewConvex->m_pRightMostPoint = pRightConvex->m_pRightMostPoint;
NewConvex->m_pLeftMostPoint = m_pLeftMostPoint;
NewConvex->SetFirstPoint(m_pFirstPoint);
}
void convex::PrintAllSites()
{
point_chain * tmpPointChain = m_pFirstPoint;
for( int i=0; i<m_iCount; i++)
{
printf("X:%f , Y:%f\n" ,tmpPointChain->pSite->x,tmpPointChain->pSite->y);
tmpPointChain = tmpPointChain->next;
}
printf("\n");
}
void convex::SetFirstPoint(point_chain * pFirstPoint)
{
m_pFirstPoint = pFirstPoint;
}
/*
void main()
{
site * psite1 = new site;
site * psite2 = new site;
site * psite3 = new site;
site * psite4 = new site;
site * psite5 = new site;
site * psite6 = new site;
psite1->id =1;
psite1->x = 11;
psite1->y = 13;
//psite1->type =
psite2->id =2;
psite2->x = 14;
psite2->y = 33;
psite3->id =3;
psite3->x = 17;
psite3->y = 21;
psite4->id =4;
psite4->x = 21;
psite4->y = 17;
psite5->id =5;
psite5->x = 31;
psite5->y = 23;
psite6->id =6;
psite6->x = 33;
psite6->y = 15;
convex aConvex = convex(psite1,psite2,psite3);
convex bConvex = convex(psite4,psite5,psite6);
convex cConvex = convex();
point_chain * pChain1 = new point_chain;
point_chain * pChain2 = new point_chain;
point_chain * pChain3 = new point_chain;
point_chain * pChain4 = new point_chain;
//aConvex.GetFourMergePoint(&bConvex, &pChain1, &pChain2 , &pChain3 , &pChain4);
aConvex.MergeWithRightConvex(&bConvex ,&cConvex);
aConvex.PrintAllSites();
cConvex.PrintAllSites();
}
*/