Скачиваний:
21
Добавлен:
01.05.2014
Размер:
20.61 Кб
Скачать
#include "stdafx.h"
#include <math.h>
#include "CH.h"

//#define n_fin "List_p.TXT"
const gr_x=1024,gr_y=768;
const double sc_x=gr_x,sc_y=gr_y,NaN=1e20;
const double eps=0.00001;

uint all_el=0;

COLORREF cDivLine=RGB(255,0,0);
int psDivLine = PS_SOLID;
int wDivLine = 1;

COLORREF cDivPoint=RGB(255,0,0);
int psDivPoint = PS_SOLID;
int wDivPoint = 1;

COLORREF cMedia=RGB(100,0,100);
int psMedia = PS_SOLID;
int wMedia = 1;

COLORREF cPairs=RGB(0,255,0);
int psPairs = PS_SOLID;
int wPairs = 1;

COLORREF cLifePoint=RGB(0,0,255);
int psLifePoint = PS_SOLID;
int wLifePoint = 1;

COLORREF cDiedPoint=RGB(40,200,200);
int psDiedPoint = PS_SOLID;
int wDiedPoint = 1;

COLORREF cOpora=RGB(0,0,0);
int psOpora = PS_DASH;
int wOpora = 1;

COLORREF cCurCH=RGB(45,0,0);
int psCurCH = PS_SOLID;
int wCurCH = 1;

COLORREF cCH=RGB(255,255,0);
int psCH = PS_SOLID;
int wCH = 2;

COLORREF cNewEdge=RGB(255,255,0);
int psNewEdge=PS_SOLID;
int wNewEdge=1;

//===================================
void PrErr(char *s,char *FName)
{ char s1[256]="";
	sprintf(s1,s,FName);
	AfxMessageBox(s1,MB_OK|MB_ICONSTOP);	
	exit (1);
}

