Скачиваний:
14
Добавлен:
01.05.2014
Размер:
96.05 Кб
Скачать
// CHRealTimeView.cpp : implementation of the CCHRealTimeView class
//

#include "stdafx.h"
#include "CHRealTime.h"
#include "mainfrm.h"
#include "CHRealTimeDoc.h"
#include "CHRealTimeView.h"
#include "RingGenerate.h"
#include <iostream>
#include <fstream>

#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCHRealTimeView
namespace CHRealTimeSpace
{
 using namespace std;
 using namespace SubsidiaryClasses;
 using namespace RandomTree;
IMPLEMENT_DYNCREATE(CCHRealTimeView, CView)

BEGIN_MESSAGE_MAP(CCHRealTimeView, CView)
	//{{AFX_MSG_MAP(CCHRealTimeView)
	ON_WM_CREATE()
	ON_WM_CANCELMODE()
	ON_WM_LBUTTONDOWN()
	ON_WM_CAPTURECHANGED()
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_TIMER()
	ON_COMMAND(ID_GENERATE, Generate)
	ON_COMMAND(ID_GO, Animate)
	ON_COMMAND(ID_STEP, NextStep)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
	ON_WM_VSCROLL()
	ON_WM_CHAR()
	ON_UPDATE_COMMAND_UI(ID_GENERATE_RECT, OnUpdateGenerateRect)
	ON_UPDATE_COMMAND_UI(ID_GENERATE_CENTER, OnUpdateGenerateCenter)
	ON_COMMAND(ID_GENERATE_CENTER, OnGenerateCenter)
	ON_COMMAND(ID_GENERATE_RECT, OnGenerateRect)
	ON_UPDATE_COMMAND_UI(ID_GENERATE_CENTER_TOOL, OnUpdateGenerateCenterTool)
	ON_UPDATE_COMMAND_UI(ID_GENERATE_RECT_TOOL, OnUpdateGenerateRectTool)
	ON_COMMAND(LEFT_TREE, LeftTree)
	ON_COMMAND(RIGHT_TREE, RightTree)
	ON_COMMAND(UP_TREE, UpTree)
	ON_COMMAND(GO_ROOT, GoRoot)
	ON_COMMAND(ID_GENERATE_VALUE_TOOL, OnGenerateValueTool)
	ON_UPDATE_COMMAND_UI(ID_GENERATE_VALUE_TOOL, OnUpdateGenerateValueTool)
	ON_COMMAND(ID_PRIORITY, OnPriority)
	ON_UPDATE_COMMAND_UI(ID_PRIORITY, OnUpdatePriority)
	ON_COMMAND(ID_SITUATION, OnSituation)
	ON_UPDATE_COMMAND_UI(ID_SITUATION, OnUpdateSituation)
	ON_UPDATE_COMMAND_UI(ID_GO, OnUpdateGo)
	ON_COMMAND(ID_GENERATE_VALUE, OnGenerateValue)
	ON_UPDATE_COMMAND_UI(ID_GENERATE_VALUE, OnUpdateGenerateValue)
	ON_COMMAND(ID_MENUITEM32806, OnCHHelp)
	ON_UPDATE_COMMAND_UI(ID_STEP, OnUpdateStep)
	ON_UPDATE_COMMAND_UI(LEFT_TREE, OnUpdateTree)
	ON_COMMAND(ID__BMP, SaveToBmp)
	ON_COMMAND(ID_PAUSE, OnPause)
	ON_COMMAND(ID_GENERATE_CENTER_TOOL, OnGenerateCenter)
	ON_COMMAND(ID_GENERATE_RECT_TOOL, OnGenerateRect)
	ON_UPDATE_COMMAND_UI(RIGHT_TREE, OnUpdateTree)
	ON_UPDATE_COMMAND_UI(UP_TREE, OnUpdateTree)
	ON_UPDATE_COMMAND_UI(GO_ROOT, OnUpdateTree)
	ON_UPDATE_COMMAND_UI(ID_PAUSE, OnUpdatePause)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCHRealTimeView construction/destruction
#define ID_GENERATING 1
#define ID_OPENING	2
#define ID_SAVE  3
double Pi = 3.1415926535897932384626433832795;
bool m_bPriority; // выводить ли приоритеты

vector<int> situation;

int DefaultClientPointsWidth=278;
int DefaultClientPointsHeight=245;

RandomizeNode<TPoint> *l;
RandomizeNode<TPoint> *r;

COLORREF defaultPalleteColor=0;
COLORREF defaultTextColor=0;


	CPen bluep1(PS_SOLID,1,	0x00323200);
	CBrush blueb1(			0x00323200);		
	CPen bluep2(PS_SOLID,1,	0x00963200);
	CBrush blueb2(			0x00963200);
	CPen bluep3(PS_SOLID,1,	0x00B86400);
	CBrush blueb3(			0x00B86400);
	CPen bluep4(PS_SOLID,1,	0x00F0B864);
	CBrush blueb4(			0x00F0B864);
	CPen bluep5(PS_SOLID,1,	0x00F0F0BB);
	CBrush blueb5(			0x00F0F0BB);

	CPen redp1(PS_SOLID,1,	0x00000064);
	CBrush redb1(			0x00000064);		
	CPen redp2(PS_SOLID,1,	0x000000B8);
	CBrush redb2(			0x000000B8);
	CPen redp3(PS_SOLID,1,	0x000000F0);
	CBrush redb3(			0x000000F0);
	CPen redp4(PS_SOLID,1,	0x006464F0);
	CBrush redb4(			0x006464F0);
	CPen redp5(PS_SOLID,1,	0x00DBDBF0);
	CBrush redb5(			0x00DBDBF0);

	CPen greenp1(PS_SOLID,1,0x00006400);
	CBrush greenb1(			0x00006400);		
	CPen greenp2(PS_SOLID,1,0x0000B800);
	CBrush greenb2(			0x0000B800);
	CPen greenp3(PS_SOLID,1,0x0000F000);
	CBrush greenb3(			0x0000F000);
	CPen greenp4(PS_SOLID,1,0x0064F064);
	CBrush greenb4(			0x0064F064);
	CPen greenp5(PS_SOLID,1,0x00DBF0DB);
	CBrush greenb5(			0x00DBF0DB);

	CPen greentree(PS_SOLID,1,0x0064A032);

	CPoint InputPoint;

	vector<int> Deleted;

/** Конструктор*/
CCHRealTimeView::CCHRealTimeView():Animation(false),
								   Opening(false),
								   distribution(0),
								   generating(false),
								   Step(0),
 							   	   tree(NULL),
								   m_bRectGenerating(false),
								   m_bCenterGenerating(false),
								   m_bValueGenerating(false),
								   m_bSituation(true),
								   m_bSituationEnabled(true),
								   CurrNode(NULL),
								   Mxx(20),
								   Myy(20),
								   m_iNumGenPoints(0),
								   m_iMinR(20),
								   m_iMaxR(120),
								   m_iWid(10),
								   m_iStep(2),
								   m_iNumPoints(10),
			/*ref*/				   m_bPauseIsPress(false)
{
	// TODO: add construction code here
    m_bPriority = false;
	situation.clear();
	Points.clear();
	CTime t;	
	srand((unsigned)t.GetTime() );
}

/** Деструктор */
CCHRealTimeView::~CCHRealTimeView()
{
	// очистка вектора
	for(vector<StepStruct *>::iterator i = stepstruct.begin(); i != stepstruct.end(); i++) 
		if((*i)) 
			delete (*i);
	stepstruct.clear();	// очистка структуры
	RST.clear();
	DeleteTree(tree);	// удаление дерева
	for(int j=0;j<9;j++)
		if(bmp[j]){
			delete bmp[j];
			bmp[j] = NULL;
		};
}

// создать дерево
TTree *MakeTree(TTree * parent, RandomizeNode<TPoint> *root)
{
	if(!root)
		return NULL;

	TTree *node = new TTree;
    
	if(root->getVal())
	{
		node->val = new TPoint(root->getVal()->getID(),root->getVal()->getX(),root->getVal()->getY());
		node->priority(root->priority());
	}
	else
	{
		node->val = NULL;
		node->priority(-1);
	};

	node->parent=parent;
	node->lchild=MakeTree(node,root->lchild());
	node->rchild=MakeTree(node,root->rchild());
	return node;
}

// удалить дерево
void DeleteTree(TTree * parent)
{
	if(parent->lchild)
		DeleteTree(parent->lchild);
	if(parent->rchild)
		DeleteTree(parent->rchild);
	delete parent;
	delete parent->val;
}

/** установить указатели на следующие элементы*/
TTree * MakeNext(TTree * treeTemp, TTree * parent, TTree *kor)
{
	TTree *tmp;
	if(!treeTemp) //ИЗМЕНИЛИ АЛГОРИТМ
	{	parent->next=parent;
		return parent; 
	}
	if(treeTemp->lchild)
		tmp=MakeNext(treeTemp->lchild,treeTemp,kor);
	if(treeTemp->rchild)
	{
		treeTemp->next = MakeNext(treeTemp->rchild,parent,kor);
		if (treeTemp->lchild)
		{
			while (treeTemp->lchild)
			{
				treeTemp = treeTemp->lchild;
				tmp = treeTemp;
			}
		}
		else
			tmp = treeTemp;
	}
	else 
	{
		if (treeTemp == kor->maximum())
			treeTemp->next = kor->minimum();
		else
			treeTemp->next = parent;
		if (treeTemp->lchild)
		{
			while (treeTemp->lchild)
			{
				treeTemp = treeTemp->lchild;
				tmp = treeTemp;
			}
		}
		else
			tmp = treeTemp;
	}
	return tmp;	

}


/** Установить указатели на предыдущие элементы*/
TTree *MakePrev(TTree *treeTemp)
{
	TTree *tmp;
	tmp=treeTemp->minimum();
	tmp->prev=treeTemp;
	do
	{
		tmp->next->prev=tmp;
		tmp=tmp->next;
	} while (tmp!=treeTemp->maximum()) ;
	return tmp;
}

/** Нарисовать линию */
void Line(CDC *dc,int x1,int y1,int x2,int y2,int r,bool Lighted=false)
{
	double k=(double)(abs(x1-x2))/(double)(y2-y1);
	int dy=r/(sqrt(k*k+1))+1;
	int dx=dy*k+1;

	if(!Lighted)
		dc->SelectObject(&greentree);
	else
		dc->SelectObject(&redp4);
	if(x1>x2) {		//налево
		dc->MoveTo(x1-dx,y1+dy);
		dc->LineTo(x2+dx,y2-dy);
	}
	else {			//направо
		dc->MoveTo(x1+dx,y1+dy);
		dc->LineTo(x2-dx,y2-dy);
	}
}


/** Нарисовать круг*/
void Circle(CDC *dc,int val,double prior, int x,int y,int r,bool Lighted=false,bool del=false)
{
	dc->SelectStockObject(WHITE_BRUSH);
	if(!Lighted)
		dc->SelectObject(&greentree);
	else
		dc->SelectObject(&redp4);
	
	dc->Ellipse(x-r,y-r,x+r,y+r);
	
	if(del) {
		for(int i=0;i<Deleted.size();i++)
			if(val==Deleted[i]) {
				dc->SelectObject(&redp2);
				dc->MoveTo(x+r,y-r-3);
				dc->LineTo(x-r,y+r+3);
				dc->MoveTo(x+r,y+r+3);
				dc->LineTo(x-r,y-r-3);
			}
	}
	char buffer[10];
	_itoa(val,buffer,10);
	dc->SetBkMode(TRANSPARENT);
	if (m_bPriority)
   		sprintf(buffer,"%d(%.3f)",val,prior);
	else
   		sprintf(buffer,"%d",val);
	dc->DrawText(buffer,-1,CRect(x-r-100,y-r-100,x+r+100,y+r+100),DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}

// изображение точки (красной, зеленой или синей)
void Point(CDC *dc, CPoint pnt,int State)
{
	int rad=3;
	// синей
	if(State==0) {

		dc->SelectObject(&bluep1);
		dc->SelectObject(&blueb1);
		dc->Ellipse(pnt.x-rad,pnt.y-rad,pnt.x+rad,pnt.y+rad);
		dc->SelectObject(&bluep2);
		dc->SelectObject(&blueb2);
		dc->Ellipse(pnt.x-rad,pnt.y-rad,pnt.x+rad-1,pnt.y+rad-1);
		dc->SelectObject(&bluep3);
		dc->SelectObject(&blueb3);
		dc->Ellipse(pnt.x-rad+1,pnt.y-rad+1,pnt.x+rad-2,pnt.y+rad-2);
		dc->SelectObject(&bluep4);
		dc->SelectObject(&blueb4);
		dc->Ellipse(pnt.x-rad+1,pnt.y-rad+1,pnt.x+rad-3,pnt.y+rad-3);
		dc->SelectObject(&bluep5);
		dc->SelectObject(&blueb5);
		dc->Ellipse(pnt.x-rad+2,pnt.y-rad+2,pnt.x+rad-4,pnt.y+rad-4);
	 }
	// красной
	if(State==1) {
		dc->SelectObject(&redp1);
		dc->SelectObject(&redb1);
		dc->Ellipse(pnt.x-rad,pnt.y-rad,pnt.x+rad,pnt.y+rad);
		dc->SelectObject(&redp2);
		dc->SelectObject(&redb2);
		dc->Ellipse(pnt.x-rad,pnt.y-rad,pnt.x+rad-1,pnt.y+rad-1);
		dc->SelectObject(&redp3);
		dc->SelectObject(&redb3);
		dc->Ellipse(pnt.x-rad+1,pnt.y-rad+1,pnt.x+rad-2,pnt.y+rad-2);
		dc->SelectObject(&redp4);
		dc->SelectObject(&redb4);
		dc->Ellipse(pnt.x-rad+1,pnt.y-rad+1,pnt.x+rad-3,pnt.y+rad-3);
		dc->SelectObject(&redp5);
		dc->SelectObject(&redb5);
		dc->Ellipse(pnt.x-rad+2,pnt.y-rad+2,pnt.x+rad-4,pnt.y+rad-4);
	}
	// зеленой
	if(State==2) {
		dc->SelectObject(&greenp1);
		dc->SelectObject(&greenb1);
		dc->Ellipse(pnt.x-rad,pnt.y-rad,pnt.x+rad,pnt.y+rad);
		dc->SelectObject(&greenp2);
		dc->SelectObject(&greenb2);
		dc->Ellipse(pnt.x-rad,pnt.y-rad,pnt.x+rad-1,pnt.y+rad-1);
		dc->SelectObject(&greenp3);
		dc->SelectObject(&greenb3);
		dc->Ellipse(pnt.x-rad+1,pnt.y-rad+1,pnt.x+rad-2,pnt.y+rad-2);
		dc->SelectObject(&greenp4);
		dc->SelectObject(&greenb4);
		dc->Ellipse(pnt.x-rad+1,pnt.y-rad+1,pnt.x+rad-3,pnt.y+rad-3);
		dc->SelectObject(&greenp5);
		dc->SelectObject(&greenb5);
		dc->Ellipse(pnt.x-rad+2,pnt.y-rad+2,pnt.x+rad-4,pnt.y+rad-4);
	}
}

void PLine(CDC *dc,int x1,int y1,int x2,int y2,int r,int Lighted=0)
{
	int dy=0;
	int dx=0;

	if(Lighted==0)
		dc->SelectObject(&bluep4);
	if(Lighted==1)
		dc->SelectObject(&redp4);
	if(Lighted==2)
		dc->SelectObject(&greenp4);
	if(Lighted==4)
		dc->SelectObject(&redp2);
	
	if(x1>x2) {		//налево
		dc->MoveTo(x1-dx,y1+dy);
		dc->LineTo(x2+dx,y2-dy);
	
	}
	else {			//направо
		dc->MoveTo(x1+dx,y1+dy);
		dc->LineTo(x2-dx,y2-dy);
	}
}

/** Изобразить дерево*/
void ShowTree(RandomizeNode<TPoint> *RN,CDC *dc,int LeftBorder,int RightBorder,int Level,double Sx,double Sy,long flag)
{
	
	int Center=(LeftBorder+RightBorder)/2;
	int y=(Level*40+20)*Sy;
	int	y2=((Level+1)*40+20)*Sy;
	int rad=8;
	if (!Level) 
		if (flag!=0)
		{	Line(dc,Center,Sy,Center,y,rad);
		}
	Circle(dc,RN->getVal()->getID(),RN->priority(),Center,y,rad);
	RandomizeNode<TPoint> *l=RN->lchild();
	RandomizeNode<TPoint> *r=RN->rchild();
	if(l) {
		Line(dc,Center,y,(LeftBorder+Center)/2,y2,rad);
		ShowTree(l,dc,LeftBorder,Center,Level+1,Sx,Sy,1);
	}
	if(r) {
		Line(dc,Center,y,(RightBorder+Center)/2,y2,rad);
		ShowTree(r,dc,Center,RightBorder,Level+1,Sx,Sy,1);
	}
}

/** Изобразить дерево*/
void ShowTree(TTree *RN,TTree *selroot,CDC *dc,int LeftBorder,int RightBorder,int Level,double Sx,double Sy,bool Lighted=false,bool Del=false)
{
	int Center=(LeftBorder+RightBorder)/2;
	int y=(Level*40+20)*Sy;
	int	y2=((Level+1)*40+20)*Sy;
	int rad=8;
	if(RN==selroot)
		Lighted=true;
	Circle(dc,RN->getVal()->getID(),RN->priority(),Center,y,rad,Lighted,Del/*m_bPriority*/);
	TTree *l=RN->lchild;
	TTree *r=RN->rchild;
	if(l) {
		Line(dc,Center,y,(LeftBorder+Center)/2,y2,rad,Lighted);
		ShowTree(l,selroot,dc,LeftBorder,Center,Level+1,Sx,Sy,Lighted,Del);
	}
	if(r) {
		Line(dc,Center,y,(RightBorder+Center)/2,y2,rad,Lighted);
		ShowTree(r,selroot,dc,Center,RightBorder,Level+1,Sx,Sy,Lighted,Del);
	}
}

HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal ) 
{
	BITMAP			bm;
	BITMAPINFOHEADER	bi;
	LPBITMAPINFOHEADER 	lpbi;
	DWORD			dwLen;
	HANDLE			hDIB;
	HANDLE			handle;
	HDC 			hDC;
	HPALETTE		hPal;


	ASSERT( bitmap.GetSafeHandle() );

	// The function has no arg for bitfields
	if( dwCompression == BI_BITFIELDS )
		return NULL;

	// If a palette has not been supplied use defaul palette
	hPal = (HPALETTE) pPal->GetSafeHandle();
	if (hPal==NULL)
		hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);

