Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Рандомизированный алгоритм построения выпуклой оболочки / program / CHList
.cpp#include "stdafx.h"
#include "randch.h"
#include "CHList.h"
#include <stdlib.h>
//#include <WINDEF.H>
//#include <stdio.h>
#ifdef _DEBUG
#undef THIS_FILE
//static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
CCHList::CCHList(void)
{
}
CCHList::~CCHList(void)
{
}
CCHList CCHList::RandCH3(int &n)
{
CCHList ch3;
CCHPoint *tmp;
list<CCHPoint*>::iterator i;
div_t div_res;
// n=data.size();
srand( (unsigned)time( NULL ) );
int k=rand();
div_res=div(k,n);
i=data.begin();
for (k=1;k<div_res.rem+1;k++) i++;
tmp=(*i);
ch3.data.push_back(tmp);
data.erase(i);
data.push_back(tmp);
n--;
div_res=div(rand(),n);
i=data.begin();
for (k=1;k<div_res.rem+1;k++) i++;
tmp=(*i);
data.erase(i);
data.push_back(tmp);
i=ch3.data.begin();
if ((*i)->p.x>tmp->p.x)
ch3.data.push_front(tmp);
else
ch3.data.push_back(tmp);
n--;
div_res=div(rand(),n);
i=data.begin();
for (k=1;k<div_res.rem+1;k++) i++;
tmp=(*i);
data.erase(i);
data.push_back(tmp);
n--;
// Comparing with x
i=ch3.data.begin();
if (tmp->p.x<(*i)->p.x)
{
ch3.data.push_front(tmp);
}
else
{
++i;
if(tmp->p.x > (*i)->p.x)
{
ch3.data.push_back(tmp);
}
else
{
ch3.data.insert(i,tmp);
}
}
FlPoint p[3];
int mc=0;
for (i=ch3.data.begin();!(i==ch3.data.end());++i)
{
p[mc]=(*i)->p;
mc++;
}
float det=p[0].x * (p[1].y - p[2].y) + p[0].y * (p[2].x - p[1].x) + p[1].x * p[2].y - p[2].x * p[1].y;
if(det>0)
// Если поворот правый, то нужно сделать, чтобы он был левым
// (Вообще < 0, НО здесь > 0, т.к. ось Y на экране ориентирована иначе)
{
i = ch3.data.begin();
++i;
ch3.data.push_back(*i);
ch3.data.erase(i);
}
return ch3;
}
CCHList CCHList::BuildCH(int &n)
{
CCHList ch;
CCHPoint *tmp;
list<CCHPoint*>::iterator i,l,r,u,d;
i=data.begin();
l=i;
r=i;
u=i;
d=i;
++i;
for (i;i!=data.end();++i)
{
if((*i)->p.x<(*l)->p.x)l=i;
if((*i)->p.x>(*r)->p.x)r=i; if((*i)->p.y<(*u)->p.y)u=i; if((*i)->p.y>(*d)->p.y)d=i;
}
tmp=(*l);
ch.data.push_back(tmp);
data.erase(l);
data.push_back(tmp);
n--;
tmp=(*d);
ch.data.push_back(tmp);
data.erase(d);
data.push_back(tmp);
n--;
tmp=(*r);
ch.data.push_back(tmp);
data.erase(r);
data.push_back(tmp);
n--;
tmp=(*u);
ch.data.push_back(tmp); data.erase(u); data.push_back(tmp);
n--;
return ch;
}
FlPoint CCHList:: CentrPoint(CCHList ch3)
{
list<CCHPoint*>::iterator i;
FlPoint p[3];
FlPoint ml3,m23,cp;
int mc=0;
for (i=ch3.data.begin();!(i==ch3.data.end());++i)
{
p[mc]=(*i)->p;
mc++;
}
float d;
ml3.x = (p[0].x+p[2].x)/2; ml3.y=(p[0].y+p[2].y)/2;
m23.x = (p[1].x+p[2].x)/2; m23.y=(p[1].y+p[2].y)/2;
d=(m23.y-p[0].y)*(p[1].x-ml3.x)-(p[0].x-m23.x)*(ml3.y-p[1].y);
cp.x=((p[0].x-m23.x)*(p[1].y*ml3.x-p[1].x*ml3.y)-(p[0].y*m23.x-p[0].x*m23.y)*(p[1].x-ml3.x))/d;
cp.y=((p[0].y*m23.x-p[0].x*m23.y)*(ml3.y-p[1].y)-(m23.y-p[0].y)*(p[1].y*ml3.x-p[1].x*ml3.y))/d;
return cp; }
FlPoint CCHList:: InPoint(CCHList ch)
{
list<CCHPoint*>::iterator i;
FlPoint p[3];
FlPoint ml3, m23, cp;
int mc=0;
i=ch.data.begin();
for(int k=1; k<=3; ++k)
{
p[mc]=(*i)->p; mc++;
++i;
}
float d;
ml3.x=(p[0].x+p[2].x)/2;
ml3.y=(p[0].y+p[2].y)/2;
m23.x=(p[1].x+p[2].x)/2;
m23.y=(p[1].y+p[2].y)/2;
d=(m23.y-p[0].y)*(p[1].x-ml3.x)-(p[0].x-m23.x)*(ml3.y-p[1].y);
cp.x=((p[0].x-m23.x)*(p[1].y*ml3.x-p[1].x*ml3.y)-(p[0].y*m23.x-p[0].x*m23.y)*(p[1].x-ml3.x))/d;
cp.y=((p[0].y*m23.x-p[0].x*m23.y)*(ml3.y-p[1].y)-(m23.y-p[0].y)*(p[1].y*ml3.x-p[1].x*ml3.y))/d;
return cp;
}
bool CCHList::IsOutside(FlPoint cp, list<CCHPoint*>::iterator it, CCHList &ch)
{
list<CCHPoint*>::iterator i,i1;
FlPoint interp;
bool found;
float d;
i = ch.data.begin();
i1 = ch.data.begin();
++i1;
found = false;
while(i != ch.data.end())
{
d=((*i1)->p.y-(*i)->p.y)*((*it)->p.x-cp.x)-((*i)->p.x-(*i1)->p.x)*(cp.y-(*it)->p.y);
if(d!=0)
{
interp.x=(((*i)->p.x-(*i1)->p.x)*((*it)->p.y*cp.x-(*it)->p.x*cp.y)-((*i)->p.y*(*i1)->p.x-(*i)->p.x*(*i1)->p.y)*((*it)->p.x-cp.x))/d;
interp.y=(((*i)->p.y*(*i1)->p.x-(*i)->p.x*(*i1)->p.y)*(cp.y-(*it)->p.y)-((*i1)->p.y-(*i)->p.y)*((*it)->p.y*cp.x-(*it)->p.x*cp.y))/d;
if (((min((*i)->p.x,(*i1)->p.x)<=interp.x)&&(interp.x<=max((*i)->p.x,(*i1)->p.x)))&&
((min((*i)->p.y,(*i1)->p.y)<=interp.y)&&(interp.y<=max((*i)->p.y,(*i1)->p.y)))&&
((min((*it)->p.x,cp.x)<=interp.x)&&(interp.x<=max((*it)->p.x,cp.x)))&&
((min((*it)->p.y,cp.y)<=interp.y)&&(interp.y<=max((*it)->p.y,cp.y))))
{
(*it)->l_i.push_back(i);
(*i)->l_i.push_back(it);
return true;
}
}
++i;
++i1;
if(i1 == ch.data.end()) {
i1 = ch.data.begin();
}
}
return found;
}
void CCHList::Pointers(FlPoint cp, int &n, CCHList &ch, int &count) {
list<CCHPoint*>::iterator i;
list<list<CCHPoint*>::iterator>::iterator i_i;
CCHPoint *tmp;
count=0;
i=data.begin();
for (int k=1 ;k<=n;++k)
{
++count;
if (!IsOutside(cp,i,ch))
{
tmp=(*i);
i = data.erase(i);
data.push_back(tmp);
--n;
--k;
}
else
{
++i;
}
}
}
list<CCHPoint*>::iterator CCHList::LeftAdjInCH(list<CCHPoint*>::iterator it, CCHList &ch, list<list<CCHPoint*>::iterator> &tmp_1)
{
list<list<CCHPoint*>::iterator>::iterator i_i; // Итератор по списку итераторов
list<CCHPoint*>::iterator i,i1 ,li;
i_i=(*it)->l_i.begin(); // Устанавливаем итератор в списке итераторов точки
i=(*i_i); //Итератор на точку в оболочке
FlPoint v1,v2;
// Влево по списку вершин
if (i==ch.data.begin())
{
i1 = ch.data.end();
--i1;
}
else
{
i1=i;
--i1;
}
v1=(*i1)->p;
v2=(*i)->p;
float det=v1.x*(v2.y-(*it)->p.y)+v1.y*((*it)->p.x-v2.x)+v2.x*(*it)->p.y-(*it)->p.x*v2.y;
tmp_1=(*i)->l_i;
(*i)->l_i.clear();
while (det>=0) //поворот правый (а нам, чтобы вставить, нужен левый)
{
//Сохраняем список итераторов на точки, пересекающих ребро, на которое указывает i (vlv2)
i_i=tmp_1.end();
tmp_1.splice(i_i,(*i1)->l_i);
(*i1)->l_i.clear();
ch.data.erase(i);
i=i1;
if (i==ch.data.begin())
{
i1 = ch.data.end(); --i1;
}
else
--i1;
v1=(*i1)->p;
v2=(*i)->p;
det=v1.x*(v2.y-(*it)->p.y)+v1.y*((*it)->p.x-v2.x)+v2.x*(*it)->p.y-(*it)->p.x*v2.y;
}
li=i;
return li;
}
list<CCHPoint*>::iterator CCHList::RightAdjInCH(list<CCHPoint*>::iterator it, list<CCHPoint*>::iterator lft_it, CCHList &ch, list<list<CCHPoint*>::iterator> &tmp_1)
{
list<list<CCHPoint*>::iterator>::iterator i_i; // Итератор по списку итераторов
list<CCHPoint*>::iterator i,i1,i2,ri;
FlPoint v1,v2;
i=lft_it;
i++;
if (i==ch.data.end()) i=ch.data.begin();
//идем вправо
i1=i;
i1++;
if (i1==ch.data.end()) i1=ch.data.begin();
v1=(*i1)->p;
v2=(*i)->p;
float det=(*it)->p.x*(v2.y-v1.y)+(*it)->p.y*(v1.x-v2.x)+v2.x*v1.y-v1.x*v2.y;
while (det>=0) //поворот правый (а нам, чтобы вставить, нужен левый)
{
i_i=tmp_1.end();
tmp_1.splice(i_i,(*i)->l_i);
(*i)->l_i.clear();
ch.data.erase(i);
i=i1;
++i1;
if (i1==ch.data.end()) i1=ch.data.begin();
v1=(*i1)->p;
v2=(*i)->p;
det=(*it)->p.x*(v2.y-v1.y)+(*it)->p.y*(v1.x-v2.x)+v2.x*v1.y-v1.x*v2.y;
}
ri=i;
return ri;
}
bool CCHList::IsOutsidePart(FlPoint cp, list<CCHPoint*>::iterator it, list<CCHPoint*>::iterator left_it, CCHList &ch)
{
list<CCHPoint*>::iterator i,i1;
FlPoint interp;
bool found; // HaH#eHo nepeceKaeMoe pe6po/TOHKa Ha pe6pe
float d;
int count=0;
i=left_it;
i1=i;
++i1;
if (i1 == ch.data.end())
i1=ch.data.begin();
found=false;
while (count<2 && !found)
{
d=((*i1)->p.y-(*i)->p.y)*((*it)->p.x-cp.x)-((*i)->p.x-(*i1)->p.x)*(cp.y-(*it)->p.y);
if(d!=0)
{
interp.x=(((*i)->p.x-(*i1)->p.x)*((*it)->p.y*cp.x-(*it)->p.x*cp.y)-((*i)->p.y*(*i1)->p.x-(*i)->p.x*(*i1)->p.y)*((*it)->p.x-cp.x))/d;
interp.y=(((*i)->p.y*(*i1)->p.x-(*i)->p.x*(*i1)->p.y)*(cp.y-(*it)->p.y)-((*i1)->p.y-(*i)->p.y)*((*it)->p.y*cp.x-(*it)->p.x*cp.y))/d;
if (((min((*i)->p.x,(*i1)->p.x)<=interp.x)&&(interp.x<=max((*i)->p.x,(*i1)->p.x)))&&
((min((*i)->p.y,(*i1)->p.y)<=interp.y)&&(interp.y<=max((*i)->p.y,(*i1)->p.y)))&&
((min((*it)->p.x,cp.x)<=interp.x)&&(interp.x<=max((*it)->p.x,cp.x)))&&
((min((*it)->p.y,cp.y)<=interp.y)&&(interp.y<=max((*it)->p.y,cp.y))))
{
(*it)->l_i.clear(); (*it)->l_i.push_back(i); (*i)->l_i.push_back(it); found=true;
}
else
d=0;
}
if(d==0)
{
i=i1;
++i1;
if (i1==ch.data.end())
i1=ch.data.begin();
count++;
}
}
return found;
}
void CCHList::NewPointers(list<CCHPoint*>::iterator cur, list<CCHPoint*>::iterator lft_it, FlPoint cp, int &n, CCHList &ch, list<list<CCHPoint*>::iterator> &tmp_1, int &count)
{
list<list<CCHPoint*>::iterator>::iterator i_i; // Итератор по списку итераторов
CCHPoint *tmp;
list<CCHPoint*>::iterator i;
count=0;
for(i_i=tmp_1.begin();i_i!=tmp_1.end();++i_i)
{
++count;
i=(*i_i);
if ((i==cur)||(!IsOutsidePart(cp,i,lft_it,ch) ) )
{
tmp=(*i);
i = data.erase(i);
data.push_back(tmp);
--n;
}
}
tmp_1.clear();
}
Соседние файлы в папке program