//===================================
tpoint* ReadMas(TMyPointVector &p)
{  
		char *FName="ReadFin";
		uint i;
		tpoint *Ar=NULL;
	 	 
	 all_el=p.N();
	 //Ar=(tpoint*) calloc(all_el,sizeof(tpoint));
	 Ar= new tpoint[(all_el)];
	 
	 if (Ar==NULL) { PrErr("%s :Error not enough memory\n",FName);}
	 for (i=0;i<all_el;i++)
	 {
		 Ar[i].x=(double) p.X(i);
		 Ar[i].y=(double) p.Y(i);
	 }
	return Ar;
}
//===================================
int VDraw_A(tpoint* Ar,uint end,TImage &Img,COLORREF Color, int PenStyle, int nWidth,int f)
{
	CPen pen(PenStyle, nWidth, Color);
    CPen *pOldPen = Img.hMem.SelectObject(&pen);

	CBrush hBrush(Color);
    CBrush  *pOldBrush = Img.hMem.SelectObject(&hBrush);

	for (uint i=0;i<=end;i++)
	{
		if (f)
		 {	
	 Img.hMem.MoveTo((int) Ar[i].x, 0);
     Img.hMem.LineTo((int) Ar[i].x, (int) gr_y);
		}
	 	else
		 {	//fillellipse(Ar[i].x*sc_x,gr_y-Ar[i].y*sc_y,2,2);
			//circle(Ar[i].x*sc_x,gr_y-Ar[i].y*sc_y,2);
		Img.hMem.Ellipse(Ar[i].x-3, gr_y-Ar[i].y-3,Ar[i].x+4, gr_y-Ar[i].y+4);
			}
	}
	
	Img.hMem.SelectObject(pOldBrush);
	Img.hMem.SelectObject(pOldPen);
	return 0;
}
//===================================
int VDraw_P(const tpqs* P,uint end,TImage &Img,COLORREF Color, int PenStyle, int nWidth)
{
	CPen pen(PenStyle, nWidth, Color);
    CPen *pOldPen = Img.hMem.SelectObject(&pen);

	CString hString;
	uint i=0;
	for (i=0;i<=end;i++)
	{
	 Img.hMem.MoveTo((int) P[i].p.x, (int) gr_y-P[i].p.y);
     Img.hMem.LineTo((int) P[i].q.x, (int) gr_y-P[i].q.y);
	 	
	 if (P[i].s>=NaN) {hString.Format("%2.2f",NaN);}
	  else {hString.Format("%2.2f",P[i].s);}
	 
	 Img.hMem.TextOut((int) P[i].p.x, (int) gr_y-P[i].p.y, hString);
	}
	Img.hMem.SelectObject(pOldPen);
	return 0;
}
//===================================
int VDraw_Q(QUEUE<tpqs> *Q,TImage &Img,COLORREF Color, int PenStyle, int nWidth)
{
	CPen pen(PenStyle, nWidth, Color);
    CPen *pOldPen = Img.hMem.SelectObject(&pen);

	CString hString;
	const tpqs* p;
		Q->Go_Beg();
		do
		{
			if (Q->IsEnd()) {break;}
			p=Q->Go_Next();

	 Img.hMem.MoveTo((int) p->p.x, (int) gr_y-p->p.y);
     Img.hMem.LineTo((int) p->q.x, (int) gr_y-p->q.y);

		if (p->s>=NaN)
			{hString.Format("%2.2f",NaN);}
		else
			{hString.Format("%2.2f",p->s);}

		
       Img.hMem.TextOut((int) p->p.x, (int) gr_y-p->p.y, hString);
		
		}
		while(!Q->IsEnd());
		Q->Go_Beg();

  Img.hMem.SelectObject(pOldPen);
	return 0;
}
//===================================
int sort_points(const void *a,const void *b)
{
   tpoint *l,*r;
   l=(tpoint*) a;r=(tpoint*) b;
   if (l->x  >  r->x) return 1;
   if (l->x  <  r->x) return -1;
   if (l->x ==  r->x)
     { if (l->y >  r->y) return 1;
       if (l->y <  r->y) return -1;
       if (l->y ==  r->y) return 0;
     }
   return 0;
}
//===================================
int sort_pairs(const void *a,const void *b)
{
   tpqs *l,*r;
   l=(tpqs*) a;r=(tpqs*) b;
   if (l->s  >  r->s) return 1;
   if (l->s  <  r->s) return -1;
   if (l->s ==  r->s) return 0;
  return 0;
}
//===================================
int Search_Median(tpoint *Ar,uint beg,uint end,tpoint* M,uint *fl)
{ double m;
    m=(beg+end)/2.0;
    if ((int) m!=m)
      {*fl=1;}
     else {*fl=0;}
     M->x = (Ar[(int) m].x+Ar[(int) (m+*fl)].x)/2.0;
     M->y = (Ar[(int) m].y+Ar[(int) (m+*fl)].y)/2.0;
	 
  return (int) m;
}
//===================================
tpqs* Pairs(tpoint *Ar,uint beg,uint end,tpoint M,uint fl,
							double *s,uint *vf,uint *n)
{uint k=0,i=0,j=0,p=0;
 tpqs* R;
 tpoint a,b;
 double sl=0;
 char *FName="Pairs";
	 i=beg;j=end;
	 while (Ar[i].x<=M.x&&Ar[j].x>=M.x)
		{if (fabs(Ar[i].x-M.x)<eps)
		   {
		     if(Ar[i].y>=M.y) break;
			}
		 if (fabs(Ar[j].x-M.x)<eps)
		   {
		     if(Ar[j].y<=M.y) break;
			}	
		 k++;
		 i++;j--;
		}
		if (k==0)
			{ PrErr("%s :Error k==0\n",FName);}
		*n=k;
		//R= (tpqs *) calloc(k, sizeof(tpqs));
		R=  new tpqs[k];
		if (R==NULL)
			{ PrErr("%s :Error not enough memory\n",FName);}
		for (i=0;i<k;i++)
		{ a=Ar[beg+i];b=Ar[end-i];
			R[i].p=a;
			R[i].q=b;
			if ((a.x-b.x)==0)
				{R[i].s=NaN;}//Warning
			else
				{R[i].s=(a.y-b.y)/(a.x-b.x);}
			//draw pairs
		}
		//Search Median for sl
		qsort((void *)R, k, sizeof(tpqs), sort_pairs);
		if (k%2==0)
		{	sl=(R[(int) ((k-1)/2)].s+R[(int) (k/2)].s)/2;
		 if (R[(int) ((k-1)/2)].s==NaN&&R[(int) (k/2)].s<NaN) 
			{sl=R[(int) (k/2)].s+0.1;}
		 if (R[(int) ((k-1)/2)].s<NaN&&R[(int) (k/2)].s==NaN) 
			{sl=R[(int) (k-1)/2].s+0.1;}
		 *vf=1;
		}
		else
		{sl=(R[(int) ((k-1)/2)].s);
		 *vf=0;
		}
		//*s=R[(int) (k/2.0)].s;//or *s=(R[k/2.0]+R[k/2.0+1])/2.0 ???
		*s=sl;
		return R;

}
//===================================
int Opor_Line(tpoint* Ar,uint beg,uint end,tpoint M,uint fl,double s,
					 uint *num,int fl_up,TImage &Img)
{ uint k=0,i=0,j=0,l=0,r=0;
	double b_m=-fl_up*NaN,b;
	tpqs P;
	char *FName="Opor_Line";
		if (s==NaN) 
		{
		  if (end-beg+1>2)
		  {*num=end;
		    return 0;
		  }
		  else
		  {*num=beg;
		   return 0;
		  }
		}
		for(i=beg;i<=end;i++)
		{
			b=Ar[i].y-Ar[i].x*s;
			if (fl_up*b>fl_up*b_m)
			{
				b_m=b;
				j=i;
			}
		}
		*num=j;
		if (j>end)
		{PrErr("%s:num>end",FName);}
		P.p.x=0;P.p.y=b_m;
		P.q.x=gr_x;P.q.y=s*P.q.x+b_m;
		P.s=s;
		
		if(Img.hDraw) VDraw_P(&P,0,Img,cOpora,psOpora,wOpora);

		for (i=beg;i<=end;i++)
		{ if (Ar[i].x<=M.x&&fabs(Ar[i].x*s+b_m-Ar[i].y)<eps)
				 {if(fabs(Ar[i].x-M.x)>eps||Ar[i].y<M.y)
						{l++;}
					}
			 if(Ar[i].x>=M.x&&fabs(Ar[i].x*s+b_m-Ar[i].y)<eps)
				 {if(fabs(Ar[i].x-M.x)>eps||Ar[i].y>M.y)
					{r++;}
					}
		}

		if (!fl&&fabs(M.x*s+b_m-M.y)<eps)
		{if (r>0) r++;}//???
		
		//if ((l>1&&r>=1)||(l>=1&&r>1))
		//  return 0;
		

		 
		if (l&&r) return 0;
		if (l) return -1;
		if (r) return 1;
	 return 2;
}

