Скачиваний:
19
Добавлен:
01.05.2014
Размер:
9.33 Кб
Скачать
#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