	// Get bitmap information
	bitmap.GetBitmap(&bm);

	// Initialize the bitmapinfoheader
	bi.biSize		= sizeof(BITMAPINFOHEADER);
	bi.biWidth		= bm.bmWidth;
	bi.biHeight 		= bm.bmHeight;
	bi.biPlanes 		= bm.bmPlanes;
	bi.biBitCount		= bm.bmBitsPixel;
	bi.biCompression	= dwCompression;
	bi.biSizeImage		= 0;
	bi.biXPelsPerMeter	= 0;
	bi.biYPelsPerMeter	= 0;
	bi.biClrUsed		= 0;
	bi.biClrImportant	= 0;

	// Compute the size of the  infoheader and the color table
	int nColors = (1 << bi.biBitCount);
	if( nColors > 256 ) 
		nColors = 0;
	dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);

	// We need a device context to get the DIB from
	hDC = GetDC(NULL);
	hPal = SelectPalette(hDC,hPal,FALSE);
	RealizePalette(hDC);

	// Allocate enough memory to hold bitmapinfoheader and color table
	hDIB = GlobalAlloc(GMEM_FIXED,dwLen);

	if (!hDIB){
		SelectPalette(hDC,hPal,FALSE);
		ReleaseDC(NULL,hDC);
		return NULL;
	}

	lpbi = (LPBITMAPINFOHEADER)hDIB;

	*lpbi = bi;

	// Call GetDIBits with a NULL lpBits param, so the device driver 
	// will calculate the biSizeImage field 
	GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
			(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);

	bi = *lpbi;

	// If the driver did not fill in the biSizeImage field, then compute it
	// Each scan line of the image is aligned on a DWORD (32bit) boundary
	if (bi.biSizeImage == 0){
		bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) 
						* bi.biHeight;

		// If a compression scheme is used the result may infact be larger
		// Increase the size to account for this.
		if (dwCompression != BI_RGB)
			bi.biSizeImage = (bi.biSizeImage * 3) / 2;
	}

	// Realloc the buffer so that it can hold all the bits
	dwLen += bi.biSizeImage;
	if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
		hDIB = handle;
	else{
		GlobalFree(hDIB);

		// Reselect the original palette
		SelectPalette(hDC,hPal,FALSE);
		ReleaseDC(NULL,hDC);
		return NULL;
	}

	// Get the bitmap bits
	lpbi = (LPBITMAPINFOHEADER)hDIB;

	// FINALLY get the DIB
	BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
				0L,				// Start scan line
				(DWORD)bi.biHeight,		// # of scan lines
				(LPBYTE)lpbi 			// address for bitmap bits
				+ (bi.biSize + nColors * sizeof(RGBQUAD)),
				(LPBITMAPINFO)lpbi,		// address of bitmapinfo
				(DWORD)DIB_RGB_COLORS);		// Use RGB for color table

	if( !bGotBits )
	{
		GlobalFree(hDIB);
		
		SelectPalette(hDC,hPal,FALSE);
		ReleaseDC(NULL,hDC);
		return NULL;
	}

	SelectPalette(hDC,hPal,FALSE);
	ReleaseDC(NULL,hDC);
	return hDIB;
}


BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB)
{
	BITMAPFILEHEADER	hdr;
	LPBITMAPINFOHEADER	lpbi;

	if (!hDIB)
		return FALSE;

	CFile file;
	if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
		return FALSE;

	lpbi = (LPBITMAPINFOHEADER)hDIB;

	int nColors = 1 << lpbi->biBitCount;
	if( nColors > 256 ) 
		nColors = 0; 
	// Fill in the fields of the file header 
	hdr.bfType		= ((WORD) ('M' << 8) | 'B');	// is always "BM"
	hdr.bfSize		= GlobalSize (hDIB) + sizeof( hdr );
	hdr.bfReserved1 	= 0;
	hdr.bfReserved2 	= 0;
	hdr.bfOffBits		= (DWORD) (sizeof( hdr ) + lpbi->biSize +
						nColors * sizeof(RGBQUAD));

	// Write the file header 
	file.Write( &hdr, sizeof(hdr) );

	// Write the DIB header and the bits 
	file.Write( lpbi, GlobalSize(hDIB) );

	return TRUE;
}

BOOL WriteWindowToDIB( LPTSTR szFile, CRect	rect, CWnd *pWnd)
{
	CBitmap 	bitmap;
	CWindowDC	dc(pWnd);
	CDC 		memDC;
	;

	memDC.CreateCompatibleDC(&dc); 

	bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
	
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
	memDC.BitBlt(0,0, rect.Width(),rect.Height(), &dc, rect.left+2, rect.top+2, SRCCOPY); 

	// Create logical palette if device support a palette
	CPalette pal;
	if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
	{
		UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
		LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
		pLP->palVersion = 0x300;

		pLP->palNumEntries = 
			GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );

		// Create the palette
		pal.CreatePalette( pLP );

		delete[] pLP;
	}

	memDC.SelectObject(pOldBitmap);

	// Convert the bitmap to a DIB
	HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal );

	if( hDIB == NULL )
		return FALSE;

	// Write it to file
	WriteDIB( szFile, hDIB );

	// Free the memory allocated by DDBToDIB for the DIB
	GlobalFree( hDIB );
	return TRUE;
}

CPoint Norm(int Mx, int My, double sigmaX,double sigmaY)
{
	CPoint p;
	double N;
	double x,y;
	x=(double) rand()/((double) RAND_MAX+1.0);
	y=(double)rand()/((double)RAND_MAX+1.0);
	N=sqrt(-2.0*log(x))*cos(2.0*Pi*y);
	N*=sigmaX;
	p.x=Mx+N;

	x=(double) rand()/((double) RAND_MAX+1.0);
	y=(double)rand()/((double)RAND_MAX+1.0);
	N=sqrt(-2.0*log(x))*cos(2.0*Pi*y);
	N*=sigmaY;
	p.y=My+N;
	return p;
}

CPoint Even(int Mx,int My, double sigmaX,double sigmaY)
{
	CPoint p;
	double N;
	N=(double) rand()*sigmaX/((double) RAND_MAX+1.0);
	p.x=Mx-sigmaX+2*N;
	N=(double) rand()*sigmaY/((double) RAND_MAX+1.0);
	p.y=My-sigmaY+2*N;
	return p;
}


/** Опорная ли точка */
bool IsAbutment(CPoint v1,CPoint v,CPoint v2,CPoint p)
{
	if (v.x != p.x)
	{
		double K = (double)(((double)v.y - (double)p.y)/((double)v.x - (double)p.x));
		double B = (double)((double)p.y - K*(double)p.x);

		if (((p.y == v.y) && (p.y == v2.y)) && (((p.x > v.x) && (p.x > v2.x)) ||((p.x < v.x) && (p.x < v2.x))))
			if (abs(p.x - v.x) > abs(p.x - v2.x))
				return false;
		else
		if (((p.x == v.x) && (p.x == v2.x)) && (((p.y > v.y) && (p.y > v2.y)) ||((p.y < v.y) && (p.y < v2.y))))
			if (abs(p.y - v.y) > abs(p.y - v2.y))
				return false;
		else
		if (((p.y == v.y) && (p.y == v1.y)) && (((p.x > v.x) && (p.x > v1.x)) ||((p.x < v.x) && (p.x < v1.x))))
			if (abs(p.x - v.x) > abs(p.x - v1.x))
				return false;
		else
		if (((p.x == v.x) && (p.x == v1.x)) && (((p.y > v.y) && (p.y > v1.y)) ||((p.y < v.y) && (p.y < v1.y))))
			if (abs(p.y - v.y) > abs(p.y - v1.y))
				return false;

		return (v1.y >= (K*v1.x + B)) && (v2.y >= (K*v2.x + B)) || (v1.y <= (K*v1.x + B)) && (v2.y <= (K*v2.x + B));
	}
	else
	{
		if (((p.y == v.y) && (p.y == v2.y)) && (((p.x > v.x) && (p.x > v2.x)) ||((p.x < v.x) && (p.x < v2.x))))
			if (abs(p.x - v.x) > abs(p.x - v2.x))
				return false;
		else
		if (((p.x == v.x) && (p.x == v2.x)) && (((p.y > v.y) && (p.y > v2.y)) ||((p.y < v.y) && (p.y < v2.y))))
			if (abs(p.y - v.y) > abs(p.y - v2.y))
				return false;
		else
		if (((p.y == v.y) && (p.y == v1.y)) && (((p.x > v.x) && (p.x > v1.x)) ||((p.x < v.x) && (p.x < v1.x))))
			if (abs(p.x - v.x) > abs(p.x - v1.x))
				return false;
		else
		if (((p.x == v.x) && (p.x == v1.x)) && (((p.y > v.y) && (p.y > v1.y)) ||((p.y < v.y) && (p.y < v1.y))))
			if (abs(p.y - v.y) > abs(p.y - v1.y))
				return false;
		
		return (v1.x >= v.x && v2.x >= v.x) || (v1.x <= v.x && v2.x <= v.x);
	}
}

/** Выпуклая ли точка */
bool IsConvex(CPoint v1,CPoint v,CPoint v2,CPoint p)
{
	
	int t1=v1.x*v.y+v1.y*v2.x+v.x*v2.y-v.y*v2.x-v.x*v1.y-v1.x*v2.y;
	int t2=v1.x*p.y+v1.y*v.x+p.x*v.y-p.y*v.x-p.x*v1.y-v1.x*v.y;

	if (((p.y == v.y) && (p.y == v2.y)) && (((p.x > v.x) && (p.x > v2.x)) ||((p.x < v.x) && (p.x < v2.x))))
		if (abs(p.x - v.x) > abs(p.x - v2.x))
			return false;
	else
	if (((p.x == v.x) && (p.x == v2.x)) && (((p.y > v.y) && (p.y > v2.y)) ||((p.y < v.y) && (p.y < v2.y))))
		if (abs(p.y - v.y) > abs(p.y - v2.y))
			return false;
	else
	if (((p.y == v.y) && (p.y == v1.y)) && (((p.x > v.x) && (p.x > v1.x)) ||((p.x < v.x) && (p.x < v1.x))))
		if (abs(p.x - v.x) > abs(p.x - v1.x))
			return false;
	else
	if (((p.x == v.x) && (p.x == v1.x)) && (((p.y > v.y) && (p.y > v1.y)) ||((p.y < v.y) && (p.y < v1.y))))
		if (abs(p.y - v.y) > abs(p.y - v1.y))
			return false;
	return (t1>=0 && t2>=0) || (t1<=0 && t2<=0);

}

/** Выпуклый ли угол */
bool IsConvexAngle(CPoint m,CPoint M,CPoint p)
{
	return (m.x-p.x)*(M.y-p.y)-(m.y-p.y)*(M.x-p.x)<0;
}




BOOL CCHRealTimeView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CCHRealTimeView drawing