//===================================
tpoint* Update(tpoint* Ar,uint all,tpqs* R,double sl,uint vf,uint k,tpoint M,uint *fl,int side,
						tpoint* El,uint *n,int fl_up)
{ QUEUE<tpoint> Q;
	tpoint* P;
	const tpoint *el;
	int i,j;
	int j_p=0,j_q=0,j_xmin=0,j_xmax=0,j_ymin=0,j_ymax=0,f_p=1,f_q=1;
	double b,s_min=fl_up*NaN,s_max=-fl_up*NaN,s_p,s_q,
		d_p,d_q,d_pmin=NaN,d_qmin=NaN,
		x_min=NaN,x_max=-NaN,y_min=NaN,y_max=-NaN;

	char* FName="Update";

		if (side==0)
		{ 
			if (sl!=NaN) 
			{b=El->y-El->x*sl;}
			 else
			 {b=0;}
			i=0;j=all-1;
			f_p=(Ar[i].x<=M.x); f_q=(Ar[j].x>=M.x);
			
		while ((Ar[i].x<=M.x&&f_p)||(Ar[j].x>=M.x&&f_q))
		{	if (f_p)
			{
				if (fabs(Ar[i].x-M.x)<eps)
					{
					if(Ar[i].y>=M.y) f_p=0;
					}
				if (f_p)
				{
					if (sl!=NaN)
					{
						if (fabs(Ar[i].x*sl+b-Ar[i].y)<eps)
						{if (Ar[i].x<=x_min)
							{x_min=Ar[i].x;
						     j_xmin=i;
							}
						//Q.Push(&Ar[i]);
						}					
						i++;
					}
					else
					{	if  (Ar[i].y<M.y&&fabs(Ar[i].x-M.x)<eps)
						{if (Ar[i].y<=y_min)
							{y_min=Ar[i].y;
						     j_ymin=i;
							}
						//Q.Push(&Ar[i]);
						}					
						i++;
					}

				}				
				if (i>=all) {f_p=0;i=all-1;}

			}
			if (f_q)
			{
				if (fabs(Ar[j].x-M.x)<eps)
					{
					if(Ar[j].y<=M.y) f_q=0;
					}				
				if(f_q)
				{
					if (sl!=NaN)
					{	if (fabs(Ar[j].x*sl+b-Ar[j].y)<eps)
						{if (Ar[j].x>=x_max)
							{x_max=Ar[j].x;
						     j_xmax=j;
							}
						//Q.Push(&Ar[j]);
						}						
						j--;			 
					}
					else
					{if  (Ar[j].y>M.y&&fabs(Ar[j].x-M.x)<eps)
						{if (Ar[j].y>=y_max)
							{y_max=Ar[j].y;
						     j_ymax=j;
							}
						//Q.Push(&Ar[j]);
						}						
						j--;			 
					}
				 }				
				if (j<0) {f_q=0;j=0;}
			}
			}
		if (sl!=NaN)
			{Q.Push(&Ar[j_xmin]);
			 Q.Push(&Ar[j_xmax]);
			}
		else
			{Q.Push(&Ar[j_ymin]);
			 Q.Push(&Ar[j_ymax]);
			}			

		}
		if (side==2)
		{
		  
		 i=0;j=all-1;
		 f_p=(Ar[i].x<=M.x); f_q=(Ar[j].x>=M.x);
		 while ((Ar[i].x<=M.x&&f_p)||(Ar[j].x>=M.x&&f_q))
		 {	if (f_p)
			{
			 if (fabs(Ar[i].x-M.x)<eps)
				{
				if(Ar[i].y>=M.y) f_p=0;
				}
		     if (f_p)
			 {
				if (Ar[i].x-M.x==0)
					{s_p=NaN;}
				else
					{s_p=(Ar[i].y-M.y)/(Ar[i].x-M.x);}
				d_p=sqrt((Ar[i].y-M.y)*(Ar[i].y-M.y)+(Ar[i].x-M.x)*(Ar[i].x-M.x));  
				if (fl_up*s_p<=fl_up*s_min)
				{ if (fabs(s_p-s_min)<eps)
					{ if (d_p<d_pmin)
						{ d_pmin=d_p;
							j_p=i;
						}
					}
					else
					{j_p=i;d_pmin=NaN;}
					s_min=s_p;
				}
				i++;			 
			 }
			 if (i>=all) {f_p=0;i=all-1;}
			 //else {i=all-1;}
			}
           if (f_q)
           {
			if (fabs(Ar[j].x-M.x)<eps)
				{
				if(Ar[j].y<=M.y) f_q=0;
				}
			if(f_q)
			{
				if (Ar[j].x-M.x==0)
					{s_q=NaN;}
				else  s_q=(Ar[j].y-M.y)/(Ar[j].x-M.x);
				d_q=sqrt((Ar[j].y-M.y)*(Ar[j].y-M.y)+(Ar[j].x-M.x)*(Ar[j].x-M.x));
				if (fl_up*s_q>=fl_up*s_max)
					{ if (fabs(s_q-s_max)<eps)
						 { if (d_q<d_qmin)
							{ d_qmin=d_q;
								j_q=j;
							}	
						}
						else
						{j_q=j;d_qmin=NaN;}
						s_max=s_q;
					}

				j--;			 
			 }
			//else {j=0;}
			if (j<0) {f_q=0;j=0;}
		   }	
				
			
			
		}		
			  
			
		if (fl_up*s_min<-fl_up*s_max)
		    Q.Push(&Ar[j_p]);
		   else
		    Q.Push(&Ar[j_q]);
		}
	    
		if (!Q.Count())
		{
		for(i=0;i<k;i++)
		{
			if (side<0)
			{
			 if (R[i].s*fl_up<sl*fl_up)
				{Q.Push(&R[i].p);}
			   Q.Push(&R[i].q);
			  }
			if (side>0)
			 {  if (R[i].s*fl_up>sl*fl_up)
				{Q.Push(&R[i].q);}
			     Q.Push(&R[i].p);
			 }
			 if (side==0)
			  {
					/* if (vf)
					 {
						 if (fabs(R[i].p.x*sl+b-R[i].p.y)<eps)
							{Q.Push(&R[i].p);}
						 if (fabs(R[i].q.x*sl+b-R[i].q.y)<eps)
							{Q.Push(&R[i].q);}
					 }
					 else
					 {*/
						if ((fabs(El->x-R[i].p.x)<eps&&(fabs(El->y-R[i].p.y)<eps)||
							 (fabs(El->x-R[i].q.x)<eps)&&fabs(El->x-R[i].q.x)<eps))
						{
							Q.Push(&R[i].p);
							Q.Push(&R[i].q);
							if (Q.IsEmpty())
								{PrErr("%s:Error QUEUE\n",FName);}
							i=k;
							}
					//}
				}
		}
	      }
	//if (side==2) Q.Push(El);
	//if (side==2&&!*fl)//or 
	if	(side!=0&&!*fl)
		{Q.Push(&M);}
	 else {*fl=1;}
	if (side!=0&&side!=2)
	{	for (i=k;i<all-k;i++)
		{
			if (fabs(M.x-Ar[i].x)>eps||fabs(M.y-Ar[i].y)>eps)
				{Q.Push(&Ar[i]);}
		}
	}

	*n=Q.Count();
	if (*n==0)
	{ PrErr("%s:n==0 \n",FName);}
	//P=(tpoint*) calloc(*n,sizeof(tpoint));
	P=new tpoint[*n];
	if (P!=NULL)
	{ Q.Go_Beg();
			for(i=0;i<*n;i++)
			{  if (!Q.IsEnd())
				 {el=Q.Go_Next();
					P[i].x= el->x;
					P[i].y= el->y;
					
				 }
			}
			Q.Go_Beg();
			qsort((void *)P, (int)*n, sizeof(tpoint), sort_points);
	}
	else
	{ PrErr("%s :Error not enough memory\n",FName);}

	return P;
}
//===================================
tpqs* Bridge(tpoint *Ar,uint beg,uint end,int fl_up,TImage &Img,BOOL hDraw,int f)
{uint b,e,m,n,num,vf,p;
 tpoint *UAr;
 static tpoint M;
 static uint fl;
 tpqs *R,*Rez;
 double sl;
 int c;
 static int side;
 char *FName="Bridge";
 static int ind=1;
 static tpoint *W;
 static uint w;
 
//com if (f) VDraw_A(W,w,Img,RGB(250,50,0),PS_SOLID, 1);

 if (Img.hStepOn)
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) Img.hDraw=true;
	}	
		if(Img.hDraw) VDraw_A(Ar,end,Img,cDiedPoint,psDiedPoint,wDiedPoint);

		b=beg;	e=end;
		if (!f||fabs(side)==3)
		{ 	m=Search_Median(Ar,b,e,&M,&fl);//Sl=[b,m-!fl] Sr=[m+1,e]
		}		
		
        if(Img.hDraw) VDraw_A(&M,0,Img,cMedia,psMedia,wMedia,1);
		
		R=Pairs(Ar,b,e,M,fl,&sl,&vf,&p);
  
		if(Img.hDraw) VDraw_P(R,p-1,Img,cPairs,psPairs,wPairs);
	
		side=Opor_Line(Ar,b,e,M,fl,sl,&num,fl_up,Img);
 		
		UAr=Update(Ar,e-b+1,R,sl,vf,p,M,&fl,side,&Ar[num],&n,fl_up);
		if(Img.hDraw) 
		{ VDraw_A(UAr,n-1,Img,cLifePoint,psLifePoint,wLifePoint);			
		  Img.hDraw=false;
		}

		if (R!=NULL) free(R);
		if (side==0||side==2)
		 { Rez=new  tpqs;
		   if (Rez==NULL) {PrErr("%s:Error -not enough memory",FName);}
		   Rez->p=UAr[0];
		   Rez->q=UAr[1];
		   if ((UAr[0].x-UAr[1].x)==0)
		   { Rez->s=NaN;}
		   else
		   { Rez->s=(UAr[0].y-UAr[1].y)/(UAr[0].x-UAr[1].x);}		   
		    
if (Img.hStepOn)
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) VDraw_P(Rez,0,Img,cNewEdge,psNewEdge,wNewEdge);
	}
		   
		 if (UAr!=NULL) free(UAr);
		   
		 };
		
		if (f)
		 {if (Ar!=NULL) free(Ar);}
		 else
		 {W=Ar;w=end;}
		if (side!=0&&side!=2)
		{Rez=Bridge(UAr,0,n-1,fl_up,Img,hDraw,1);}
    return Rez;
}
//===================================
UandD(tpoint* Ar,uint end,uint lb,uint le,
	 tpoint** ArU,uint *U,tpoint** ArD,uint *D,int fl_up,TImage &Img,BOOL hDraw,tpqs &P)
{uint u=0,d=0,i=0,c;
 double k=0,b=0;
 tpoint *AU=NULL,*AD=NULL;
 char *FName="UandD";

	 if (lb>end||le>end)
	 { PrErr("%s:lb>end||le>end\n",FName);}
	 if (le==lb)
	 {*U=2;*D=0;
		*ArU=NULL;*ArD=NULL;
		return 1;
	 }
	 if ((Ar[lb].x-Ar[le].x)==0)
		{k=NaN;}
		 else
		{ k=(Ar[lb].y-Ar[le].y)/(Ar[lb].x-Ar[le].x);}
	 b=Ar[lb].y-Ar[lb].x*k;
	 P.p=Ar[lb]; P.q=Ar[le];P.s=k;
	 
 	 for (i=lb;i<=le;i++)
	 {
	  	  if ((Ar[i].x*k+b>=Ar[i].y&&k!=NaN)||i==lb||i==le)
			{d++;}
		  else
		  {if (k==NaN)
			 if(Ar[i].x<=Ar[lb].x) d++;			  
			
		  }
		   if ((Ar[i].x*k+b<=Ar[i].y&&k!=NaN)||i==lb||i==le)
			{u++;}
		   else
		   { if (k==NaN)
			   if(Ar[i].x>=Ar[le].x) u++;
		   }
	 }
	 *U=u;*D=d;
	 if (fl_up>=0)
		{ //AU=(tpoint*) calloc(u,sizeof(tpoint));
			AU=new tpoint[u];
		if (AU==NULL)
		 { PrErr("%s :Error not enough memory\n",FName);}
		}
	 if(fl_up<=0)
		{//AD=(tpoint*) calloc(d,sizeof(tpoint));
		  AD= new tpoint[d];
		 if (AD==NULL)
		  { PrErr("%s :Error not enough memory\n",FName);}
		}

	 *ArU=AU;*ArD=AD;
	 d=0;u=0;
	 for (i=lb;i<=le;i++)
	 {
	  	  if (((Ar[i].x*k+b>=Ar[i].y&&k!=NaN)||i==lb||i==le)&&fl_up<=0)
			{AD[d]=Ar[i];
			  d++;}
		  else
		  {if (k==NaN&&fl_up<=0)
			 if(Ar[i].x<=Ar[lb].x) 
				{AD[d]=Ar[i];
				d++;};			  
			
		  }
		   if (((Ar[i].x*k+b<=Ar[i].y&&k!=NaN)||i==lb||i==le)&&fl_up>=0)
			{AU[u]=Ar[i];
			  u++;}
		   else
		   { if (k==NaN&&fl_up>=0)
				 if(Ar[i].x>=Ar[le].x) 
					{AU[u]=Ar[i];
					u++;}					
		   }
	 }
	return 0;
}


