Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Построение выпуклой оболочки в режиме реального времени / Source / CHRealTimeView
.cpp// 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