void CCHRealTimeView::OnDraw(CDC* pDC)
{
	CCHRealTimeDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CCHRealTimeView printing

BOOL CCHRealTimeView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CCHRealTimeView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CCHRealTimeView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CCHRealTimeView diagnostics

#ifdef _DEBUG
void CCHRealTimeView::AssertValid() const
{
	CView::AssertValid();
}

void CCHRealTimeView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CCHRealTimeDoc* CCHRealTimeView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCHRealTimeDoc)));
	return (CCHRealTimeDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CCHRealTimeView message handlers

int CCHRealTimeView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	CMainFrame *pFrame = (CMainFrame *) AfxGetApp()->m_pMainWnd;
	m_ToolBar=&pFrame->m_wndToolBar;

	
	
	m_ToolBar->GetToolBarCtrl().HideButton(ID_STEP);
	int i;
	for(i=0;i<9;i++)
		bmp[i]=new CBitmap;
	
	bmp[0]->LoadBitmap(IDB_BITMAP1);
	bmp[1]->LoadBitmap(IDB_BITMAP2);
	bmp[2]->LoadBitmap(IDB_BITMAP3);
	bmp[3]->LoadBitmap(IDB_BITMAP4);
	bmp[4]->LoadBitmap(IDB_BITMAP5);
	bmp[5]->LoadBitmap(IDB_BITMAP6);
	bmp[6]->LoadBitmap(IDB_BITMAP7);
	bmp[7]->LoadBitmap(IDB_BITMAP8);

	return 0;	
	
}


void CCHRealTimeView::OnCancelMode() 
{
	CView::OnCancelMode();
	
	// TODO: Add your message handler code here

	
}

void CCHRealTimeView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(ClientPoints.PtInRect(point)) 
	{
		if(generating)
		{	
			m_bRectGenerating = false;
			m_bCenterGenerating = false;
			KillTimer(ID_GENERATING);
			generating=false;
		}
		double ScaleX=(double)ClientPoints.Width()/(double)DefaultClientPointsWidth;
		double ScaleY=(double)ClientPoints.Height()/(double)DefaultClientPointsHeight;
		point.x-=ClientPoints.left;
		point.y-=ClientPoints.top;
		point.x/=ScaleX;
		point.y/=ScaleY;
		if (RST.size() >= 2)
		{
			if (PointSurLine(point) != 1)
				InsertNewPoint(point);
		}
		else
			InsertNewPoint(point);
	}
	CView::OnLButtonDown(nFlags, point);
}

void CCHRealTimeView::OnCaptureChanged(CWnd *pWnd) 
{
	// TODO: Add your message handler code here
	
	CView::OnCaptureChanged(pWnd);
}

/** Перерисовка экрана (вызывается принудительно)*/
void CCHRealTimeView::OnPaint2() 
{
	CClientDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here

	CBrush grayb((COLORREF)0x00C0C0C0);
	CPen   dk_grayp(PS_SOLID,2,(COLORREF)0x00606060);
	CPen   lt_grayp(PS_SOLID,2,(COLORREF)0x00E0E0E0);
	CRgn border,treeBorder,points,bmpBorder;
	if (m_bSituation)
		bmpBorder.CreateRectRgnIndirect(ClientBmp);
	border.CreateRectRgn(0,0,ClientX,ClientY);
	treeBorder.CreateRectRgnIndirect(&ClientTree);
	points.CreateRectRgnIndirect(&ClientPoints);
	border.CombineRgn(&border,&treeBorder,RGN_XOR);
	border.CombineRgn(&border,&points,RGN_XOR);
	if (m_bSituation)
		border.CombineRgn(&border,&bmpBorder,RGN_XOR);

	dc.FillRgn(&border,&grayb);
	dc.SelectObject(dk_grayp);
	dc.MoveTo(ClientTree.left-1,ClientTree.bottom+1);
	dc.LineTo(ClientTree.left-1,ClientTree.top-1);
	if (m_bSituation)
	{
		dc.LineTo(ClientTree.right+1-ClientBmp.Width(),ClientTree.top-1);
		dc.SelectObject(lt_grayp);	
		dc.LineTo(ClientTree.right+1-ClientBmp.Width(),ClientTree.top-1+ClientBmp.Height());
		dc.SelectObject(dk_grayp);
		dc.LineTo(ClientTree.right+1,ClientTree.top-1+ClientBmp.Height());
	}
	else
		dc.LineTo(ClientTree.right+1,ClientTree.top-1);

	dc.SelectObject(lt_grayp);	
	dc.LineTo(ClientTree.right+1,ClientTree.bottom+1);
	dc.LineTo(ClientTree.left-1,ClientTree.bottom+1);


	dc.SelectObject(dk_grayp);
	dc.MoveTo(ClientPoints.left-1,ClientPoints.bottom+1);
	dc.LineTo(ClientPoints.left-1,ClientPoints.top-1);
	dc.LineTo(ClientPoints.right+1,ClientPoints.top-1);
	dc.MoveTo(ClientPoints.right+1,ClientPoints.top-1);
	dc.SelectObject(lt_grayp);	
	dc.LineTo(ClientPoints.right+1,ClientPoints.bottom+1);
	dc.LineTo(ClientPoints.left-1,ClientPoints.bottom+1);

	if(Animation) 
	{
		Step--;
		NextStep();
	}
	else {
		DrawPoints();
		DrawTree();
	}

	// Do not call CView::OnPaint() for painting messages
}

/** Перерисовка экрана (вызывается автоматически)*/

void CCHRealTimeView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	if (m_bIsFirstExecute)
	{
		AutoLoad();
	}
	m_bIsFirstExecute = false;
	CBrush grayb((COLORREF)0x00C0C0C0);
	CPen   dk_grayp(PS_SOLID,2,(COLORREF)0x00606060);
	CPen   lt_grayp(PS_SOLID,2,(COLORREF)0x00E0E0E0);
	CRgn border,treeBorder,points,bmpBorder;
	if (m_bSituation)
		bmpBorder.CreateRectRgnIndirect(ClientBmp);
	border.CreateRectRgn(0,0,ClientX,ClientY);
	treeBorder.CreateRectRgnIndirect(&ClientTree);
	points.CreateRectRgnIndirect(&ClientPoints);
	border.CombineRgn(&border,&treeBorder,RGN_XOR);
	border.CombineRgn(&border,&points,RGN_XOR);
	if (m_bSituation)
		border.CombineRgn(&border,&bmpBorder,RGN_XOR);

	dc.FillRgn(&border,&grayb);
	dc.SelectObject(dk_grayp);
	dc.MoveTo(ClientTree.left-1,ClientTree.bottom+1);
	dc.LineTo(ClientTree.left-1,ClientTree.top-1);
	if (m_bSituation)
	{
		dc.LineTo(ClientTree.right+1-ClientBmp.Width(),ClientTree.top-1);
		dc.SelectObject(lt_grayp);	
		dc.LineTo(ClientTree.right+1-ClientBmp.Width(),ClientTree.top-1+ClientBmp.Height());
		dc.SelectObject(dk_grayp);
		dc.LineTo(ClientTree.right+1,ClientTree.top-1+ClientBmp.Height());
	}
	else
		dc.LineTo(ClientTree.right+1,ClientTree.top-1);

	dc.SelectObject(lt_grayp);	
	dc.LineTo(ClientTree.right+1,ClientTree.bottom+1);
	dc.LineTo(ClientTree.left-1,ClientTree.bottom+1);

	dc.SelectObject(dk_grayp);
	dc.MoveTo(ClientPoints.left-1,ClientPoints.bottom+1);
	dc.LineTo(ClientPoints.left-1,ClientPoints.top-1);
	dc.LineTo(ClientPoints.right+1,ClientPoints.top-1);

	dc.MoveTo(ClientPoints.right+1,ClientPoints.top-1);
	dc.SelectObject(lt_grayp);	
	dc.LineTo(ClientPoints.right+1,ClientPoints.bottom+1);
	dc.LineTo(ClientPoints.left-1,ClientPoints.bottom+1);

	if(Animation) {
		Step--;
		NextStep();
		
	}
	else {
		DrawPoints();
		DrawTree();
	}

	// Do not call CView::OnPaint() for painting messages
}

/** Обработка изменения размера окна */
void CCHRealTimeView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	ClientX=cx;
	ClientY=cy;
	ClientTree.left=ClientX/2+10;
	ClientTree.top=10;
	ClientTree.right=ClientX-10;
	ClientTree.bottom=ClientY-10;/*120*/

	
	ClientPoints.left=10;
	ClientPoints.top=10;
	ClientPoints.right=ClientX/2-10;
	ClientPoints.bottom=ClientY-10;
	
	ClientBmp.left=ClientTree.right-90;
	ClientBmp.top=ClientTree.top;
	ClientBmp.right=ClientTree.right;
	ClientBmp.bottom=ClientTree.top+70;	
}


/** Обработчик таймера */
void CCHRealTimeView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent==ID_GENERATING)
	{
		if (m_bValueGenerating)
			m_iNumGenPoints++;
		CPoint p_tmp;
		p_tmp = Rovn(ClientPoints.right/2,ClientPoints.bottom/2,ClientPoints.right/8,ClientPoints.bottom/8);

		if ((m_iNumGenPoints >= m_iNumPoints) && m_bValueGenerating)
		{	KillTimer(ID_GENERATING);
			m_bCenterGenerating = false;		// Происходит генерация с центрическим распределением
			m_bRectGenerating = false;			// Происходит генерация с распределением в прямоугольнике
			m_bValueGenerating = false;		// Происходит генерация с распределением в круге
			generating = false;
			m_iNumGenPoints = 0;
		}	
		if (RST.size()>=2)
		{
			bool isInsert = false;
			for (int i = 0; i < 5; i++)
			{
				if (PointSurLine(p_tmp) != 1)
				{
					InsertNewPoint(p_tmp);
					isInsert = true;
					break;
				}
				else
					if (i != 4)
						p_tmp = Rovn(ClientPoints.right/2,ClientPoints.bottom/2,ClientPoints.right/8,ClientPoints.bottom/8);
			}
			if (!isInsert)
				if (m_bValueGenerating)
					m_iNumGenPoints--;
		}
		else
			InsertNewPoint(p_tmp);

	}
	if(nIDEvent==ID_OPENING) {
		if(OpenNum>=OpenPoints.size())
			KillTimer(ID_OPENING);
		else {
			if(Animation)
				KillTimer(ID_OPENING);
			InsertNewPoint(OpenPoints[OpenNum]);
			OpenNum++;
		}
	}	
	if (nIDEvent == ID_SAVE)
	{
		this->KillTimer(nIDEvent);
		SaveToBmpFile(MyName);
	}

	CView::OnTimer(nIDEvent);
}


/** Режим пошагового построения */
void CCHRealTimeView::Animate()
{
	if(Animation) {
		m_ToolBar->GetToolBarCtrl().HideButton(ID_STEP);
/*		m_ToolBar->GetToolBarCtrl().HideButton(LEFT_TREE,false);
		m_ToolBar->GetToolBarCtrl().HideButton(RIGHT_TREE,false);
		m_ToolBar->GetToolBarCtrl().HideButton(UP_TREE,false);
		m_ToolBar->GetToolBarCtrl().HideButton(GO_ROOT,false);
*/		m_bSituationEnabled = true;
		Animation=false;
		DrawPoints();
		DrawTree();
		for(vector<StepStruct *>::iterator i = stepstruct.begin(); i != stepstruct.end(); i++) if((*i)) delete (*i);
		stepstruct.clear();
		Step=0;
	}
	else {
		m_ToolBar->GetToolBarCtrl().HideButton(ID_STEP,false);
/*		m_ToolBar->GetToolBarCtrl().HideButton(LEFT_TREE);
		m_ToolBar->GetToolBarCtrl().HideButton(RIGHT_TREE);
		m_ToolBar->GetToolBarCtrl().HideButton(UP_TREE);
		m_ToolBar->GetToolBarCtrl().HideButton(GO_ROOT);
*/		m_bSituationEnabled = false;
		Animation=true;
		Step=0;
	}

}


/** Очистка контейнеров */
void CCHRealTimeView::Clear()
{
     Points.clear();
     situation.clear();
     RST.clear();
     Deleted.clear();
     DeleteTree(tree);
     tree=NULL;
     l = NULL;
     r = NULL;
     CurrNode=NULL;
     Opening=false;
     Invalidate(FALSE);

}


ofstream& print(ofstream& os,RandomizeNode<TPoint> *p, int w);
/** Вывод в файл дерева */
/** !!!Манипулятор!!! */
ofstream& operator<<(ofstream& os, RandomizeSearchTree<TPoint> &tmp)
{	
	RandomizeNode<TPoint> *n = tmp.getRoot();
	t_TreeIter it=tmp.find(n->getVal());
	os = print(os,(*it),1);
	return os;
}

FILE* outf;

/** Вспомогательная функция манипулятора */
ofstream& print(ofstream& os,RandomizeNode<TPoint> *p, int w)
{
	int i;
	 if (p != NULL)
	 {
		if (p->lchild())
			os = print(os,p->lchild(), w+3);
        for (i=1; i <= w; i++)
		{
			os<<" ";
		}
		char buf[200];
		sprintf(buf,"%d (%f)\n\n",p->getVal()->getID(),p->priority());
		os<<buf;
		if (p->rchild())
			os = print(os,p->rchild(),w+3);
	 }
	 return os;
}

/** функция для проверки работы манипулятора */
void print(RandomizeNode<TPoint> *p, int w)
{
	int i;
	 if (p != NULL)
	 {
		if (p->lchild())
			print(p->lchild(), w+3);
        for (i=1; i <= w; i++)
		{
			fputs(" ",outf);
			fflush(outf);
		}
		char buf[200];
		sprintf(buf,"%d (%f)\n\n",p->getVal()->getID(),p->priority());
		fputs(buf,outf);
		fflush(outf);
		if (p->rchild())
			print(p->rchild(),w+3);
	 }
}