//=========================================
int CH(tpoint* Ar,uint u,QUEUE<tpqs> *Q,int fl_up,TImage &Img)

{tpqs *Br;
 tpoint *Ar_lu,*Ar_ld,*Ar_ru,*Ar_rd,*Ar_l,*Ar_r;
 uint lu,ld,ru,rd;
 uint i,l,r;
 static int fl_u=0,fl_d=0;
 int rez_l=0,rez_r=0;
 char *FName="CH";
  BOOL hDraw=false;
  tpqs P;
  
	 Br=Bridge(Ar,0,u-1,fl_up,Img,hDraw);

	 for(i=0;i<u;i++)
	 {
		if ( fabs(Ar[i].x-Br->p.x)<eps&&fabs(Ar[i].y-Br->p.y)<eps)
			{l=i;}//number point p
		if (fabs(Ar[i].x-Br->q.x)<eps&&fabs(Ar[i].y-Br->q.y)<eps)
			{r=i;}//number point q
	 }

	 Q->Push(Br);

     if(Img.cur_step<=Img.cal_step) VDraw_Q(Q,Img,cCurCH,psCurCH,wCurCH);
	  	 
	 rez_l=UandD(Ar,u-1,0,l,&Ar_lu,&lu,&Ar_ld,&ld,fl_up,Img,hDraw,P);
 
	 if (fl_u) return 0;
	 if (fl_d) return 0;
	 if (fl_up==1)
	   {l=lu;Ar_l=Ar_lu;}
	 else
	   {l=ld;Ar_l=Ar_ld;}

	 if (l>=2&&!fl_u&&!rez_l)
	 { if (l==2) fl_u=1;

 if (Img.hStepOn)
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) Img.hDraw=true;
	}
	 if (Img.hDraw)
	 {
	  VDraw_P(&P,0,Img,cDivLine,psDivLine,wDivLine);
	  VDraw_A(Ar_l,l-1,Img,cDivPoint,psDivPoint,wDivPoint);
	  Img.hDraw=false;
	 }
	    CH(Ar_l,l,Q,fl_up,Img);
	    if (fl_u) fl_u=0;
	  }

	 if (Ar_lu!=NULL) free(Ar_lu);
	 if (Ar_ld!=NULL) free(Ar_ld);

	 rez_r=UandD(Ar,u-1,r,u-1,&Ar_ru,&ru,&Ar_rd,&rd,fl_up,Img,hDraw,P);


	 if (fl_up==1)
	   {r=ru;Ar_r=Ar_ru;}
	 else
	   {r=rd;Ar_r=Ar_rd;}
	 if (r>=2&&!fl_d&&!rez_r)
	 { if (r==2) fl_d=1;
 if (Img.hStepOn)
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) Img.hDraw=true;
	}
	 if (Img.hDraw)
	  {
	   VDraw_P(&P,0,Img,cDivLine,psDivLine,wDivLine);
	   VDraw_A(Ar_r,r-1,Img,cDivPoint,psDivPoint,wDivPoint);
	   Img.hDraw=false;
	  }
	   CH(Ar_r,r,Q,fl_up,Img);
	   if (fl_d) fl_d=0;
	 }
	 if (Ar_ru!=NULL) free(Ar_ru);
	 if (Ar_rd!=NULL) free(Ar_rd);

	 return 0;
}
//===================================
int Del_El_Q(QUEUE<tpqs> *Q)
{  tpqs *E;
	 while (!Q->IsEmpty())
	 {
		 E=Q->Pop();
		 if (E!=NULL) delete(E);
	 }
 return 0;
}
//===================================