// создать выпуклую оболочку
void CCHRealTimeView::Create_Convex_hull(CPoint point)
{
	
	Deleted.clear();
	DeleteTree(tree);
	tree = MakeTree(NULL,RST.getRoot());
	MakeNext(tree,tree,tree);
	MakePrev(tree);
	l = NULL;
	r = NULL;

	for(vector<StepStruct *>::iterator i = stepstruct.begin(); i != stepstruct.end(); i++) if((*i)) delete (*i);
	stepstruct.clear();
	situation.clear();	
	if(Search(RST.getRoot(),tree,point)) 
	{
		StepStruct *ss=new StepStruct(ltree,rtree,situation[situation.size()-1],4);
		stepstruct.push_back(ss);

		TPoint *tp;
		RandomizeNode<TPoint> *temp;
		if(r->getVal()->getID() > l->getVal()->getID()) 
		{
			temp=l->next();
			while(temp!=r) 
			{
				RST.setWin(temp);
				temp=temp->next();
				Deleted.push_back(RST.getWin()->getVal()->getID());
			RST.remove(RST.getWin()->getVal());
			}
			int dif=l->getVal()->getID() - r->getVal()->getID()+2;   //+2
			temp=r;
// перенумеровка вершин выпуклой оболочки
			dif = 2;


			do 
			{
				temp->getVal()->setID(dif);
				temp=temp->next();
				dif++;
			} while(temp!=r);

			tp=new TPoint(1,point.x,point.y);
			
			TPoint r_temp(*r->getVal());
			TPoint l_temp(*l->getVal());

			RandomizeSearchTree<TPoint> TempTree;
			t_TreeIter it = RST.begin();
			try
			{
				for (int i = 0; i < RST.size(); i++)
				{
					TPoint *qqq = (*it)->getVal();
					double www = (*it)->priority();
					TempTree.insert((*it)->getVal(),(*it)->priority(), false);
					++it;
				}
			}
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return;
			}			

			RST.clear();
			try
			{
				it = TempTree.begin();
				for (int i = 0; i < TempTree.size(); i++)
				{
					RST.insert((*it)->getVal(),(*it)->priority(), false);
					++it;
				}
			}
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return;
			}			


			it = RST.find(&r_temp);
			r = (*it);
			it = RST.find(&l_temp);
			l = (*it);

		
			RST.insert(tp);
		}
		else {
			temp = l->next();
			while(temp!=r) {
				RST.setWin(temp);
				temp=temp->next();
				Deleted.push_back(RST.getWin()->getVal()->getID());
				RST.remove(RST.getWin()->getVal());
			}
			int dif=2 - r->getVal()->getID();

			temp=r;
			dif = 2;
			do 
			{
				temp->getVal()->setID(dif);
				temp=temp->next();
				dif++;
			} while(temp!=r);

			tp=new TPoint(1,point.x,point.y);
			
			TPoint r_temp(*r->getVal());
			TPoint l_temp(*l->getVal());
			
			RandomizeSearchTree<TPoint> TempTree;
			t_TreeIter it = RST.begin();
			try
			{
				for (int i = 0; i < RST.size(); i++)
				{
					TempTree.insert((*it)->getVal(),(*it)->priority(), false);
					++it;
				}
				RST.clear();
				it = TempTree.begin();
				for (i = 0; i < TempTree.size(); i++)
				{
					RST.insert((*it)->getVal(),(*it)->priority(), false);
					++it;
				}
			}
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return;
			}			

			it = RST.find(&r_temp);
			r = (*it);
			it = RST.find(&l_temp);
			l = (*it);

			
			RST.insert(tp);
		 }

	}
	CurrNode=RST.getRoot();
		// вывод в файл всех вершин дерева с использованием манипулятора		
/*		ofstream fout;
		fout.open("print_man.txt");
		fout<<(RST);
		fout.close();
*/
	if(!Animation) {
		DrawPoints();
		DrawTree();
	} else
		NextStep();


}

/** Изобразить точки */
CCHRealTimeView::DrawPoints()
{
	int PointRad=3;	
	CClientDC dc(this);
		
	CDC dcMem;
	dcMem.CreateCompatibleDC(&dc);

	CBitmap bitmap,*pBitmap;
	bitmap.CreateCompatibleBitmap(&dc,ClientPoints.Width(),ClientPoints.Height());
	pBitmap=dcMem.SelectObject(&bitmap);
	dcMem.PatBlt(0,0,ClientPoints.Width(),ClientPoints.Height(),WHITENESS);
	
	dcMem.SelectObject(&bluep4);
	dcMem.SetBkMode(TRANSPARENT);
	double ScaleX=(double)ClientPoints.Width()/(double)DefaultClientPointsWidth;
	double ScaleY=(double)ClientPoints.Height()/(double)DefaultClientPointsHeight;
	if(RST.size()>0) 
	{
		try
		{
			t_TreeIter it = RST.begin();
			char buffer[10];
			_itoa((*it)->getVal()->getID(),buffer,10);

			int qqq = (*it)->getVal()->getID();
			int www = (*it)->prev()->getVal()->getID();
			
			PLine(&dcMem,((*it)->getVal()->getX())*ScaleX,((*it)->getVal()->getY())*ScaleY,(/*RST.roundprev()*/(*it)->prev()->getVal()->getX())*ScaleX,(/*RST.roundprev()*/(*it)->prev()->getVal()->getY())*ScaleY,3);
			dcMem.TextOut(((*it)->getVal()->getX())*ScaleX+5,((*it)->getVal()->getY())*ScaleY,buffer);
			do
			{
				++it;
				
				int qqq = (*it)->getVal()->getID();
				int www = (*it)->prev()->getVal()->getID();
			
				_itoa((*it)->getVal()->getID(),buffer,10);
				PLine(&dcMem,((*it)->getVal()->getX())*ScaleX,((*it)->getVal()->getY())*ScaleY,(/*RST.roundprev()*/(*it)->prev()->getVal()->getX())*ScaleX,(/*RST.roundprev()*/(*it)->prev()->getVal()->getY())*ScaleY,3);
				dcMem.TextOut(((*it)->getVal()->getX())*ScaleX+5,((*it)->getVal()->getY())*ScaleY,buffer);
			} while((*it)->next() != RST.getMin());
		}
		catch(treeException& ex)
		{
			AutoSave(true);
			AfxMessageBox(ex.get_comment());
			return NULL;
		}			

	}

	for(int i=0;i<Points.size();i++) {
		Point(&dcMem,CPoint(Points[i].x*ScaleX,Points[i].y*ScaleY),0);
	}
	if(RST.getRoot()) 
	{
		Point(&dcMem,CPoint(RST.getRoot()/*->rchild()*/->getVal()->getX()*ScaleX,RST.getRoot()/*->rchild()*/->getVal()->getY()*ScaleY),1);
		Point(&dcMem,CPoint(RST.getMin()->getVal()->getX()*ScaleX,RST.getMin()->getVal()->getY()*ScaleY),2);
	}
	dc.BitBlt(ClientPoints.left,ClientPoints.top,ClientPoints.Width(),ClientPoints.Height(),&dcMem,0,0,SRCCOPY);
	dcMem.DeleteDC();

}

/** Изобразить дерево */
CCHRealTimeView::DrawTree()
{
	CClientDC dc(this);
		
	CDC dcMem;
	dcMem.CreateCompatibleDC(&dc);
	if (!CurrNode) CurrNode=RST.getRoot();
	double iii=(double)RST.depthOfTree(CurrNode)*42.0;
	double ScaleX=(double)ClientTree.Width();
	double ScaleY=(double)ClientTree.Height()/iii;

	CBitmap bitmap,*pBitmap;
	bitmap.CreateCompatibleBitmap(&dc,ClientTree.Width(),ClientTree.Height());
	pBitmap=dcMem.SelectObject(&bitmap);
	dcMem.PatBlt(0,0,ClientTree.Width(),ClientTree.Height(),WHITENESS);
	
	
	if (CurrNode)
		ShowTree(CurrNode,&dcMem,10,ClientTree.right-ClientTree.left-10,0,ScaleX,ScaleY,((long)RST.getRoot()-(long)CurrNode));

	dc.BitBlt(ClientTree.left,ClientTree.top,ClientTree.Width(),ClientTree.Height(),&dcMem,0,0,SRCCOPY);
	dcMem.DeleteDC();
	
	if (m_bSituation)
	{
		CDC dcMem2;
		dcMem2.CreateCompatibleDC(&dc);
		CBitmap bitmap2,*pBitmap2;
		bitmap2.CreateCompatibleBitmap(&dc,ClientBmp.Width(),ClientBmp.Height());
		pBitmap2=dcMem2.SelectObject(&bitmap2);
		CBrush grayb((COLORREF)0x00C0C0C0);
		dcMem2.FillRect(CRect(0,0,ClientBmp.Width(),ClientBmp.Height()),&grayb);

		if(!situation.empty()) {
			dcMem2.DrawState(CPoint(0,0),CSize(133,110),bmp[situation[0]-1],DST_BITMAP);
			dcMem2.DrawState(CPoint(143,0),CSize(195,110),bmp[8],DST_BITMAP);
		}
			
		dc.BitBlt(ClientBmp.left,ClientBmp.top,ClientBmp.Width(),ClientBmp.Height(),&dcMem2,0,0,SRCCOPY);
		dcMem2.DeleteDC();
	}	

}


CCHRealTimeView::FExport()
{
  CFileDialog fileDlg(FALSE);
  CString str("Точки (.din)"); str += (TCHAR)NULL; str+="*.bmp"; str += (TCHAR)NULL; 
  fileDlg.m_ofn.lpstrFilter = str;
  fileDlg.m_ofn.nFilterIndex = 1;
  fileDlg.m_ofn.lpstrDefExt = "bmp";

  TCHAR strName[_MAX_PATH];

  strName[0] = (TCHAR)NULL;
  fileDlg.m_ofn.lpstrFile = strName;
  
  TCHAR title[] = "Экспорт картинок";
  fileDlg.m_ofn.lpstrTitle = title;

  if (fileDlg.DoModal() == IDOK)
  {
	if(Animation) {
		Step--;
		NextStep();
	}
	else {
		DrawPoints();
		DrawTree();
	}
	WriteWindowToDIB(strName, ClientPoints, this);

	CString s1=fileDlg.GetPathName();
    s1.Insert(s1.GetLength()-4,'T');
	WriteWindowToDIB(s1.GetBuffer(3), ClientTree, this);

	CString s2=fileDlg.GetPathName();
    s2.Insert(s2.GetLength()-4,'S');
	WriteWindowToDIB(s2.GetBuffer(3), ClientBmp, this);
  }

}

/** Генерация точек */
void CCHRealTimeView::Generate()
{
	if(!generating) {
		srand(6666672);

		distribution=0;
		generating=true;
		SetTimer(ID_GENERATING,500,NULL);
	}
	else {
		KillTimer(ID_GENERATING);
		generating=false;
	}

}

//моё
int CCHRealTimeView::PointSurLine(CPoint p)
{
	
	//t_TreeIter it = RST.begin();
	RandomizeNode<TPoint> *tmp = RST.getRoot(), *tmp1;
	//RandomizeNode<TPoint> *tmp = *it, *tmp1;
	tmp = tmp->minimum();

	tmp1 = tmp;

	do
	{
		RandomizeNode<TPoint> *tm;
		double K, B;
		tm = tmp->next();

		if (tmp->getVal()->getX() != tm->getVal()->getX())
		{
			K = (tmp->getVal()->getY() - tm->getVal()->getY())/(tmp->getVal()->getX() - tm->getVal()->getX());
			B = tmp->getVal()->getY() - K*tmp->getVal()->getX();
			if ( K*p.x + B == p.y)
				return 1;
		}
		else
			if (p.x == tmp->getVal()->getX())
				return 1;
		tmp = tmp->next();
	}
	while (tmp->next() != tmp1);
    return 0;
}

/** Добавление новой точки */
CCHRealTimeView::InsertNewPoint(CPoint point)
{
	double ScaleX=(double)ClientPoints.Width()/(double)DefaultClientPointsWidth;
	double ScaleY=(double)ClientPoints.Height()/(double)DefaultClientPointsHeight;

	CClientDC dc(this);

	int kol=0;

	if (defaultPalleteColor==0)
		defaultPalleteColor=dc.GetPixel(ClientPoints.left+point.x*ScaleX,ClientPoints.top+point.y*ScaleY);

	COLORREF ccc;

	if (generating)
	{
		for (int k = 0; k < 5; k++)
		{

			for (int ii=-2; ii<=2; ii++)
				for (int jj=-2; jj<=2; jj++)
					if ((point.x*ScaleX+ii)>0 &&
						(point.y*ScaleY+jj)>0 &&
						(point.x*ScaleX+ii)<ClientPoints.Width() &&
						(point.y*ScaleY+jj)<ClientPoints.Height())
					{
						ccc=dc.GetPixel(ClientPoints.left+point.x*ScaleX+ii,ClientPoints.top+point.y*ScaleY+jj);
						if  ((ccc!=defaultPalleteColor) &&
							(ccc!=defaultTextColor))      
							kol++;

					}
			if (kol == 0)
				break;
			else
			{	
				if (k != 4)
				{
					kol = 0;
					point = Rovn(ClientPoints.right/2,ClientPoints.bottom/2,ClientPoints.right/8,ClientPoints.bottom/8);
				}
			}
		}
	}
	else
	{
		kol = 0;
		for (int ii=-2; ii<=2; ii++)
			for (int jj=-2; jj<=2; jj++)
				if ((point.x*ScaleX+ii)>0 &&
					(point.y*ScaleY+jj)>0 &&
					(point.x*ScaleX+ii)<ClientPoints.Width() &&
					(point.y*ScaleY+jj)<ClientPoints.Height())
				{
					ccc=dc.GetPixel(ClientPoints.left+point.x*ScaleX+ii,ClientPoints.top+point.y*ScaleY+jj);
					if  ((ccc!=defaultPalleteColor) &&
						(ccc!=defaultTextColor))      
						kol++;

				}
	}
	if (kol > 0)
	{
		if (m_bValueGenerating)
			m_iNumGenPoints--;
		return 0;
	}

	TPoint *tp;
	for(vector<CPoint>::iterator i = Points.begin(); i != Points.end();i++){
		if(((*i).x == point.x) && ((*i).y == point.y)) return 0;
	};
	Points.push_back(point);
//	AutoSave();				// автосохранение точек на каждом шаге

	if (Points.size() == 134)
	{
		int j = 1;
	}
	InputPoint=point;
	for(vector<StepStruct *>::iterator iss = stepstruct.begin(); iss != stepstruct.end(); iss++) if((*iss)) delete (*iss);
	stepstruct.clear();
	Step=0;
	
	if(RST.size()<2) {
		tp=new TPoint(RST.size()+1,point.x,point.y);
		RST.insert(tp);
		CurrNode=RST.getRoot();
		DrawPoints();

		DeleteTree(tree);
		tree=MakeTree(NULL,RST.getRoot());
		MakeNext(tree,tree,tree);
		
		
		DrawTree();
	}
	else {
		Create_Convex_hull(point);
	}
	
}

/** Следующий шаг (в пошаговом режиме)*/
void CCHRealTimeView::NextStep()
{
	if(Animation) {
		if (Step>=0)
		if(stepstruct.size()>=Step+1) {
			StepStruct *ss;
			ss=stepstruct[Step];
			ShowStep(ss->stage,ss->situation,ss->root,ss->seltree);
			Step++;
		}
		else {
			if(stepstruct.size()==Step)
				Step++;
			DrawPoints();
			DrawTree();
			SetTimer(ID_OPENING,500,NULL);
		}
	}

}


/** Открыть файл */
CCHRealTimeView::Open()
{
  CFileDialog fileDlg(TRUE);
  CString str("Точки (.din)"); str += (TCHAR)NULL; str+="*.din"; str += (TCHAR)NULL; 
  fileDlg.m_ofn.lpstrFilter = str;
  fileDlg.m_ofn.nFilterIndex = 1;
  fileDlg.m_ofn.lpstrDefExt = "din";

  TCHAR strName[_MAX_PATH];

  strName[0] = (TCHAR)NULL;
  fileDlg.m_ofn.lpstrFile = strName;
  
  if (fileDlg.DoModal() == IDOK)
  {
	Clear();
	CFile f(strName,CFile::modeRead);
	CPoint p;
	OpenPoints.clear();
	while(f.Read(&p,sizeof(CPoint))==sizeof(CPoint)){
		OpenPoints.push_back(p);
	}
	Opening=true;
	OpenNum=0;
	SetTimer(ID_OPENING,500,NULL);
	Invalidate();
	f.Close();
  }
}


/** Сохранить точки */
CCHRealTimeView::SaveAs()
{
CFileDialog fileDlg(FALSE);
  CString str("Точки (.din)"); str += (TCHAR)NULL; str+="*.din"; str += (TCHAR)NULL; 
  fileDlg.m_ofn.lpstrFilter = str;
  fileDlg.m_ofn.nFilterIndex = 1;
  fileDlg.m_ofn.lpstrDefExt = "din";

  TCHAR strName[_MAX_PATH];

  strName[0] = (TCHAR)NULL;
  fileDlg.m_ofn.lpstrFile = strName;
  
  if (fileDlg.DoModal() == IDOK)
  {
	CFile f(strName,CFile::modeCreate|CFile::modeWrite);
	for(int i=0;i<Points.size();i++) {
		f.Write(&Points[i],sizeof(CPoint));
	}
	f.Close();
  }
}



/** Показать текущий шаг ( в пошаговом режиме) */
CCHRealTimeView::ShowStep(int stage, int situation, TTree *subtree, TTree *seltree)
{
	CClientDC dc(this);
	CDC dcMem1,dcMem2,dcMem3;
	dcMem1.CreateCompatibleDC(&dc);
	dcMem2.CreateCompatibleDC(&dc);
	dcMem3.CreateCompatibleDC(&dc);

	CBitmap *p_pointsBmp,pointsBmp;
	CBitmap *p_treeBmp,treeBmp;
	CBitmap *p_situationBmp,situationBmp;
	
	pointsBmp.CreateCompatibleBitmap(&dc,ClientPoints.Width(),ClientPoints.Height());
	treeBmp.CreateCompatibleBitmap(&dc,ClientTree.Width(),ClientTree.Height());
	situationBmp.CreateCompatibleBitmap(&dc,ClientBmp.Width(),ClientBmp.Height());

	p_pointsBmp=dcMem1.SelectObject(&pointsBmp);
	p_treeBmp=dcMem2.SelectObject(&treeBmp);
	p_situationBmp=dcMem3.SelectObject(&situationBmp);

	CBrush grayb((COLORREF)0x00C0C0C0);

	double ScaleX=(double)ClientPoints.Width()/(double)DefaultClientPointsWidth;
	double ScaleY=(double)ClientPoints.Height()/(double)DefaultClientPointsHeight;
	
	CPoint tmp_point;
	double iii;
	double SXTree;
	double SYTree;

	switch(stage) {
	case 1:
		dcMem1.PatBlt(0,0,ClientPoints.Width(),ClientPoints.Height(),WHITENESS);
		dcMem2.PatBlt(0,0,ClientTree.Width(),ClientTree.Height(),WHITENESS);
		
		dcMem1.SelectObject(&bluep4);
		dcMem1.SetBkMode(TRANSPARENT);
		if(RST.size()>0 && (long)subtree != 0xcdcdcdcd)
		{
			char buffer[10];
			TTree *t= subtree->minimum();
			do
			{
				_itoa(t->getVal()->getID(),buffer,10);
				PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,t->next->getVal()->getX()*ScaleX,t->next->getVal()->getY()*ScaleY,3);
				dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
				Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);
				t=t->next;
			}while(t!=subtree->minimum());
			PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,subtree->minimum()->getVal()->getX()*ScaleX,subtree->minimum()->getVal()->getY()*ScaleY,3);
			_itoa(t->getVal()->getID(),buffer,10);
			dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
			Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);

		}
		
		if(RST.getRoot() && (long)subtree != 0xcdcdcdcd) 
		{
			Point(&dcMem1,CPoint(subtree->getVal()->getX()*ScaleX,subtree->getVal()->getY()*ScaleY),1);
			Point(&dcMem1,CPoint(subtree->minimum()->getVal()->getX()*ScaleX,subtree->minimum()->getVal()->getY()*ScaleY),2);
		}
	
		tmp_point.x=InputPoint.x*ScaleX;
		tmp_point.y=InputPoint.y*ScaleY;
		Point(&dcMem1,tmp_point,0);
		if ( (long)subtree != 0xcdcdcdcd)
		{
			PLine(&dcMem1,InputPoint.x*ScaleX,InputPoint.y*ScaleY,subtree->minimum()->getVal()->getX()*ScaleX,subtree->minimum()->getVal()->getY()*ScaleY,3,1);
			PLine(&dcMem1,InputPoint.x*ScaleX,InputPoint.y*ScaleY,subtree->getVal()->getX()*ScaleX,subtree->getVal()->getY()*ScaleY,3,1);
			
			iii=(double)subtree->depthOfTree(subtree)*42.0;
			SXTree=(double)ClientTree.Width();
			SYTree=(double)ClientTree.Height()/iii;
			
			
			ShowTree(subtree,NULL,&dcMem2,10,ClientTree.right-ClientTree.left-10,0,SXTree,SYTree);
		}	

		dcMem3.FillRect(CRect(0,0,ClientBmp.Width(),ClientBmp.Height()),&grayb);

		if(situation) 
		{
			dcMem3.DrawState(CPoint(0,0),CSize(133,110),bmp[situation-1],DST_BITMAP);
			dcMem3.DrawState(CPoint(143,0),CSize(195,110),bmp[8],DST_BITMAP);
		}
		dc.BitBlt(ClientPoints.left,ClientPoints.top,ClientPoints.Width(),ClientPoints.Height(),&dcMem1,0,0,SRCCOPY);
		dc.BitBlt(ClientTree.left,ClientTree.top,ClientTree.Width(),ClientTree.Height(),&dcMem2,0,0,SRCCOPY);
			dc.BitBlt(ClientBmp.left,ClientBmp.top,ClientBmp.Width(),ClientBmp.Height(),&dcMem3,0,0,SRCCOPY);
		break;

	case 2:
		dcMem1.PatBlt(0,0,ClientPoints.Width(),ClientPoints.Height(),WHITENESS);
		dcMem2.PatBlt(0,0,ClientTree.Width(),ClientTree.Height(),WHITENESS);
		
		dcMem1.SelectObject(&bluep4);
		dcMem1.SetBkMode(TRANSPARENT);
		if(RST.size()>0 && (long)subtree != 0xcdcdcdcd) {
			char buffer[10];
			TTree *t= subtree->minimum();
			do
			{
				_itoa(t->getVal()->getID(),buffer,10);
				PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,t->next->getVal()->getX()*ScaleX,t->next->getVal()->getY()*ScaleY,3);
				dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
				Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);
				t=t->next;
			} while(t!=subtree->minimum());
			PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,subtree->minimum()->getVal()->getX()*ScaleX,subtree->minimum()->getVal()->getY()*ScaleY,3);
			_itoa(t->getVal()->getID(),buffer,10);
			dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
			Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);

		}
		
		if(RST.getRoot() && (long)subtree != 0xcdcdcdcd) {
			Point(&dcMem1,CPoint(subtree->getVal()->getX()*ScaleX,subtree->getVal()->getY()*ScaleY),1);
			Point(&dcMem1,CPoint(subtree->minimum()->getVal()->getX()*ScaleX,subtree->minimum()->getVal()->getY()*ScaleY),2);
		}
		
		tmp_point.x=InputPoint.x*ScaleX;
		tmp_point.y=InputPoint.y*ScaleY;
		Point(&dcMem1,tmp_point,0);
		if ((long)subtree != 0xcdcdcdcd)
		{
			PLine(&dcMem1,InputPoint.x*ScaleX,InputPoint.y*ScaleY,subtree->minimum()->getVal()->getX()*ScaleX,subtree->minimum()->getVal()->getY()*ScaleY,3,1);
			PLine(&dcMem1,InputPoint.x*ScaleX,InputPoint.y*ScaleY,subtree->getVal()->getX()*ScaleX,subtree->getVal()->getY()*ScaleY,3,1);
			iii=(double)subtree->depthOfTree(subtree)*42.0;
			SXTree=(double)ClientTree.Width();
			SYTree=(double)ClientTree.Height()/iii;

			ShowTree(subtree,seltree,&dcMem2,10,ClientTree.right-ClientTree.left-10,0,SXTree,SYTree);
			
		}
		dcMem3.FillRect(CRect(0,0,ClientBmp.Width(),ClientBmp.Height()),&grayb);

		if(situation) {
			dcMem3.DrawState(CPoint(0,0),CSize(133,110),bmp[situation-1],DST_BITMAP);
			dcMem3.DrawState(CPoint(143,0),CSize(195,110),bmp[8],DST_BITMAP);
		}
		dc.BitBlt(ClientPoints.left,ClientPoints.top,ClientPoints.Width(),ClientPoints.Height(),&dcMem1,0,0,SRCCOPY);
		dc.BitBlt(ClientTree.left,ClientTree.top,ClientTree.Width(),ClientTree.Height(),&dcMem2,0,0,SRCCOPY);
		dc.BitBlt(ClientBmp.left,ClientBmp.top,ClientBmp.Width(),ClientBmp.Height(),&dcMem3,0,0,SRCCOPY);
		break;
	case 3:
		dcMem1.PatBlt(0,0,ClientPoints.Width(),ClientPoints.Height(),WHITENESS);
		dcMem2.PatBlt(0,0,ClientTree.Width(),ClientTree.Height(),WHITENESS);
		
		dcMem1.SelectObject(&bluep4);
		dcMem1.SetBkMode(TRANSPARENT);
		if(RST.size()>0) {
			char buffer[10];
			TTree *t= stree->minimum();
			do
			{
				_itoa(t->getVal()->getID(),buffer,10);
				PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,t->next->getVal()->getX()*ScaleX,t->next->getVal()->getY()*ScaleY,3);
				dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
				Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);
				t=t->next;
			} while(t!=stree->minimum());
			PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,stree->minimum()->getVal()->getX()*ScaleX,stree->minimum()->getVal()->getY()*ScaleY,3);
			_itoa(t->getVal()->getID(),buffer,10);
			dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
			Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);
		}
		if(seltree==NULL) {
			if ((long)subtree != 0xcdcdcdcd)
				PLine(&dcMem1,InputPoint.x*ScaleX,InputPoint.y*ScaleY,subtree->getVal()->getX()*ScaleX,subtree->getVal()->getY()*ScaleY,3,4);
		}
		else {
			if ((long)subtree != 0xcdcdcdcd)
				PLine(&dcMem1,InputPoint.x*ScaleX,InputPoint.y*ScaleY,subtree->getVal()->getX()*ScaleX,subtree->getVal()->getY()*ScaleY,3,1);
		}

		if(RST.getRoot()) {
			Point(&dcMem1,CPoint(stree->getVal()->getX()*ScaleX,stree->getVal()->getY()*ScaleY),1);
			Point(&dcMem1,CPoint(stree->minimum()->getVal()->getX()*ScaleX,stree->minimum()->getVal()->getY()*ScaleY),2);
		}
	
		tmp_point.x=InputPoint.x*ScaleX;
		tmp_point.y=InputPoint.y*ScaleY;
		Point(&dcMem1,tmp_point,0);
		
		if ((long)subtree != 0xcdcdcdcd)
		{	
			iii=(double)subtree->depthOfTree(subtree)*42.0;
			SXTree=(double)ClientTree.Width();
			SYTree=(double)ClientTree.Height()/iii;

			ShowTree(subtree,seltree,&dcMem2,10,ClientTree.right-ClientTree.left-10,0,SXTree,SYTree);
		
		}
		dcMem3.FillRect(CRect(0,0,ClientBmp.Width(),ClientBmp.Height()),&grayb);

		if(situation) {
			dcMem3.DrawState(CPoint(0,0),CSize(133,110),bmp[situation-1],DST_BITMAP);
			dcMem3.DrawState(CPoint(143,0),CSize(195,110),bmp[8],DST_BITMAP);
		}
		dc.BitBlt(ClientPoints.left,ClientPoints.top,ClientPoints.Width(),ClientPoints.Height(),&dcMem1,0,0,SRCCOPY);
		dc.BitBlt(ClientTree.left,ClientTree.top,ClientTree.Width(),ClientTree.Height(),&dcMem2,0,0,SRCCOPY);
		dc.BitBlt(ClientBmp.left,ClientBmp.top,ClientBmp.Width(),ClientBmp.Height(),&dcMem3,0,0,SRCCOPY);
		break;

	case 4:
		dcMem1.PatBlt(0,0,ClientPoints.Width(),ClientPoints.Height(),WHITENESS);
		dcMem2.PatBlt(0,0,ClientTree.Width(),ClientTree.Height(),WHITENESS);
		
		dcMem1.SelectObject(&bluep4);
		dcMem1.SetBkMode(TRANSPARENT);
		if(RST.size()>0) {
			char buffer[10];
			TTree *t= tree->minimum();
			do
			{
				_itoa(t->getVal()->getID(),buffer,10);
				PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,t->next->getVal()->getX()*ScaleX,t->next->getVal()->getY()*ScaleY,3);
				dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
				Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);
				t=t->next;
			} while(t!=tree->minimum());
			PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,tree/*->rchild*/->minimum()->getVal()->getX()*ScaleX,tree/*->rchild*/->minimum()->getVal()->getY()*ScaleY,3);
			_itoa(t->getVal()->getID(),buffer,10);
			dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
			Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);
		}
		if ((long)subtree != 0xcdcdcdcd && (long)seltree != 0xcdcdcdcd && subtree->getVal())
		{

			PLine(&dcMem1,InputPoint.x*ScaleX,InputPoint.y*ScaleY,subtree->getVal()->getX()*ScaleX,subtree->getVal()->getY()*ScaleY,3,4);
			PLine(&dcMem1,InputPoint.x*ScaleX,InputPoint.y*ScaleY,seltree->getVal()->getX()*ScaleX,seltree->getVal()->getY()*ScaleY,3,4);
		
			if (RST.size() != 3)
			{
				if(subtree->getVal()->getID() > seltree->getVal()->getID()) 
				{
					TTree *t= subtree;
					while(t!=seltree) {
						PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,t->next->getVal()->getX()*ScaleX,t->next->getVal()->getY()*ScaleY,3,2);
						t=t->next;
					}
				}
				else {
					TTree *t= subtree;
					while(t!=seltree) {
						PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,t->next->getVal()->getX()*ScaleX,t->next->getVal()->getY()*ScaleY,3,2);
						t=t->next;
					}
				}
			}
		}
		if(RST.getRoot()) {
			Point(&dcMem1,CPoint(stree->getVal()->getX()*ScaleX,stree->getVal()->getY()*ScaleY),1);
			Point(&dcMem1,CPoint(stree->minimum()->getVal()->getX()*ScaleX,stree->minimum()->getVal()->getY()*ScaleY),2);
		}
	
		tmp_point.x=InputPoint.x*ScaleX;
		tmp_point.y=InputPoint.y*ScaleY;
		Point(&dcMem1,tmp_point,0);
		


		iii=(double)tree->depthOfTree(tree)*42.0;
		SXTree=(double)ClientTree.Width();
		SYTree=(double)ClientTree.Height()/iii;

		ShowTree(tree,NULL,&dcMem2,10,ClientTree.right-ClientTree.left-10,0,SXTree,SYTree,false,true);
		dcMem3.FillRect(CRect(0,0,ClientBmp.Width(),ClientBmp.Height()),&grayb);
		
 
		if(situation) {
			dcMem3.DrawState(CPoint(0,0),CSize(133,110),bmp[situation-1],DST_BITMAP);
			dcMem3.DrawState(CPoint(143,0),CSize(195,110),bmp[8],DST_BITMAP);
		}
		dc.BitBlt(ClientPoints.left,ClientPoints.top,ClientPoints.Width(),ClientPoints.Height(),&dcMem1,0,0,SRCCOPY);
		dc.BitBlt(ClientTree.left,ClientTree.top,ClientTree.Width(),ClientTree.Height(),&dcMem2,0,0,SRCCOPY);
		dc.BitBlt(ClientBmp.left,ClientBmp.top,ClientBmp.Width(),ClientBmp.Height(),&dcMem3,0,0,SRCCOPY);
		
		break;
	case 5:
		dcMem1.PatBlt(0,0,ClientPoints.Width(),ClientPoints.Height(),WHITENESS);
		dcMem2.PatBlt(0,0,ClientTree.Width(),ClientTree.Height(),WHITENESS);
		
		dcMem1.SelectObject(&bluep4);
		dcMem1.SetBkMode(TRANSPARENT);
		if(RST.size()>0) {
			char buffer[10];
			TTree *t= tree->minimum();
			do
			{
				_itoa(t->getVal()->getID(),buffer,10);
				PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,t->next->getVal()->getX()*ScaleX,t->next->getVal()->getY()*ScaleY,3);
				dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
				Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);
				t=t->next;
			} while(t!=tree->minimum());
			PLine(&dcMem1,t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY,tree/*->rchild*/->minimum()->getVal()->getX()*ScaleX,tree/*->rchild*/->minimum()->getVal()->getY()*ScaleY,3);
			_itoa(t->getVal()->getID(),buffer,10);
			dcMem1.TextOut(t->getVal()->getX()*ScaleX+5,t->getVal()->getY()*ScaleY,buffer);
			Point(&dcMem1,CPoint(t->getVal()->getX()*ScaleX,t->getVal()->getY()*ScaleY),0);
		}
		

		if(RST.getRoot()) {
			Point(&dcMem1,CPoint(stree->getVal()->getX()*ScaleX,stree->getVal()->getY()*ScaleY),1);
			Point(&dcMem1,CPoint(stree->minimum()->getVal()->getX()*ScaleX,stree->minimum()->getVal()->getY()*ScaleY),2);
		}
	
		tmp_point.x=InputPoint.x*ScaleX;
		tmp_point.y=InputPoint.y*ScaleY;
		Point(&dcMem1,tmp_point,0);
				
		iii=(double)subtree->depthOfTree(subtree)*42.0;
		SXTree=(double)ClientTree.Width();
		SYTree=(double)ClientTree.Height()/iii;

		ShowTree(tree,NULL,&dcMem2,10,ClientTree.right-ClientTree.left-10,0,SXTree,SYTree);
		dcMem3.FillRect(CRect(0,0,ClientBmp.Width(),ClientBmp.Height()),&grayb);


		dc.BitBlt(ClientPoints.left,ClientPoints.top,ClientPoints.Width(),ClientPoints.Height(),&dcMem1,0,0,SRCCOPY);
		dc.BitBlt(ClientTree.left,ClientTree.top,ClientTree.Width(),ClientTree.Height(),&dcMem2,0,0,SRCCOPY);
		dc.BitBlt(ClientBmp.left,ClientBmp.top,ClientBmp.Width(),ClientBmp.Height(),&dcMem3,0,0,SRCCOPY);
		
		break;
	}
	dcMem1.DeleteDC();
	dcMem2.DeleteDC();
	dcMem3.DeleteDC();
}