tpqs* CH_all(tpoint* Ar,uint end,TImage &Img)
{uint u=0,d=0;

 char *FName="CH";
 tpoint* ArU,*ArD;
 QUEUE <tpqs> Q_U,Q_D;
 BOOL hDraw=false;
 tpqs P;

 Img.hDraw=false;
 

 	UandD(Ar,end,0,end,&ArU,&u,&ArD,&d,0,Img,hDraw,P);
 
 if (Img.hStepOn)
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) Img.hDraw=true;
	}

   if (Img.hDraw) 
	{ VDraw_P(&P,0,Img,cDivLine,psDivLine,wDivLine);
	  VDraw_A(ArU,u-1,Img,cDivPoint,psDivPoint,wDivPoint);
	  Img.hDraw=false;
	}
	   
	CH(ArU,u,&Q_U,1,Img);
	if (ArU!=NULL) free(ArU);
	
 if (Img.hStepOn)
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) VDraw_Q(&Q_U,Img,cCH,psCH,wCH);
	}
   
 if (Img.hStepOn)
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) Img.hDraw=true;
	}

    if (Img.hDraw) 
	{ VDraw_P(&P,0,Img,cDivLine,psDivLine,wDivLine);
	  VDraw_A(ArD,d-1,Img,cDivPoint,psDivPoint,wDivPoint);
	  Img.hDraw=false;
	}
 
	CH(ArD,d,&Q_D,-1,Img);
	if (ArD!=NULL) free(ArD);

  if (Img.hStepOn)
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) VDraw_Q(&Q_U,Img,cCH,psCH,wCH);
	}
 	
 if (Img.hStepOn)
 {
  if(!Img.hKnow) Img.all_step++;
   else
	{
	 Img.cur_step++;  
	 if(Img.cur_step==Img.cal_step) 
	 { VDraw_Q(&Q_U,Img,cCH,psCH,wCH);
	   VDraw_Q(&Q_D,Img,cCH,psCH,wCH);
	 }
	}
 }
 else  
 {Img.chp = Q_U.Count()+Q_D.Count();
  VDraw_Q(&Q_U,Img,cCH,psCH,wCH);
  VDraw_Q(&Q_D,Img,cCH,psCH,wCH);
 }
 	
	Del_El_Q(&Q_U);
	Del_El_Q(&Q_D);

 return NULL;
}
//===================================
int Check(tpoint **Ar,uint *a)
{uint i=0,n,j=1;
 QUEUE <tpoint> Q;
 tpoint *A;
 const tpoint *el,*B;
 int fl=0;
  B=*Ar;
  while(i<*a&&j<*a)
  {
    if(fabs(B[i].x-B[j].x)>eps||
       fabs(B[i].y-B[j].y)>eps)
    {
	    Q.Push(&B[i]);		
	    i=j;j++;
    }
    else
    {  
	   j++;
	   fl=1;
    }
  }
  if (j==*a) Q.Push(&B[j-1]);		
  n=Q.Count();
  if (n==0||!fl) return 0;
  //A=(tpoint*) calloc(n,sizeof(tpoint));
  A=new tpoint[n];
  if (A!=NULL)
   { Q.Go_Beg();
     for(i=0;i<n;i++)
     {  if (!Q.IsEnd())
	 {el=Q.Go_Next();
	  A[i].x= el->x;
	  A[i].y= el->y;
	 }
     }
   }
   Q.Go_Beg();
   free(*Ar);
    *Ar=A;
    *a=n;
  return 1;
}
//===================================
MyUpdate(TMyPointVector &p, TImage &Img)
{
 tpoint *Ar;
 tpqs *Br;
 uint r=0,m=0,n=0;

     Img.ClearImage();
	 Img.Update(p);
	 if (Img.hDiagram &&(p.N()>1)) 
	 {
	  Img.hStepOn = false;
	  Ar=ReadMas(p);	 
	  qsort((void *)Ar, all_el, sizeof(tpoint), sort_points);
	  //Check(&Ar,&all_el);
	  CH_all(Ar,all_el-1,Img);
	  Img.hCHP=true;
	 }
}
Соседние файлы в папке Source