CCHRealTimeView::StepBack()
{
if(Animation && Step>1) {
			StepStruct *ss;
			Step--;
				ss=stepstruct[Step-1];
			ShowStep(ss->stage,ss->situation,ss->root,ss->seltree);
			
	}
}

/** Левый поиск */
RandomizeNode<TPoint> * CCHRealTimeView::Left_Search(RandomizeNode<TPoint> *root, TTree *troot, CPoint p)
{
	try{
		RandomizeNode<TPoint> *l;
		RandomizeNode<TPoint> *RN;
		TTree *treeTree;
		RST.setWin(root);
		CPoint v1(RST.roundprev()->getX(),RST.roundprev()->getY());
		CPoint v(RST.getWin()->getVal()->getX(),RST.getWin()->getVal()->getY());
		CPoint v2(RST.roundnext()->getX(),RST.roundnext()->getY());

		bool abut = false;
		bool conv = false;

		t_TreeIter it = RST.find(root->getVal());
		if ((v.x == v1.x) && (v.x == v2.x) && (p.x != v.x))
		{
			try
			{
				while (((*it)->getVal()->getX() == v.x) && ((*it)->next()->getVal() != root->getVal()))
					++it;
			}
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return NULL;
			}			

			if ((((*it)->getVal()->getX() > v.x) && (p.x > v.x)) ||(((*it)->getVal()->getX() < v.x) && (p.x < v.x)))
			{
				conv = 0;
				abut = 0;
			}
			else
			if ((((*it)->getVal()->getX() > v.x) && (p.x < v.x)) ||(((*it)->getVal()->getX() < v.x) && (p.x > v.x)))
			{
				conv = 1;
				abut = 0;
			}
			else
			if ((p.y < v.y) ||(p.y > v.y) || (p.y == v.y))
				conv = 1;
		}
		else
		if ((v.y == v1.y) && (v.y == v2.y) && (p.y != v.y))
		{
			t_TreeIter it = RST.find(root->getVal());
			try
			{
				while (((*it)->getVal()->getY() == v.y) && ((*it)->next()->getVal() != root->getVal()))
					++it;
			}	
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return NULL;
			}			
			if ((((*it)->getVal()->getY() > v.y) && (p.y > v.y)) ||(((*it)->getVal()->getY() < v.y) && (p.x < v.x)))
			{
				conv = 0;
				abut = 0;
			}
			else
			if ((((*it)->getVal()->getY() > v.y) && (p.y < v.y)) ||(((*it)->getVal()->getY() < v.y) && (p.y > v.y)))
			{
				conv = 1;
				abut = 0;
			}
			else
			if ((p.x < v.x) ||(p.x > v.x) || (p.x == v.x))
				conv = 1;
		}
		/*
		else
		if ((v1.x == v.x) && (v2.x != v.x) && (p.x != v.x))
		{
		}
		else
		if ((v2.x == v.x) && (v1.x != v.x) && (p.x != v.x))
		{
		}
		else
		if ((v1.y == v.y) && (v2.y != v.y) && (p.y != v.y))
		{
			if (((v2.y > v.y) && (p.y > v.y)) || ((v2.y < v.y) && (p.y < v.y))) 
			{	
				conv = 0;
				abut = 0;
			}
			else
			if (((v2.y > v.y) && (p.y < v.y)) || ((v2.y < v.y) && (p.y > v.y))) 
			{	
				conv = 0;
				abut = 1;
			}
		}
		else
		if ((v2.y == v.y) && (v1.y != v.y) && (p.y != v.y))
		{
			if (((v1.y > v.y) && (p.y > v.y)) || ((v1.y < v.y) && (p.y < v.y))) 
			{	
				conv = 0;
				abut = 0;
			}
			else
			if (((v2.y > v.y) && (p.y < v.y)) || ((v2.y < v.y) && (p.y > v.y))) 
			{	
				conv = 0;
				abut = 1;
			}
		}
*/
		if(IsAbutment(v1,v,v2,p) || abut) {
			l=root;
			ltree=troot;
			StepStruct *ss=new StepStruct(troot,ltree,situation[situation.size()-1],3);
			stepstruct.push_back(ss);
		}
		else {
			if(IsConvex(v1,v,v2,p) || conv) {
				RN=root->lchild();
				treeTree=troot->lchild;
				StepStruct *ss=new StepStruct(troot,treeTree,situation[situation.size()-1],3);
				stepstruct.push_back(ss);
			}
			else {
				RN=root->rchild();// добавил
				treeTree=troot->rchild;
				StepStruct *ss=new StepStruct(troot,treeTree,situation[situation.size()-1],3);
				stepstruct.push_back(ss);
			}
			if(treeTree){
				l=Left_Search(RN,treeTree,p);
			}else{
				l=root;
				ltree=troot;
				StepStruct *ss=new StepStruct(troot,ltree,situation[situation.size()-1],3);
				stepstruct.push_back(ss);
			};
		}
	return l;
	}
	catch(...) {AfxMessageBox("Ошибка при определении левой опорной точки!");}


}


/** Правый поиск */
RandomizeNode<TPoint> * CCHRealTimeView::Right_Search(RandomizeNode<TPoint> *root,TTree *troot, CPoint p)
{
	try{
		RandomizeNode<TPoint> *r;
		RandomizeNode<TPoint> *RN;
		TTree *treeTree;
		RST.setWin(root);
		CPoint v1(RST.roundprev()->getX(),RST.roundprev()->getY());
		CPoint v(RST.getWin()->getVal()->getX(),RST.getWin()->getVal()->getY());
		CPoint v2(RST.roundnext()->getX(),RST.roundnext()->getY());
		bool abut = false;
		bool conv = false;

		if ((v.x == v1.x) && (v.x == v2.x) && (p.x != v.x))
		{
			t_TreeIter it = RST.find(root->getVal());
			try
			{
				while (((*it)->getVal()->getX() == v.x) && ((*it)->next()->getVal() != root->getVal()))
					++it;
			}
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return NULL;
			}			
			if ((((*it)->getVal()->getX() > v.x) && (p.x > v.x)) ||(((*it)->getVal()->getX() < v.x) && (p.x < v.x)))
			{
				conv = 0;
				abut = 0;
			}
			else
			if ((((*it)->getVal()->getX() > v.x) && (p.x < v.x)) ||(((*it)->getVal()->getX() < v.x) && (p.x > v.x)))
			{
				conv = 1;
				abut = 0;
			}
			else
			if (p.y < v.y)
				conv = 1;
		}
		else
		if ((v.y == v1.y) && (v.y == v2.y) && (p.y != v.y))
		{
			t_TreeIter it = RST.find(root->getVal());
			try
			{
				while (((*it)->getVal()->getY() == v.y) && ((*it)->next()->getVal() != root->getVal()))
					++it;
			}
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return NULL;
			}			

			if ((((*it)->getVal()->getY() > v.y) && (p.y > v.y)) ||(((*it)->getVal()->getY() < v.y) && (p.x < v.x)))
			{
				conv = 0;
				abut = 0;
			}
			else
			if ((((*it)->getVal()->getY() > v.y) && (p.y < v.y)) ||(((*it)->getVal()->getY() < v.y) && (p.y > v.y)))
			{
				conv = 1;
				abut = 0;
			}
			else
			if (p.x < v.x)
				conv = 1;
		}



		if(IsAbutment(v1,v,v2,p) || abut) {
			r=root;
			rtree=troot;
			StepStruct *ss=new StepStruct(troot,rtree,situation[situation.size()-1],3);
			stepstruct.push_back(ss);
		}
		else {
			if(IsConvex(v1,v,v2,p) || conv) {
				RN=root->rchild();
				treeTree=troot->rchild;
				StepStruct *ss=new StepStruct(troot,treeTree,situation[situation.size()-1],3);
				stepstruct.push_back(ss);
			}
			else {
				RN=root->lchild();
				treeTree=troot->lchild;
				StepStruct *ss=new StepStruct(troot,treeTree,situation[situation.size()-1],3);
				stepstruct.push_back(ss);
			}
			if(treeTree){
				r=Right_Search(RN,treeTree,p);
			}else{
				r=root;
				rtree=troot;
				StepStruct *ss=new StepStruct(troot,rtree,situation[situation.size()-1],3);
				stepstruct.push_back(ss);
			};
		}
	return r;
	}
	catch(...) {AfxMessageBox("Ошибка при определении правой опорной точки!");}

}


/** Поиск опорных точек */
bool CCHRealTimeView::Search(RandomizeNode<TPoint> *root,TTree *troot, CPoint p)
{
	try{
	if(!root) {
		StepStruct *ss=new StepStruct(troot,NULL,0,5);
		stepstruct.push_back(ss);
		return false;
	}

	if (Points.size() == 5)
	{
		int i = 1;
	}
	int sit=Situation(root->minimum(),root,p);
	situation.push_back(sit);
	
	StepStruct *ss=new StepStruct(troot,NULL,sit,1);
	stepstruct.push_back(ss);
	
	stree=troot;
	switch(sit) {
	case 1:
		ss=new StepStruct(troot,troot->rchild,sit,2);
		stepstruct.push_back(ss);
		
		if (root->rchild()) //добавил
			return Search(root->rchild(),troot->rchild,p);
		else
			if (l != NULL && r == l)
			{
				l = NULL;
				ltree = NULL;
				l = Left_Search(root,troot,p);
				return true;
			}
			else
			if (root->lchild())
				return Search(root->lchild(),troot->lchild,p);
			else
				return Search(root->rchild(),troot->rchild,p);

		break;
	case 2:
		try{
		if(root->rchild()) r=Right_Search(root->rchild(),troot->rchild,p);
		else 
		{
			r = root;
			rtree = troot;
		}
		if(root == root->minimum() && root->lchild()) l=Left_Search(root->lchild(),troot->lchild,p);
		else
		if(root) l=Left_Search(root,troot,p);
		else 
		{
			l = root;
			ltree = troot;
		}	
		if (l == r && root->parent())
			return Search(root->parent(),troot->parent,p);
		return true;
		}
		catch(...) {AfxMessageBox("Ошибка при обработке ситуации 2!");}

		break;
	case 3:
		ss=new StepStruct(troot,troot->lchild,sit,2);
		stepstruct.push_back(ss);
		if (root->lchild()) //добавил
			return Search(root->lchild(),troot->lchild,p);
		else
			if (l != NULL && r == l)
			{
				l = NULL;
				ltree = NULL;
				l = Left_Search(root,troot,p);
				return true;
			}
			else
			if (root->rchild())
				return Search(root->rchild(),troot->rchild,p);
			else
				return Search(root->lchild(),troot->lchild,p);

		
		break;
	case 4:{
		if (RST.size() == 2)
		{
			r = Right_Search(root->lchild(),troot->lchild,p);
			l = root;
			ltree = troot;
			return true; 
		}
		if(root->lchild()) r=Right_Search(root->lchild(),troot->lchild,p);
		else 
		{
			r = root;
			rtree = troot;
		}
		if(root == root->minimum() && root->rchild()) l=Left_Search(root->rchild(),troot->rchild,p);
		else
		if(root) l=Left_Search(root,troot,p);
		else
		{
			l = root;
			ltree = troot;
		}
		if (l == r && root->parent())
			return Search(root->parent(),troot->parent,p);
		return true;
		break;}
	case 5:
		ss=new StepStruct(troot,troot->rchild,sit,2);
		stepstruct.push_back(ss);
		if (root->rchild()) //добавил
			return Search(root->rchild(),troot->rchild,p);
		else
			if (l != NULL && r == l)
			{
				l = NULL;
				l = Left_Search(root,troot,p);
				return true;
			}
			else
			if (root->lchild())
				return Search(root->lchild(),troot->lchild,p);
			else
				return Search(root->rchild(),troot->rchild,p);

		break;
	case 6:
		if(root->rchild()) l=Left_Search(root->rchild(),troot->rchild,p);
		else
		{
			l = root;
			ltree = troot;
		}
		if(root == root->minimum() && root->lchild()) r=Right_Search(root->lchild(),troot->lchild,p);
		else
		if(root)r=Right_Search(root,troot,p);
		else 
		{
			r = root;
			rtree = troot;
		}
		if (l == r && root->parent())
			return Search(root->parent(),troot->parent,p);
		return true;
		break;
	case 7:
		ss=new StepStruct(troot,troot->lchild,sit,2);
		stepstruct.push_back(ss);
		if (root->lchild()) //добавил
			return Search(root->lchild(),troot->lchild,p);
		else
			if (l != NULL && r == l)
			{
				l = NULL;
				l = Left_Search(root,troot,p);
				return true;
			}
			else
			if (root->rchild())
				return Search(root->rchild(),troot->rchild,p);
			else
				if (RST.getRoot()->getVal()->getX() == RST.getRoot()->minimum()->getVal()->getX() && RST.getRoot()->minimum()->getVal()->getX() == p.x)
				{
					t_TreeIter it = RST.begin();
					TTree *tmpTree = troot->minimum();
					TTree *maxTree,*minTree;
					int diffMin = 10000;
					int diffMax = 0;
					RandomizeNode<TPoint> *numMin, *numMax;
					try
					{
						for (int i = 0; i < RST.size(); i++)
						{
							int tempDiff = abs((*it)->getVal()->getY() - p.y);
							if (tempDiff < diffMin)
							{
								diffMin = tempDiff;
								numMin = *it;
								minTree = tmpTree;
							}
							if (tempDiff > diffMax)
							{
								diffMax = tempDiff;
								numMax = *it;
								maxTree = tmpTree;
							}
							++it;
							tmpTree = tmpTree->next;
						}
					}
					catch(treeException& ex)
					{
						AutoSave(true);
						AfxMessageBox(ex.get_comment());
						return NULL;
					}			

					r = numMin;
					rtree = minTree;
					l = numMax;
					ltree = maxTree;
					return true; 
				}
				else
				if (RST.getRoot()->getVal()->getY() == RST.getRoot()->minimum()->getVal()->getY() && RST.getRoot()->minimum()->getVal()->getY() == p.y)
				{
					t_TreeIter it = RST.begin();
					TTree *tmpTree = troot->minimum();
					TTree *maxTree,*minTree;
					int diffMin = 10000;
					int diffMax = 0;
					RandomizeNode<TPoint> *numMin,*numMax;
					try
					{
						for (int i = 0; i < RST.size(); i++)
						{
							int tempDiff = abs((*it)->getVal()->getX() - p.x);
							if (tempDiff < diffMin)
							{
								diffMin = tempDiff;
								numMin = *it;
								minTree = tmpTree;
							}
							if (tempDiff > diffMax)
							{
								diffMax = tempDiff;
								numMax = *it;
								maxTree = tmpTree;
							}
							++it;
							tmpTree = tmpTree->next;
						}
					}
					catch(treeException& ex)
					{
						AutoSave(true);
						AfxMessageBox(ex.get_comment());
						return NULL;
					}			

					r = numMin;
					rtree = minTree;
					l = numMax;
					ltree = maxTree;
					return true; 
				}
				else
					return Search(root->lchild(),troot->lchild,p);
		break;
	case 8:
		if (RST.size() == 2)
		{
			r = root;
			rtree = troot;
			l = Left_Search(root->lchild(),troot->lchild,p);
			return true; 
		}
		if(root->lchild()) l=Left_Search(root->lchild(),troot->lchild,p);
		else 
		{
			l = root;
			ltree = troot;
		}
		if (RST.getRoot()->getVal()->getX() == RST.getRoot()->minimum()->getVal()->getX() && RST.getRoot()->minimum()->getVal()->getX() == p.x)
		{
			t_TreeIter it = RST.begin();
			TTree *tmpTree = troot->minimum();
			TTree *maxTree,*minTree;
			int diffMin = 10000;
			int diffMax = 0;
			RandomizeNode<TPoint> *numMin, *numMax;
			try
			{
				for (int i = 0; i < RST.size(); i++)
				{
					int tempDiff = abs((*it)->getVal()->getY() - p.y);
					if (tempDiff < diffMin)
					{
						diffMin = tempDiff;
						numMin = *it;
						minTree = tmpTree;
					}
					if (tempDiff > diffMax)
					{
						diffMax = tempDiff;
						numMax = *it;
						maxTree = tmpTree;
					}
					++it;
					tmpTree = tmpTree->next;
				}
			}
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return NULL;
			}			
			r = numMin;
			rtree = minTree;
			l = numMax;
			ltree = maxTree;
			return true; 
		}
		else
		if (RST.getRoot()->getVal()->getY() == RST.getRoot()->minimum()->getVal()->getY() && RST.getRoot()->minimum()->getVal()->getY() == p.y)
		{
			t_TreeIter it = RST.begin();
			TTree *tmpTree = troot->minimum();
			TTree *maxTree,*minTree;
			int diffMin = 10000;
			int diffMax = 0;
			RandomizeNode<TPoint> *numMin,*numMax;
			try
			{
				for (int i = 0; i < RST.size(); i++)
				{
					int tempDiff = abs((*it)->getVal()->getX() - p.x);
					if (tempDiff < diffMin)
					{
						diffMin = tempDiff;
						numMin = *it;
						minTree = tmpTree;
					}
					if (tempDiff > diffMax)
					{
						diffMax = tempDiff;
						numMax = *it;
						maxTree = tmpTree;
					}
					++it;
					tmpTree = tmpTree->next;
				}
			}
			catch(treeException& ex)
			{
				AutoSave(true);
				AfxMessageBox(ex.get_comment());
				return NULL;
			}			
			r = numMin;
			rtree = minTree;
			l = numMax;
			ltree = maxTree;
			return true; 
		}

		if(root == root->minimum() && root->rchild()) r=Right_Search(root->rchild(),troot->rchild,p);
		else
		if(root)r=Right_Search(root,troot,p);
		else 
		{
			r = root;
			rtree = troot;
		}
		if (l == r && root->parent())
			return Search(root->parent(),troot->parent,p);
		return true;
		break;
	}
	}
	catch(...){AfxMessageBox("Ошибка при поиске опорных точек");}

}

/** Определение ситуации */
int CCHRealTimeView::Situation(RandomizeNode<TPoint> *m, RandomizeNode<TPoint> *M,CPoint p)
{
	try{
	int sit;
	bool a_convex;
	bool m_convex;
	bool M_convex;
	bool m_abutment;
	bool M_abutment;
	CPoint pm,pM;

	pm.x=m->getVal()->getX();
	pm.y=m->getVal()->getY();
	pM.x=M->getVal()->getX();
	pM.y=M->getVal()->getY();

	if (m == M)
	{
		CPoint M_old;
		M_old.x=M->parent()->getVal()->getX();
		M_old.y=M->parent()->getVal()->getY();

		a_convex=IsConvexAngle(pm,M_old,p);
	}
	else
		a_convex=IsConvexAngle(pm,pM,p);
	
	CPoint v1,v2;
	RST.setWin(m);
	v1.x=RST.roundprev()->getX();
	v1.y=RST.roundprev()->getY();
	v2.x=RST.roundnext()->getX();
	v2.y=RST.roundnext()->getY();

	if ((pm.x == v1.x) && (pm.x == v2.x) && (p.x != pm.x) && (p.y < pm.y))
	{
		t_TreeIter it = RST.find(m->getVal());
		try
		{
			while (((*it)->getVal()->getX() == pm.x) && ((*it)->next()->getVal() != m->getVal()))
				++it;
		}
		catch(treeException& ex)
		{
			AutoSave(true);
			AfxMessageBox(ex.get_comment());
			return NULL;
		}			
		if ((((*it)->getVal()->getX() > pm.x) && (p.x > pm.x)) ||(((*it)->getVal()->getX() < pm.x) && (p.x < pm.x)))
		{
			m_convex = 0;
			m_abutment = 0;
		}
		else
		if ((((*it)->getVal()->getX() > pm.x) && (p.x < pm.x)) ||(((*it)->getVal()->getX() < pm.x) && (p.x > pm.x)))
		{
			m_convex = 1;
			m_abutment = 0;
		}
		else
		if (p.y < pm.y)
		{	
			m_convex=1;
			m_abutment=IsAbutment(v1,pm,v2,p);
		}
	}
	else
	if ((pm.y == v1.y) && (pm.y == v2.y) && (p.y != pm.y))
	{
		t_TreeIter it = RST.find(m->getVal());
		try
		{
			while (((*it)->getVal()->getY() == pm.y) && ((*it)->next()->getVal() != m->getVal()))
				++it;
		}
		catch(treeException& ex)
		{
			AutoSave(true);
			AfxMessageBox(ex.get_comment());
			return NULL;
		}			
		if ((((*it)->getVal()->getY() > pm.y) && (p.y > pm.y)) ||(((*it)->getVal()->getY() < pm.y) && (p.x < pm.x)))
		{
			m_convex = 0;
			m_abutment = 0;
		}
		else
		if ((((*it)->getVal()->getY() > pm.y) && (p.y < pm.y)) ||(((*it)->getVal()->getY() < pm.y) && (p.y > pm.y)))
		{
			m_convex = 1;
			m_abutment = 0;
		}
		else
		if  (p.x < pm.x)		
		{
			m_convex=1;
			m_abutment=IsAbutment(v1,pm,v2,p);
		}
	}
	else
	{	
		m_convex=IsConvex(v1,pm,v2,p);
		m_abutment=IsAbutment(v1,pm,v2,p);
	}
	RST.setWin(M);
	v1.x=RST.roundprev()->getX();
	v1.y=RST.roundprev()->getY();
	v2.x=RST.roundnext()->getX();
	v2.y=RST.roundnext()->getY();

	if ((pM.x == v1.x) && (pM.x == v2.x) && (pM.x != p.x))
	{
		t_TreeIter it = RST.find(M->getVal());
		try
		{
			while (((*it)->getVal()->getX() == pM.x) && ((*it)->next()->getVal() != M->getVal()))
				++it;
		}
		catch(treeException& ex)
		{
			AutoSave(true);
			AfxMessageBox(ex.get_comment());
			return NULL;
		}			
		if ((((*it)->getVal()->getX() > pM.x) && (p.x > pM.x)) ||(((*it)->getVal()->getX() < pM.x) && (p.x < pm.x)))
		{
			M_convex = 0;
			M_abutment = 0;
		}
		else
		if ((((*it)->getVal()->getX() > pM.x) && (p.x < pM.x)) ||(((*it)->getVal()->getX() < pM.x) && (p.x > pM.x)))
		{
			M_convex = 1;
			M_abutment = 0;
		}
		else
		if (p.y < pM.y)
		{	
			M_convex=1;
			M_abutment=IsAbutment(v1,pM,v2,p);
		}
	}
	else
	if ((pM.y == v1.y) && (pM.y == v2.y) && (pM.y != p.y))
	{
		t_TreeIter it = RST.find(M->getVal());
		try
		{
			while (((*it)->getVal()->getY() == pM.y) && ((*it)->next()->getVal() != M->getVal()))
				++it;
		}
		catch(treeException& ex)
		{
			AutoSave(true);
			AfxMessageBox(ex.get_comment());
			return NULL;
		}			
		if ((((*it)->getVal()->getY() > pM.y) && (p.y > pM.y)) ||(((*it)->getVal()->getY() < pM.y) && (p.x < pM.x)))
		{
			M_convex = 0;
			M_abutment = 0;
		}
		else
		if ((((*it)->getVal()->getY() > pM.y) && (p.y < pM.y)) ||(((*it)->getVal()->getY() < pM.y) && (p.y > pM.y)))
		{
			M_convex = 1;
			M_abutment = 0;
		}
		else
		if (p.x < pM.x)
		{	
			M_convex=1;
			M_abutment=IsAbutment(v1,pM,v2,p);
		}
	}
	else
	{	
		M_convex=IsConvex(v1,pM,v2,p);
		M_abutment=IsAbutment(v1,pM,v2,p);
	}
	if (a_convex)							//alpha - выпуклый
	{
		if(!m_convex && !m_abutment){		//m - вогнутая
			if(!M_convex && !M_abutment) {	//M - вогнутая
				sit=1;
			}
			else {							//M - невогнутая
				sit=2;
			}
		}
		else {								//m - невогнутая
			if(M_convex && !M_abutment) {	//M - выпуклая
				sit=3;
			}
			else {							//M - невыпуклая
				sit=4;
			}	
		}
	}
	else									//alpha - вогнутый
	{
		if(m_convex && !m_abutment){		//m - выпуклая
			if(M_convex && !M_abutment) {	//M - выпуклая
				sit=5;
			}
			else {							//M - невыпуклая
				sit=6;
			}
		}
		else {								//m - невыпуклая
			if(!M_convex && !M_abutment) {	//M - вогнутая
				sit=7;
			}
			else {							//M - невогнутая
				sit=8;
			}	
		}
	}
	return sit;
	}
	catch(...) {AfxMessageBox("Ошибка при определении ситуации!");}
}


/** Открытие файла */
void CCHRealTimeView::OnFileOpen() 
{
  CFileDialog fileDlg(TRUE);
  CString str("Точки (.din)"); str += (TCHAR)NULL; str+="*.din"; str += (TCHAR)NULL; 
  fileDlg.m_ofn.lpstrFilter = str;
  fileDlg.m_ofn.nFilterIndex = 1;
  fileDlg.m_ofn.lpstrDefExt = "din";

  TCHAR strName[_MAX_PATH];

  strName[0] = (TCHAR)NULL;
  fileDlg.m_ofn.lpstrFile = strName;
  

  if (fileDlg.DoModal() == IDOK)
  {
	Clear();
	CFile serializeFile;
	if (!serializeFile.Open(strName, CFile::modeRead))
		return;
	CArchive archive(&serializeFile, CArchive::load);

	CSerialization sg;
	sg.Serialize(archive);
	OpenPoints.clear();
	if (sg.IsFileCorrect())
	{
		OpenPoints = sg.getPoints();
	}

	Opening=true;
	OpenNum=0;
	SetTimer(ID_OPENING,50,NULL);
	Invalidate();

	archive.Close();
	serializeFile.Close();
 }
	
}


/** Сохранение файла */
void CCHRealTimeView::OnFileSave() 
{
  CFileDialog fileDlg(FALSE);
  CString str("Точки (.din)"); str += (TCHAR)NULL; str+="*.din"; str += (TCHAR)NULL; 
  fileDlg.m_ofn.lpstrFilter = str;
  fileDlg.m_ofn.nFilterIndex = 1;
  fileDlg.m_ofn.lpstrDefExt = "din";

  TCHAR strName[_MAX_PATH];

  strName[0] = (TCHAR)NULL;
  fileDlg.m_ofn.lpstrFile = strName;
  
  if (fileDlg.DoModal() == IDOK)
  {
	CFile serializeFile;
	if (!serializeFile.Open(strName, CFile::modeCreate | CFile::modeWrite )) 
		return;
	CArchive archive(&serializeFile, CArchive::store);
	// установка параметров для сериализации
	CSerialization sg;
	sg.SetParams(Points);
	// сериализация
	sg.Serialize(archive);

	archive.Close();
	serializeFile.Close();
  }	
}


void CCHRealTimeView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	
	CView::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CCHRealTimeView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	
	CView::OnChar(nChar, nRepCnt, nFlags);
}

void CCHRealTimeView::OnInitialUpdate()
{
	CView::OnInitialUpdate();
	CSize sizeTotal(20000,30000);
	CSize sizePage(sizeTotal.cx/2,sizeTotal.cy/2);
	CSize sizeLine(sizeTotal.cx/50,sizeTotal.cy/50);
}

/** Генерация точек */
CPoint CCHRealTimeView::Rovn(int Mx, int My, double sigmaX, double sigmaY)
{
	CPoint p;
    double ScaleX=(double)ClientPoints.Width()/(double)DefaultClientPointsWidth;
	double ScaleY=(double)ClientPoints.Height()/(double)DefaultClientPointsHeight;
	if (m_bCenterGenerating)
	{
       
	   int f=abs(rand() % 10);
	   f++;
	   int X=Mx-30;
	   int Y=My-30;
	   int X1=(Mx-30)/f;
	   int Y1=(My-30)/f;
	   int zn=abs(rand() % 10);
	   if (zn>=3) 
		   zn=1;
	   else zn=-1;
	   p.x=X + zn*abs(rand() % X1);
       p.y=Y + zn*abs(rand() % Y1);
	   


	p.x/=ScaleX;
	p.y/=ScaleY;
	}
	else
	if (m_bRectGenerating)
	{
		p.x=abs(rand() % Mx*2 - 30);
		p.y=abs(rand() % My*2 - 30);
		p.x/=ScaleX;
		p.y/=ScaleY;
	}
	else 
		if (m_bValueGenerating)
		{
			int X=Mx-15;
			int Y=My-15;
			if (Mx>My)
				Mx=My;
			Mx-=15;
			
			int dr=abs(rand() % (int)(((m_iCurrR*(m_iWid+1))/100)+1))-abs(rand() % (int)(((m_iCurrR*(m_iWid+1))/100)+1));
			if ((m_iCurrR - m_iCurrR*m_iWid/100 + dr) > m_iMaxR) /*Mxx*/m_iCurrR=/*Mx*/m_iMaxR-dr;
			double ygol=(double)(rand() % 700)/100.0;
			p.x=X+(m_iCurrR - m_iCurrR*m_iWid/100 + dr)*cos(ygol);
			p.y=Y+(m_iCurrR - m_iCurrR*m_iWid/100 + dr)*sin(ygol);
			
			m_iCurrR+=m_iStep;

			p.x/=ScaleX;
			p.y/=ScaleY;
		}
	return p;
}



void CCHRealTimeView::OnUpdateGenerateRect(CCmdUI* pCmdUI) 
{
	if (m_bRectGenerating)
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);

}

void CCHRealTimeView::OnUpdateGenerateCenter(CCmdUI* pCmdUI) 
{
	if (m_bCenterGenerating)
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);
	
}

void CCHRealTimeView::OnGenerateCenter() 
{
	if (!generating && !m_bPauseIsPress)
	{
		Generate();
		generating=true;
		m_bCenterGenerating = true;
		m_bValueGenerating = false;
		m_bRectGenerating = false;
	}
	else
	{
		m_bCenterGenerating = false;
		m_bRectGenerating = false;
		m_bValueGenerating = false;
		Generate();
	}
}

void CCHRealTimeView::OnGenerateRect() 
{
	// TODO: Add your command handler code here
/*ref*/		if (generating || m_bPauseIsPress)
	{
		m_bCenterGenerating = false;
		m_bRectGenerating = false;
		m_bValueGenerating = false;
/*ref*/			if (!m_bPauseIsPress)
			Generate();
/*ref*/			else
/*ref*/			{
/*ref*/				generating = false;
/*ref*/				m_bPauseIsPress = false;
/*ref*/			}
	}
	else
	{
		Generate();
		generating=true;
		m_bValueGenerating = false;
		m_bCenterGenerating = false;
		m_bRectGenerating = true;
	}
}

void CCHRealTimeView::OnUpdateGenerateCenterTool(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_bCenterGenerating)
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);
}

void CCHRealTimeView::OnUpdateGenerateRectTool(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_bRectGenerating)
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);
	
}

void CCHRealTimeView::LeftTree() 
{
	if 	(!CurrNode) CurrNode=RST.getRoot();
	else
	if (CurrNode->lchild())
		{	CurrNode=CurrNode->lchild();
			DrawTree();
		}
	
}

void CCHRealTimeView::RightTree() 
{
if 	(!CurrNode) CurrNode=RST.getRoot();
	else
	if (CurrNode->rchild())
		{	CurrNode=CurrNode->rchild();
			DrawTree();
		}	
}

void CCHRealTimeView::UpTree() 
{
if 	(!CurrNode) CurrNode=RST.getRoot();
	else
	if (CurrNode->parent())
		{	CurrNode=CurrNode->parent();
			DrawTree();
		}	
}

void CCHRealTimeView::GoRoot() 
{
	CurrNode=RST.getRoot();
	DrawTree();
	
}

void CCHRealTimeView::OnGenerateValueTool() 
{
	// TODO: Add your command handler code here
/*ref*/	if (generating|| m_bPauseIsPress)
	{
		m_bCenterGenerating = false;
		m_bRectGenerating = false;
		m_bValueGenerating = false;
/*ref*/			if (!m_bPauseIsPress)
			Generate();
/*ref*/			else
/*ref*/			{
/*ref*/				generating = false;
/*ref*/				m_bPauseIsPress = false;
/*ref*/			}
	}
	else
	{
		CRingGenerate *crg = new CRingGenerate(m_iMinR,m_iMaxR,m_iWid,m_iStep,m_iNumPoints);
		if (crg->DoModal() == IDOK)
		{	
			m_iMinR = crg->m_min;
			m_iMaxR = crg->m_max;
			m_iWid = crg->m_tolsh;
			m_iStep = crg->m_prir;
			m_iNumPoints = crg->m_poiints;
			m_iCurrR = m_iMinR;

			Generate();
			generating=true;
			m_bCenterGenerating = false;
			m_bRectGenerating = false;
			m_bValueGenerating = true;
		}	
		delete crg;
	}
}

void CCHRealTimeView::OnUpdateGenerateValueTool(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_bValueGenerating)
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);
}

void CCHRealTimeView::OnPriority() 
{
	// TODO: Add your command handler code here
	m_bPriority = !m_bPriority;
	if (!Animation)
		DrawTree();
}

void CCHRealTimeView::OnUpdatePriority(CCmdUI* pCmdUI) 
{
	if (m_bPriority)
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);
}

void CCHRealTimeView::OnSituation() 
{
	// TODO: Add your command handler code here
	m_bSituation = !m_bSituation;
	OnPaint2();
}

void CCHRealTimeView::OnUpdateSituation(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_bSituationEnabled)
		pCmdUI->Enable();
	else
		pCmdUI->Enable(false);
	if (m_bSituation)
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);
}

void CCHRealTimeView::OnUpdateGo(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (Animation)	
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);
}

void CCHRealTimeView::OnGenerateValue() 
{
	// TODO: Add your command handler code here

/*ref*/	if (generating || m_bPauseIsPress)
	{
		m_bCenterGenerating = false;
		m_bRectGenerating = false;
		m_bValueGenerating = false;
/*ref*/		if (!m_bPauseIsPress)
			Generate();
/*ref*/		else
/*ref*/		{
/*ref*/			generating = false;
/*ref*/			m_bPauseIsPress = false;
/*ref*/		}
	}
	else
	{
		CRingGenerate *crg = new CRingGenerate(m_iMinR,m_iMaxR,m_iWid,m_iStep,m_iNumPoints);
		if (crg->DoModal() == IDOK)
		{	
			m_iMinR = crg->m_min;
			m_iMaxR = crg->m_max;
			m_iWid = crg->m_tolsh;
			m_iStep = crg->m_prir;
			m_iNumPoints = crg->m_poiints;
			m_iCurrR = m_iMinR;

			Generate();
			generating=true;
			m_bCenterGenerating = false;
			m_bRectGenerating = false;
			m_bValueGenerating = true;
		}	
		delete crg;
	}
}

// автосохранение точек 
void CCHRealTimeView::AutoSave(bool wasErr)
{
	CFile serializeFile;
	if (!serializeFile.Open("autosave.din", CFile::modeCreate | CFile::modeWrite )) 
		return;
	CArchive archive(&serializeFile, CArchive::store);
	// установка параметров для сериализации
	CSerialization sg;
	sg.SetParams(Points,wasErr);
	// сериализация
	sg.Serialize(archive);

	archive.Close();
	serializeFile.Close();
}

// загрузка автосохраненных точек
void CCHRealTimeView::AutoLoad()
{
	CFile serializeFile;
	if (!serializeFile.Open("autosave.din", CFile::modeRead))
		return;
	CArchive archive(&serializeFile, CArchive::load);

	CSerialization sg;
	sg.Serialize(archive);
	int k = IDYES;
	if (sg.WasError())
	{
		if (AfxMessageBox("Во время предыдущего сеанса работы, возможно, произошла ошибка.\nВосстановить предыдущее состояние?",MB_YESNO|MB_ICONQUESTION) == IDYES)
		{
			OpenPoints.clear();
			if (sg.IsFileCorrect())
			{
				OpenPoints = sg.getPoints();
			}
			Opening=true;
			OpenNum=0;
			SetTimer(ID_OPENING,500,NULL);
			Invalidate();
		}
	}

	archive.Close();
	serializeFile.Close();
}


void CCHRealTimeView::OnUpdateGenerateValue(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_bValueGenerating)
		pCmdUI->SetCheck();
	else
		pCmdUI->SetCheck(false);
	
}

void CCHRealTimeView::OnCHHelp() 
{
	// TODO: Add your command handler code here
	CCHHelp dlg;
	dlg.DoModal();
}


void CCHRealTimeView::OnUpdateStep(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (Animation)
		pCmdUI->Enable();
	else
		pCmdUI->Enable(false);
	
}


void CCHRealTimeView::OnUpdateTree(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (!Animation)
		pCmdUI->Enable();
	else
		pCmdUI->Enable(false);
	
}

void CCHRealTimeView::SaveToBmp()
{
// TODO: Add your command handler code here
	CFileDialog fdlg(FALSE,"BMP","*.BMP",OFN_OVERWRITEPROMPT,"Графические файлы (BMP)\0");		// select filename
	if(fdlg.DoModal() != IDOK) return;			// get filename to write to
	MyName=fdlg.GetPathName();
	this->SetTimer(ID_SAVE,100,NULL);
}

void CCHRealTimeView::SaveToBmpFile(CString MyName)
{
		BITMAPINFO bmi;        // used to define the bitmap-format we want to create
        BITMAPFILEHEADER        bfh; // used to define the BMP-file-format
        HBITMAP         hbm=0;// handle to the newly created bitmap
        HBITMAP ohbm;
        CClientDC hdc(this); // screen-DC to take image from
        HDC mhdc=0; // screen-compatible DC for the new bitmap
        int width,height;                        // screen-dimension
        BYTE *imagedata;
        struct tagRECT Rr;
        GetClientRect(&Rr);
        width=Rr.right-Rr.left;
        height=Rr.bottom-Rr.top;
// now let's prepare the bitmap-format
        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // the size helps to distinguish b/w diff.versions
        bmi.bmiHeader.biWidth = width;
        bmi.bmiHeader.biHeight = height;
        bmi.bmiHeader.biPlanes = 1; // has to be 1
        bmi.bmiHeader.biBitCount = 16; // as we want true-color
        bmi.bmiHeader.biCompression = BI_RGB; // no compression
        bmi.bmiHeader.biSizeImage = (((width * 16 + 31) & ~31) >> 3) * height;        // lines have to be DWORD aligned
        bmi.bmiHeader.biXPelsPerMeter = 0;
        bmi.bmiHeader.biYPelsPerMeter = 0; // could be used to describe physical dimension
        bmi.bmiHeader.biClrImportant = 0;
        bmi.bmiHeader.biClrUsed = 0; // we are not using palette
// enough information to create a DIBSECTION in memory
        if(!(hbm = ::CreateDIBSection(hdc,&bmi,DIB_RGB_COLORS,(void**)&imagedata,0,0))) throw 0;
        if(!(mhdc = ::CreateCompatibleDC(hdc))) throw 0;        // create a screen-compatible DC
        ohbm = (HBITMAP)::SelectObject(mhdc,hbm);// select the new bitmap into the compatible DC
        if(!::BitBlt(mhdc,0,0,width,height,hdc,0,0,SRCCOPY)) throw 0;        // copy the screen-image into the bitmap
        ::SelectObject(mhdc,ohbm); ::DeleteDC(mhdc); mhdc = 0;        // the compatible DC is no longer needed
// prepare the BITMAPFILEHEADER to save the image
        ZeroMemory(&bfh,sizeof(BITMAPFILEHEADER)); // clear the unused entries
        bfh.bfType = *(WORD*)"BM"; // BMP-Files stat with "BM"
        bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmi.bmiHeader.biSizeImage;        // the complete file-size
        bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// now we write the whole stuff to file
        CFile        fo(MyName,CFile::modeCreate|CFile::modeWrite);
        fo.Write(&bfh,sizeof(BITMAPFILEHEADER));                // write the BITMAPFILEHEADER
        fo.Write(&bmi,sizeof(BITMAPINFOHEADER));                // write the BITMAPINFOHEADER
        fo.Write(imagedata,bmi.bmiHeader.biSizeImage);        // write the image data
        if(mhdc) ::DeleteDC(mhdc);
        if(hbm) ::DeleteObject(hbm);
        if(hdc) ::ReleaseDC(0,hdc);
}




/*
void CCHRealTimeView::SaveToBmp() 
{
	// TODO: Add your command handler code here
	
}
*/

/*int CCHRealTimeView::Vid(CP)
{

}
*/


/*ref вся функция*/
void CCHRealTimeView::OnPause() 
{
	// TODO: Add your command handler code here
	if (generating)
	{
		generating = false;
		KillTimer(ID_GENERATING);
	}
	else
	{
		generating = true;
		SetTimer(ID_GENERATING,500,NULL);
	}
	m_bPauseIsPress = !m_bPauseIsPress;
}

/*ref вся функция*/
void CCHRealTimeView::OnUpdatePause(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if(m_bValueGenerating || m_bRectGenerating)
		pCmdUI->Enable(true);
	else
		pCmdUI->Enable(false);
	if ((m_bValueGenerating || m_bRectGenerating) && !generating)
		pCmdUI->SetCheck(true);
	else
		pCmdUI->SetCheck(false);


}
}
Соседние файлы в папке Source