Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Диаметр множества / src / DiameterView
.cpp// DiameterView.cpp : implementation of the CDiameterView class
//
#include "stdafx.h"
#include "Diameter.h"
#include "DiameterDoc.h"
#include "DiameterView.h"
#include <fstream>
#include <cstdlib>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int DRAW_POSITION=false;
int DELETE_POSITION=false;
int CH_BUILD=false;
int BUILD_CH=false;
int BUILD_CH_ENABLED=false;
int GENERATE=false;
TNode *Id1=0;
int GLOBAL_XXX=0,GLOBAL_YYY=0;
int NEXT_ENABLED=false;
int ALL_ENABLED=false;
int FIRST_ENABLED=false;
int USER_ENABLED=false;
int USER=false;
int VERT_NUM=false;
int DRAW_LINES=false;
int NumPare=0;
//Vars for Algotithm
int Step=0;
int iter=0;
TNode *NodeP=0;
TNode *NodeQ=0;
TNode *NodeP1=0;
TNode *NodeQ1=0;
TNode *NodeP0=0;
TNode *NodeQ0=0;
TNode *DiamNodeP=0;
TNode *DiamNodeQ=0;
TNode *UserNodeP=0;
TNode *UserNodeQ=0;
float MaxDiameter=0;
struct Peer{
TNode* P;
TNode* Q;
};
typedef std::list<Peer> MyList;
MyList List;
/////////////////////////////////////////////////////////////////////////////
// CDiameterView
IMPLEMENT_DYNCREATE(CDiameterView, CScrollView)
BEGIN_MESSAGE_MAP(CDiameterView, CScrollView)
//{{AFX_MSG_MAP(CDiameterView)
ON_WM_LBUTTONUP()
ON_COMMAND(ID_ADD_POSITION, OnAddPosition)
ON_UPDATE_COMMAND_UI(ID_ADD_POSITION, OnUpdateAddPosition)
ON_COMMAND(ID_DELETE_POSITION, OnDeletePosition)
ON_UPDATE_COMMAND_UI(ID_DELETE_POSITION, OnUpdateDeletePosition)
ON_COMMAND(ID_BUILD_CH, OnBuildCh)
ON_UPDATE_COMMAND_UI(ID_BUILD_CH, OnUpdateBuildCh)
ON_COMMAND(ID_FILE_NEW, OnFileNew)
ON_COMMAND(ID_SAVE_BMP, OnSaveBmp)
ON_COMMAND(ID_GENERATE_BTN, OnGenerateBtn)
ON_UPDATE_COMMAND_UI(ID_GENERATE_BTN, OnUpdateGenerateBtn)
ON_COMMAND(ID_SCALE_MAX, OnScaleMax)
ON_UPDATE_COMMAND_UI(ID_SCALE_MAX, OnUpdateScaleMax)
ON_COMMAND(ID_SCALE_MIN, OnScaleMin)
ON_UPDATE_COMMAND_UI(ID_SCALE_MIN, OnUpdateScaleMin)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(ID_FILE_SAVE, OnFileSave)
ON_COMMAND(ID_ALGORITM_NEXT, OnAlgoritmNext)
ON_UPDATE_COMMAND_UI(ID_ALGORITM_NEXT, OnUpdateAlgoritmNext)
ON_COMMAND(ID_ALGORITM_ALL, OnAlgoritmAll)
ON_UPDATE_COMMAND_UI(ID_ALGORITM_ALL, OnUpdateAlgoritmAll)
ON_COMMAND(ID_ALGORITM_FIRST, OnAlgoritmFirst)
ON_UPDATE_COMMAND_UI(ID_ALGORITM_FIRST, OnUpdateAlgoritmFirst)
ON_COMMAND(ID_VERT_NUM, OnVertNum)
ON_UPDATE_COMMAND_UI(ID_VERT_NUM, OnUpdateVertNum)
ON_COMMAND(ID_ALGORITM_USER, OnAlgoritmUser)
ON_UPDATE_COMMAND_UI(ID_ALGORITM_USER, OnUpdateAlgoritmUser)
ON_COMMAND(ID_LOG_SHOW, OnLogShow)
ON_UPDATE_COMMAND_UI(ID_LOG_SHOW, OnUpdateLogShow)
ON_COMMAND(ID_BUTTON_ALG, OnButtonAlg)
ON_COMMAND(ID_DRAW_LINES, OnDrawLines)
ON_UPDATE_COMMAND_UI(ID_DRAW_LINES, OnUpdateDrawLines)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDiameterView construction/destruction
CDiameterView::CDiameterView()
{
// TODO: add construction code here
}
CDiameterView::~CDiameterView()
{
}
BOOL CDiameterView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
lDialog.Create(IDD_DIALOG1);
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDiameterView drawing
void CDiameterView::OnDraw(CDC* pDC)
{
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
DiameterIterator<TNode*> p = pDoc->Diameter.begin();
while (!( p==pDoc->Diameter.end()))
{
TNode* node = (*p);
DrawPosition(pDC,node);
++p;
}
if (Step==4)
{
MyList::iterator t = List.begin();
while (!(t==List.end()))
{
Peer MyPeer = (*t);
DrawPeer(pDC,MyPeer.P,MyPeer.Q);
++t;
}
}
if ((Step>=1)&&(Step<=4)) DrawDiameter(pDC,1);
if ((Step>=1)&&(Step<=2)) DrawDiameter(pDC,2);
if ((Step>=0)&&(Step<=2)) DrawDiameter(pDC,3);
}
/////////////////////////////////////////////////////////////////////////////
// CDiameterView diagnostics
#ifdef _DEBUG
void CDiameterView::AssertValid() const
{
CScrollView::AssertValid();
}
void CDiameterView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CDiameterDoc* CDiameterView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDiameterDoc)));
return (CDiameterDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDiameterView message handlers
void CDiameterView::DrawPeer(CDC* pDC, TNode *P, TNode *Q)
{
if ((P!=0)&&(Q!=0))
{
CPen *Pn=new CPen();
CPen *tmpP=0;
Pn->CreatePen(0,1,RGB(250,220,180));
tmpP=pDC->SelectObject(Pn);
pDC->MoveTo(P->GetXCoord(),P->GetYCoord());
pDC->LineTo(Q->GetXCoord(),Q->GetYCoord());
if (tmpP!=0) pDC->SelectObject(tmpP);
delete Pn;
}
}
void CDiameterView::DrawPosition(CDC* pDC, TNode *node)
{
CPen *Pn=new CPen();
CBrush *Br=new CBrush();
CPen *tmpP=0;
CBrush *tmpB=0;
int Size=3;
if (node==Id1)
{
Pn->CreatePen(0,2,RGB(0,0,0));
tmpP=pDC->SelectObject(Pn);
Br->CreateSolidBrush(RGB(255,100,100));
tmpB=pDC->SelectObject(Br);
Size=6;
}
else
{
Pn->CreatePen(0,1,RGB(0,0,255));
tmpP=pDC->SelectObject(Pn);
tmpB=(CBrush*)pDC->SelectStockObject(NULL_BRUSH);
}
pDC->Ellipse(node->GetXCoord()-Size,node->GetYCoord()-Size,
node->GetXCoord()+Size,node->GetYCoord()+Size);
if (VERT_NUM==true)
{
char ss[10];
itoa(node->GetID(),ss,10);
pDC->TextOut(node->GetXCoord()+3,node->GetYCoord()+3,ss);
}
if (CH_BUILD==true)
{
TNode *node2=0;
node2=node->GetRight();
if (node2!=0)
{
CPen *PnL=new CPen();
CPen *tmpPL=0;
PnL->CreatePen(0,1,RGB(0,0,255));
tmpPL=pDC->SelectObject(PnL);
pDC->MoveTo(node->GetXCoord(),node->GetYCoord());
pDC->LineTo(node2->GetXCoord(),node2->GetYCoord());
pDC->SelectObject(tmpPL);
delete PnL;
}
}
if (tmpP!=0) pDC->SelectObject(tmpP);
if (tmpB!=0) pDC->SelectObject(tmpB);
delete Br;
delete Pn;
}
int GetKB(TNode *p1, TNode *p2, float &k, float &b)
{
float x1=p1->GetXCoord();
float x2=p2->GetXCoord();
float y1=p1->GetYCoord();
float y2=p2->GetYCoord();
if (fabs(x2-x1)<0.0001)
{
k=0;b=x1;return 2;
} else
{
k=(y2-y1)/(x2-x1);
b=y1-k*x1;
return 1;
}
}
void CDiameterView::DrawDiameter(CDC* pDC,int Type)
{
CPen *Pn;
CBrush *Br;
CPen *tmpP=0;
CBrush *tmpB=0;
int Size=6;
if (Type==1) //текущий диаметр
{
if ((DiamNodeP==0)||(DiamNodeQ==0)) return;
Pn=new CPen();
Br=new CBrush();
Pn->CreatePen(0,1,RGB(255,50,50));
tmpP=pDC->SelectObject(Pn);
pDC->MoveTo(DiamNodeP->GetXCoord(),DiamNodeP->GetYCoord());
pDC->LineTo(DiamNodeQ->GetXCoord(),DiamNodeQ->GetYCoord());
pDC->SelectObject(tmpP);
delete Pn;Pn=new CPen();
Pn->CreatePen(0,2,RGB(0,0,0));
tmpP=pDC->SelectObject(Pn);
Br->CreateSolidBrush(RGB(0,0,255));
tmpB=pDC->SelectObject(Br);
pDC->Ellipse(DiamNodeP->GetXCoord()-Size,DiamNodeP->GetYCoord()-Size,
DiamNodeP->GetXCoord()+Size,DiamNodeP->GetYCoord()+Size);
pDC->Ellipse(DiamNodeQ->GetXCoord()-Size,DiamNodeQ->GetYCoord()-Size,
DiamNodeQ->GetXCoord()+Size,DiamNodeQ->GetYCoord()+Size);
if (tmpP!=0) pDC->SelectObject(tmpP);
if (tmpB!=0) pDC->SelectObject(tmpB);
delete Br;
delete Pn;
}else
if (Type==2) //текущая пара
{
if ((NodeP==0)||(NodeQ==0)) return;
Pn=new CPen();
Br=new CBrush();
Pn->CreatePen(0,1,RGB(50,255,50));
tmpP=pDC->SelectObject(Pn);
pDC->MoveTo(NodeP->GetXCoord(),NodeP->GetYCoord());
pDC->LineTo(NodeQ->GetXCoord(),NodeQ->GetYCoord());
//+2 перпендикулярных линии
if (DRAW_LINES==true)
{
pDC->SelectObject(tmpP);
delete Pn;Pn=new CPen();
Pn->CreatePen(0,1,RGB(220,220,220));
pDC->SelectObject(Pn);
//уравнение 1-й прямой
//y=kx+b
float k1=0,b1=0,k2=0,b2=0,k3=0,b3=0,k4=0,b4=0;
int t1=0,t2=0,t3=0,t4=0;
float k,b;
t1=GetKB(NodeP,NodeP->GetRight(),k1,b1);
t2=GetKB(NodeQ,NodeQ->GetRight(),k2,b2);
t3=GetKB(NodeP->GetLeft(),NodeP,k3,b3);
t4=GetKB(NodeQ->GetLeft(),NodeQ,k4,b4);
if (t1==1)
{
k=k1;b=b1-k1*((NodeQ->GetXCoord())-(NodeP->GetXCoord())) + ((NodeQ->GetYCoord())-(NodeP->GetYCoord()));
float y=k*(NodeQ->GetRight()->GetXCoord())+b;
if (k>=0)
{
if ( ((NodeQ->GetXCoord()<=NodeP->GetXCoord())&&(NodeQ->GetRight()->GetYCoord()<=y)) ||
((NodeQ->GetXCoord()>NodeP->GetXCoord())&&(NodeQ->GetRight()->GetYCoord()>=y)) )
{//все ок
}else {t1=t2;k1=k2;b1=b2-k2*((NodeP->GetXCoord())-(NodeQ->GetXCoord())) + ((NodeP->GetYCoord())-(NodeQ->GetYCoord()));}
}
else //if (k<=0)
{
if ( ((NodeQ->GetXCoord()<=NodeP->GetXCoord())&&(NodeQ->GetRight()->GetYCoord()>=y)) ||
((NodeQ->GetXCoord()>NodeP->GetXCoord())&&(NodeQ->GetRight()->GetYCoord()>=y)) )
{//все ок
}else {t1=t2;k1=k2;b1=b2-k2*((NodeP->GetXCoord())-(NodeQ->GetXCoord())) + ((NodeP->GetYCoord())-(NodeQ->GetYCoord()));}
}
}else
{
b=b1+(NodeQ->GetXCoord())-(NodeP->GetXCoord());
if ( ((NodeQ->GetXCoord()>=NodeP->GetXCoord())&&(NodeQ->GetRight()->GetXCoord()<=b)) ||
((NodeQ->GetXCoord()<NodeP->GetXCoord())&&(NodeQ->GetRight()->GetXCoord()>=b)) )
{}
else {t1=t2;k1=k2;b1=b2-(NodeQ->GetXCoord())-(NodeP->GetXCoord());}
}
if (t3==1)
{
k=k3;b=b3-k3*((NodeQ->GetXCoord())-(NodeP->GetXCoord())) + ((NodeQ->GetYCoord())-(NodeP->GetYCoord()));
float y=k*(NodeQ->GetLeft()->GetXCoord())+b;
if (k>=0)
{
if ( ((NodeQ->GetXCoord()<=NodeP->GetXCoord())&&(NodeQ->GetLeft()->GetYCoord()>=y)) ||
((NodeQ->GetXCoord()>NodeP->GetXCoord())&&(NodeQ->GetLeft()->GetYCoord()>=y)) )
{//все ок
}else {t3=t4;k3=k4;b3=b4-k4*((NodeP->GetXCoord())-(NodeQ->GetXCoord())) + ((NodeP->GetYCoord())-(NodeQ->GetYCoord()));}
}
else //if (k<=0)
{
if ( ((NodeQ->GetXCoord()<=NodeP->GetXCoord())&&(NodeQ->GetLeft()->GetYCoord()>=y)) ||
((NodeQ->GetXCoord()>NodeP->GetXCoord())&&(NodeQ->GetLeft()->GetYCoord()<=y)) )
{//все ок
}else {t3=t4;k3=k4;b3=b4-k4*((NodeP->GetXCoord())-(NodeQ->GetXCoord())) + ((NodeP->GetYCoord())-(NodeQ->GetYCoord()));}
}
if (NodeP->GetLeft()==NodeQ)
{t3=t4;k3=k4;b3=b4-k4*((NodeP->GetXCoord())-(NodeQ->GetXCoord())) + ((NodeP->GetYCoord())-(NodeQ->GetYCoord()));}
}else
{
b=b1+(NodeQ->GetXCoord())-(NodeP->GetXCoord());
if ( ((NodeQ->GetXCoord()>=NodeP->GetXCoord())&&(NodeQ->GetRight()->GetXCoord()<=b)) ||
((NodeQ->GetXCoord()<NodeP->GetXCoord())&&(NodeQ->GetRight()->GetXCoord()>=b)) )
{}
else {t3=t4;k3=k4;b3=b4-(NodeQ->GetXCoord())-(NodeP->GetXCoord());}
}
if (t1==1)
{
b2=-k1*((NodeQ->GetXCoord())-(NodeP->GetXCoord())) + ((NodeQ->GetYCoord())-(NodeP->GetYCoord()));
pDC->MoveTo(-100,floor(k1*(-100)+b1));
pDC->LineTo(2100,floor(k1*2100+b1));
pDC->MoveTo(-100,floor(k1*(-100)+b1+b2));
pDC->LineTo(2100,floor(k1*2100+b1+b2));
}else
{
pDC->MoveTo(floor(b1),-100);
pDC->LineTo(floor(b1),2100);
pDC->MoveTo(floor(b1-b2),-100);
pDC->LineTo(floor(b1-b2),2100);
}
if (t3==1)
{
b2=-k3*((NodeQ->GetXCoord())-(NodeP->GetXCoord())) + ((NodeQ->GetYCoord())-(NodeP->GetYCoord()));
pDC->MoveTo(-100,floor(k3*(-100)+b3));
pDC->LineTo(2100,floor(k3*2100+b3));
pDC->MoveTo(-100,floor(k3*(-100)+b3+b2));
pDC->LineTo(2100,floor(k3*2100+b3+b2));
}else
{
pDC->MoveTo(floor(b3),-100);
pDC->LineTo(floor(b3),2100);
pDC->MoveTo(floor(b3-b2),-100);
pDC->LineTo(floor(b3-b2),2100);
}
}//if (DRAW_LINES)
//*/
pDC->SelectObject(tmpP);
delete Pn;Pn=new CPen();
Pn->CreatePen(0,2,RGB(0,0,0));
pDC->SelectObject(Pn);
Br->CreateSolidBrush(RGB(0,255,0));
tmpB=pDC->SelectObject(Br);
pDC->Ellipse(NodeP->GetXCoord()-Size,NodeP->GetYCoord()-Size,
NodeP->GetXCoord()+Size,NodeP->GetYCoord()+Size);
pDC->SelectObject(tmpB);
delete Br;Br=new CBrush();
Br->CreateSolidBrush(RGB(0,255,255));
pDC->SelectObject(Br);
pDC->Ellipse(NodeQ->GetXCoord()-Size,NodeQ->GetYCoord()-Size,
NodeQ->GetXCoord()+Size,NodeQ->GetYCoord()+Size);
if (tmpP!=0) pDC->SelectObject(tmpP);
if (tmpB!=0) pDC->SelectObject(tmpB);
delete Br;
delete Pn;
}else
if (Type==3) //пара пользователя
{
if ((UserNodeP==0)&&(UserNodeQ==0)) return;
Pn=new CPen();
Br=new CBrush();
Pn->CreatePen(0,2,RGB(0,0,0));
tmpP=pDC->SelectObject(Pn);
Br->CreateSolidBrush(RGB(255,255,0));
tmpB=pDC->SelectObject(Br);
if (UserNodeP!=0)
{
pDC->Ellipse(UserNodeP->GetXCoord()-Size,UserNodeP->GetYCoord()-Size,
UserNodeP->GetXCoord()+Size,UserNodeP->GetYCoord()+Size);
}
if (UserNodeQ!=0)
{
pDC->Ellipse(UserNodeQ->GetXCoord()-Size,UserNodeQ->GetYCoord()-Size,
UserNodeQ->GetXCoord()+Size,UserNodeQ->GetYCoord()+Size);
}
if (tmpP!=0) pDC->SelectObject(tmpP);
if (tmpB!=0) pDC->SelectObject(tmpB);
delete Br;
delete Pn;
}
}
void CDiameterView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (DRAW_POSITION==true)
{
TNode *Node1=0;
try{
Node1=pDoc->Diameter.GetByXY(point.x+GLOBAL_XXX,point.y+GLOBAL_YYY,0);
}catch(DiameterError::EInvalidNodeXY eINXY)
{
Node1=0;
}
if (Node1==0)
{
TNode *Node=new TNode();
Node->SetXCoord(point.x+GLOBAL_XXX);
Node->SetYCoord(point.y+GLOBAL_YYY);
try{
pDoc->Diameter.Insert(Node);
}catch(DiameterError::EInvalidInsert eI)
{
AfxMessageBox(eI.p,16);
}
if (pDoc->Diameter.size()>2) BUILD_CH_ENABLED=true; else BUILD_CH_ENABLED=false;
char str[10];itoa(pDoc->Diameter.size(),str,10);
lDialog.mPoints=str;
lDialog.mSteps="";
lDialog.mEdit="";
lDialog.UpdateData(false);
Invalidate();
}else
{
Node1=0;
AfxMessageBox("На этом месте уже есть вершина!",16);
}
}
if (DELETE_POSITION==true)
{
TNode *Node=0;
try{
Node=pDoc->Diameter.GetByXY(point.x+GLOBAL_XXX,point.y+GLOBAL_YYY,3);
}catch(DiameterError::EInvalidNodeXY eINXY)
{
AfxMessageBox(eINXY.p,16);
Node=0;
}
if (Node!=0)
{
Id1=Node;
Invalidate();
if (AfxMessageBox("Вы уверены?",MB_YESNO+32)==IDYES)
{
try{
pDoc->Diameter.DeleteByID(Node->GetID());
}catch(DiameterError::EInvalidDelete eID)
{
AfxMessageBox(eID.p,16);
}
}
Id1=0;
char str[10];itoa(pDoc->Diameter.size(),str,10);
lDialog.mPoints=str;
lDialog.mSteps="";
lDialog.mEdit="";
lDialog.UpdateData(false);
if (pDoc->Diameter.size()>2) BUILD_CH_ENABLED=true; else BUILD_CH_ENABLED=false;
Invalidate();
}
}
if (USER==true)
{
TNode *Node=0;
try{
Node=pDoc->Diameter.GetByXY(point.x+GLOBAL_XXX,point.y+GLOBAL_YYY,3);
}catch(DiameterError::EInvalidNodeXY eINXY)
{
AfxMessageBox(eINXY.p);
Node=0;
}
if (Node!=0)
{
if (UserNodeP==0) UserNodeP=Node;
else
{
UserNodeQ=Node;
}
Invalidate();
if ((UserNodeP!=0)&&(UserNodeQ!=0)) OnAlgoritmNext();
}
}
CScrollView::OnLButtonUp(nFlags, point);
}
void CDiameterView::ResetFlags()
{
DRAW_POSITION=false;
DELETE_POSITION=false;
BUILD_CH=false;
CH_BUILD=false;
GENERATE=false;
}
void CDiameterView::OnAddPosition()
{
// TODO: Add your command handler code here
int tmp=DRAW_POSITION;
int tmp1=CH_BUILD;
ResetFlags();
ALL_ENABLED=FIRST_ENABLED=NEXT_ENABLED=USER_ENABLED=false;
NodeP=NodeQ=0;Step=0;List.clear();
if (tmp1==true) Invalidate();
DRAW_POSITION=!tmp;
}
void CDiameterView::OnUpdateAddPosition(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(DRAW_POSITION);
/*if (CH_BUILD==true) pCmdUI->Enable(false);
else pCmdUI->Enable(true);//*/
}
void CDiameterView::OnDeletePosition()
{
// TODO: Add your command handler code here
int tmp=DELETE_POSITION;
int tmp1=CH_BUILD;
ResetFlags();
ALL_ENABLED=FIRST_ENABLED=NEXT_ENABLED=USER_ENABLED=false;
NodeP=NodeQ=0;Step=0;List.clear();
if (tmp1==true) Invalidate();
DELETE_POSITION=!tmp;
}
void CDiameterView::OnUpdateDeletePosition(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(DELETE_POSITION);
/*if (CH_BUILD==true) pCmdUI->Enable(false);
else pCmdUI->Enable(true);//*/
}
void CDiameterView::OnBuildCh()
{
// TODO: Add your command handler code here
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
ResetFlags();
BUILD_CH=true;
try{
pDoc->Diameter.MakeCH();
}catch (DiameterError::EInvalidCH eCH)
{
AfxMessageBox(eCH.p,16);
}
BUILD_CH=false;
CH_BUILD=true;
NEXT_ENABLED=true;
ALL_ENABLED=true;
USER_ENABLED=true;
FIRST_ENABLED=false;
Step=0;List.clear();
NodeP=NodeQ=0;
BUILD_CH_ENABLED=true;
UserNodeP=UserNodeQ=0;USER=false;
Invalidate();
}
void CDiameterView::OnUpdateBuildCh(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(BUILD_CH);
if (BUILD_CH_ENABLED==true) pCmdUI->Enable(true);
else pCmdUI->Enable(false);
}
void CDiameterView::OnFileNew()
{
// TODO: Add your command handler code here
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDoc->Diameter.ClearDiameterCont();
ResetFlags();
ALL_ENABLED=FIRST_ENABLED=NEXT_ENABLED=USER_ENABLED=false;
NodeP=NodeQ=0;Step=0;List.clear();
Invalidate();
char str[10];itoa(pDoc->Diameter.size(),str,10);
lDialog.mPoints=str;
lDialog.mSteps="";
lDialog.mEdit="";
lDialog.UpdateData(false);
if (pDoc->Diameter.size()>2) BUILD_CH_ENABLED=true; else BUILD_CH_ENABLED=false;
}
void CDiameterView::OnSaveBmp()
{
// TODO: Add your command handler code here
BOOL WriteWindowToDIB( LPCTSTR szFile, CRect rect, CWnd *pWnd);
CRect r;
CString bitName;
CFileDialog fd(FALSE,"bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Windows bitmap|*.bmp||");
if(fd.DoModal()!=IDCANCEL)
{
bitName = fd.GetPathName();
this->GetClientRect(r);
WriteWindowToDIB((LPCTSTR)bitName,r,this);
}
}
void CDiameterView::OnGenerateBtn()
{
// TODO: Add your command handler code here
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
int tmp1=CH_BUILD;
ResetFlags();
ALL_ENABLED=FIRST_ENABLED=NEXT_ENABLED=USER_ENABLED=false;
NodeP=NodeQ=0;Step=0;List.clear();
GENERATE=true;
if (tmp1==true) Invalidate();
if (cd.DoModal()==IDOK)
{
int w=atoi(cd.mWidth);
int h=atoi(cd.mHeight);
int rg=atoi(cd.mRing);
float r=rg/100.0;
int p=atoi(cd.mPoints);
int lx=atoi(cd.mX);
int ly=atoi(cd.mY);
int t=cd.mType;
//0-кольцо, 1-прямоугольник
for (int i=0;i<p;i++)
{
TNode *node=new TNode();
//здесь генерация координат
switch (t)
{
case 0://кольцо
{
float x,y;
int isok=false;
int Num=0;
do{
Num++;
float Rmax=(w>h?w:h)/2.0;
float wD=w/(Rmax*2.0);
float hD=h/(Rmax*2.0);
float Rmin=Rmax*(1-r);
int divider=Rmax-Rmin;
if (divider==0) divider=1;
float R=(rand()%divider)+Rmin;
float A=rand()%360;
x=w/2+R*cos(A)*wD;
y=h/2+R*sin(A)*hD;
TNode *Node1=0;
try{
Node1=pDoc->Diameter.GetByXY(lx+x,ly+y,0);
}catch(DiameterError::EInvalidNodeXY eINXY)
{
Node1=0;isok=true;
}
}while ((isok==false)&&(Num<10));
if (Num<10)
{
node->SetXCoord(lx+x);
node->SetYCoord(ly+y);
pDoc->Diameter.Insert(node);
}else delete node;
break;
}
default://прямоугольник
{
float x,y;
int isok=false;
int Num=0;
do{
Num++;
x=rand()%w;
y=rand()%h;
TNode *Node1=0;
try{
Node1=pDoc->Diameter.GetByXY(lx+x,ly+y,0);
}catch(DiameterError::EInvalidNodeXY eINXY)
{
Node1=0;isok=true;
}
}while ((isok==false)&&(Num<10));
if (Num<10)
{
node->SetXCoord(lx+x);
node->SetYCoord(ly+y);
pDoc->Diameter.Insert(node);
}else delete node;
break;
}
}
}
char str[10];itoa(pDoc->Diameter.size(),str,10);
lDialog.mPoints=str;
lDialog.mSteps="";
lDialog.mEdit="";
lDialog.UpdateData(false);
if (pDoc->Diameter.size()>2) BUILD_CH_ENABLED=true; else BUILD_CH_ENABLED=false;
Invalidate();
}
GENERATE=false;
}
void CDiameterView::OnUpdateGenerateBtn(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(GENERATE);
}
void CDiameterView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
CSize s;s.cx=2000;s.cy=2000;
SetScrollSizes(1,s,s,s);
}
BOOL CDiameterView::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)
{
// TODO: Add your specialized code here and/or call the base class
CPoint cp=GetScrollPosition();
GLOBAL_XXX=cp.x;GLOBAL_YYY=cp.y;
return CScrollView::OnScroll(nScrollCode, nPos, bDoScroll);
}
void CDiameterView::OnScaleMax()
{
// TODO: Add your command handler code here
ResetFlags();
ALL_ENABLED=FIRST_ENABLED=NEXT_ENABLED=USER_ENABLED=false;
NodeP=NodeQ=0;Step=0;List.clear();
//
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDoc->Diameter.ScaleAll(2.0,2.0);
if (pDoc->Diameter.size()>2) BUILD_CH_ENABLED=true; else BUILD_CH_ENABLED=false;
Invalidate();
}
void CDiameterView::OnUpdateScaleMax(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(false);
}
void CDiameterView::OnScaleMin()
{
// TODO: Add your command handler code here
ResetFlags();
ALL_ENABLED=FIRST_ENABLED=NEXT_ENABLED=USER_ENABLED=false;
NodeP=NodeQ=0;Step=0;List.clear();
//
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDoc->Diameter.ScaleAll(0.5,0.5);
if (pDoc->Diameter.size()>2) BUILD_CH_ENABLED=true; else BUILD_CH_ENABLED=false;
Invalidate();
}
void CDiameterView::OnUpdateScaleMin(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(false);
}
int CDiameterView::Compare(CDiameterDoc* pDoc, TNode* p, TNode* q) //сравнение треугольников
{
float p_pn=pDoc->Diameter.GetDistance(p,(p->GetRight()));
float pn_qn=pDoc->Diameter.GetDistance((p->GetRight()),(q->GetRight()));
float p_qn=pDoc->Diameter.GetDistance(p,(q->GetRight()));
float pn_q=pDoc->Diameter.GetDistance((p->GetRight()),q);
float p_q=pDoc->Diameter.GetDistance(p,q);
float p1=(p_pn+pn_qn+p_qn)/2.0;
float p2=(p_pn+pn_q+p_q)/2.0;
float s1=sqrt(p1*(p1-p_pn)*(p1-pn_qn)*(p1-p_qn));
float s2=sqrt(p2*(p2-p_pn)*(p2-pn_q)*(p2-p_q));
if (s1>s2) return 1;
else if (s2>s1) return 2;
else return 3;
}
void CDiameterView::WriteToLog(CDiameterDoc* pDoc)
{
char str1[10];
if (Step==4) lDialog.mEdit+="ДИАМЕТР:\r\n";
if (Step!=4)
{
NumPare++;
lDialog.mEdit+="Шаг ";
itoa(NumPare,str1,10);
lDialog.mSteps=str1;
lDialog.mEdit+=str1;
lDialog.mEdit+="\r\n";
}
lDialog.mEdit+=" пара: [";
itoa(NodeP->GetID(),str1,10);
lDialog.mEdit+=str1;
lDialog.mEdit+=" , ";
itoa(NodeQ->GetID(),str1,10);
lDialog.mEdit+=str1;
lDialog.mEdit+="]\r\n расстояние = ";
gcvt(pDoc->Diameter.GetDistance(NodeP,NodeQ),6,str1);
lDialog.mEdit+=str1;
lDialog.mEdit+="\r\n";
lDialog.UpdateData(false);
}
float Angle(TNode *p1, TNode *p2)
{
float x1=p1->GetXCoord();
float x2=p2->GetXCoord();
float y1=p1->GetYCoord();
float y2=p2->GetYCoord();
float a=atan2(y2-y1,x2-x1);
return a;
}
AddPeer(TNode* P, TNode* Q)
{
Peer MyPeer;
MyPeer.P=P;MyPeer.Q=Q;
List.push_front(MyPeer);
}
int CDiameterView::NextStep(int AutType)
{
if (!CH_BUILD) return(-1);//если не построена ВО
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
switch (Step){
case 0:
{//ищем макс и мин по х
iter=0;
NumPare=0;
lDialog.mEdit="Начало алгоритма\r\n";
DiameterIterator<TNode*> p = (pDoc->Diameter.begin());
while (p != (pDoc->Diameter.end())) //ищем вершину из ВО (n)
{
if ((*p)->GetRight()!=0) break;
++p;
}
if (p==(pDoc->Diameter.end())) return (-1);
float MinX=1000000,MaxX=-1;
float MinY=-1,MaxY=1000000;
float tmp=-100;
TNode *tmpFir=(*p);
TNode *tmpCur=(*p);
while ((tmpCur!=tmpFir)||(tmp==-100)) //ищем противолежащие по X точки (n)
{
tmp=tmpCur->GetXCoord();
if (tmp<MinX)
{
MinX=tmp;MinY=tmpCur->GetYCoord();NodeP=tmpCur;
} else if ((tmp==MinX)&&(tmpCur->GetYCoord()>MinY))
{
MinX=tmp;MinY=tmpCur->GetYCoord();NodeP=tmpCur;
}
if (tmp>MaxX)
{
MaxX=tmp;MaxY=tmpCur->GetYCoord();NodeQ=tmpCur;
} else if ((tmp==MaxX)&&(tmpCur->GetYCoord()<MaxY))
{
MaxX=tmp;MaxY=tmpCur->GetYCoord();NodeQ=tmpCur;
}
tmpCur=tmpCur->GetRight();
}
/* if (NodeP->GetRight()==NodeQ)//тогда поменяем
{
NodeP0=NodeP;NodeP=NodeQ;NodeQ=NodeP0;
}*/
NodeP0=NodeP;
NodeQ0=NodeQ;
DiamNodeP=NodeP;
DiamNodeQ=NodeQ;
MaxDiameter=pDoc->Diameter.GetDistance(NodeP,NodeQ);
AddPeer(NodeP,NodeQ);
Step=1;
break;
}
case 1:
{//выполняем очередной шаг алгоритма (while NodeQ!=NodeP0)
if ((NodeP==NodeQ0)&&(NodeQ==NodeP0))
{
Step=4;break;
}
AddPeer(NodeP,NodeQ);
if ((pDoc->Diameter.GetDistance(NodeP,NodeQ))>MaxDiameter)
{
DiamNodeP=NodeP;
DiamNodeQ=NodeQ;
MaxDiameter=pDoc->Diameter.GetDistance(NodeP,NodeQ);
}
NodeP1=NodeP->GetRight();
NodeQ1=NodeQ->GetRight();
float a1=-Angle(NodeP,NodeP1);
float a2=-Angle(NodeQ1,NodeQ);
if (a1<a2) {NodeP=NodeP1;}
else if (a1>a2) {NodeQ=NodeQ1;}
else
{
if ((pDoc->Diameter.GetDistance(NodeP1,NodeQ))>MaxDiameter)
{
DiamNodeP=NodeP1;
DiamNodeQ=NodeQ;
MaxDiameter=pDoc->Diameter.GetDistance(NodeP1,NodeQ);
}
if ((pDoc->Diameter.GetDistance(NodeP,NodeQ1))>MaxDiameter)
{
DiamNodeP=NodeP;
DiamNodeQ=NodeQ1;
MaxDiameter=pDoc->Diameter.GetDistance(NodeP1,NodeQ1);
}
NodeP=NodeP1;
NodeQ=NodeQ1;
AddPeer(NodeP,NodeQ);
}
if ((NodeP==NodeQ0)&&(NodeQ==NodeP0))
{
Step=4;break;
}
break;
}
}
iter++;
return 0;
}
/*int CDiameterView::NextStep(int AutType)
{
if (!CH_BUILD) return(-1);//если не построена ВО
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
switch (Step){
case 0:
{//ищем макс и мин по х
iter=0;
lDialog.mEdit="Начало алгоритма\r\n";
DiameterIterator<TNode*> p = (pDoc->Diameter.begin());
while (p != (pDoc->Diameter.end())) //ищем вершину из ВО (n)
{
if ((*p)->GetRight()!=0) break;
++p;
}
if (p==(pDoc->Diameter.end())) return (-1);
float MinX=1000000,MaxX=-1;
float tmp=-100;
TNode *tmpFir=(*p);
TNode *tmpCur=(*p);
while ((tmpCur!=tmpFir)||(tmp==-100)) //ищем противолежащие по X точки (n)
{
tmp=tmpCur->GetXCoord();
if (tmp<MinX)
{
MinX=tmp;NodeP=tmpCur;
}
if (tmp>MaxX)
{
MaxX=tmp;NodeQ=tmpCur;
}
tmpCur=tmpCur->GetRight();
}
if (NodeP->GetRight()==NodeQ)//тогда поменяем
{
NodeP0=NodeP;NodeP=NodeQ;NodeQ=NodeP0;
}
NodeP0=NodeP;
NodeQ0=NodeQ;
DiamNodeP=NodeP;
DiamNodeQ=NodeQ;
MaxDiameter=pDoc->Diameter.GetDistance(NodeP,NodeQ);
Step=1;
break;
}
case 1:
{//выполняем очередной шаг алгоритма (while NodeQ!=NodeP0)
if (NodeQ!=NodeP0)
{
NodeP=NodeP->GetRight();
if ((pDoc->Diameter.GetDistance(NodeP,NodeQ))>MaxDiameter)
{
DiamNodeP=NodeP;
DiamNodeQ=NodeQ;
MaxDiameter=pDoc->Diameter.GetDistance(NodeP,NodeQ);
}
Step=2;
}else
{
if ((NodeP==NodeQ0)||(NodeP->GetRight()==NodeQ0)) Step=4;
else Step=3;
}
break;
}
case 2:
{//вложенный цикл while ((P,Q,>))
int cmp=Compare(pDoc,NodeP,NodeQ);
if (cmp==1)
{
NodeQ=NodeQ->GetRight();
if ((pDoc->Diameter.GetDistance(NodeP,NodeQ))>MaxDiameter)
{
DiamNodeP=NodeP;
DiamNodeQ=NodeQ;
MaxDiameter=pDoc->Diameter.GetDistance(NodeP,NodeQ);
}
Step=2;
if (NodeQ->GetRight()==NodeP0) {Step=4;break;}
}else Step=1;
break;
}
case 3:
{
if (NodeP->GetRight()!=NodeQ0)
{
NodeP=NodeP->GetRight();
if ((pDoc->Diameter.GetDistance(NodeP,NodeQ))>MaxDiameter)
{
DiamNodeP=NodeP;
DiamNodeQ=NodeQ;
MaxDiameter=pDoc->Diameter.GetDistance(NodeP,NodeQ);
}
Step=3;
} else Step=4;
}
}
iter++;
return 0;
}*/
void CDiameterView::OnFileOpen()
{
// TODO: Add your command handler code here
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CFileDialog fdlg(true,"pts",NULL,0,"Множество точек (*.pts)|*.pts||");
if(fdlg.DoModal() == IDOK)
{
pDoc->Diameter.ClearDiameterCont();
CString fname = fdlg.GetPathName();
std::ifstream fin(fname);
fin >> pDoc->Diameter;
fin.close();
pDoc->SetTitle(fdlg.GetPathName());
}
Invalidate();
char str[10];itoa(pDoc->Diameter.size(),str,10);
lDialog.mPoints=str;
lDialog.mSteps="";
lDialog.mEdit="";
lDialog.UpdateData(false);
if (pDoc->Diameter.size()>2) BUILD_CH_ENABLED=true; else BUILD_CH_ENABLED=false;
ALL_ENABLED=FIRST_ENABLED=NEXT_ENABLED=USER_ENABLED=false;
NodeP=NodeQ=0;Step=0;List.clear();
}
void CDiameterView::OnFileSave()
{
// TODO: Add your command handler code here
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CFileDialog fdlg(false,"pts",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"Множество точек (*.pts)|*.pts||");
if(fdlg.DoModal() == IDOK)
{
CString fname = fdlg.GetPathName();
std::ofstream fout(fname);
fout<<pDoc->Diameter;
fout.close();
pDoc->SetTitle(fdlg.GetPathName());
}
}
void CDiameterView::OnAlgoritmNext()
{
// TODO: Add your command handler code here
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
int tmp=CH_BUILD;
ResetFlags();
CH_BUILD=tmp;
FIRST_ENABLED=true;
//BUILD_CH_ENABLED=false;
int CurStep=Step;
int res=NextStep(0);
if ((CurStep==2)&&(Step==1)) {CurStep=Step;res=NextStep(0);}
if ((CurStep==1)&&(Step==3)) {res=NextStep(0);}
if (res==-1)
{
AfxMessageBox("Error!");
return;
}
if (Step!=4) WriteToLog(pDoc);
if ((UserNodeP!=0)&&(UserNodeQ!=0))
{
if (Step==4) AfxMessageBox("Это был последний шаг!",0);
else
{
if ( ((UserNodeP==NodeP)&&(UserNodeQ==NodeQ)) ||
((UserNodeP==NodeQ)&&(UserNodeQ==NodeP)) )
{//угадал
AfxMessageBox("Вы правильно выбрали вершины!",0);
}else
{//не угадал
AfxMessageBox("Вы НЕ правильно выбрали вершины!",16);
}
}
}
UserNodeP=UserNodeQ=0;USER=false;
Invalidate();
if (Step==4)
{
NEXT_ENABLED=false;
ALL_ENABLED=false;
USER_ENABLED=false;
//12NodeP=DiamNodeP;
//12NodeQ=DiamNodeQ;
WriteToLog(pDoc);
NodeP=NodeQ=0;
char ss[20];
gcvt(MaxDiameter,8,ss);
CString Out="Диаметр: ";Out+=ss;
AfxMessageBox(Out);
}
}
void CDiameterView::OnUpdateAlgoritmNext(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(false);
pCmdUI->Enable(NEXT_ENABLED);
}
void CDiameterView::OnAlgoritmAll()
{
// TODO: Add your command handler code here
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
int tmp=CH_BUILD;
ResetFlags();
CH_BUILD=tmp;
UserNodeP=UserNodeQ=0;USER=false;
FIRST_ENABLED=true;
//BUILD_CH_ENABLED=false;
//NodeP=0;NodeQ=0;
while ((Step!=4)&&(iter<10000))
{
int CurStep=Step;
int res=NextStep(0);
if ((CurStep==2)&&(Step==1)) {CurStep=Step;res=NextStep(0);}
if ((CurStep==1)&&(Step==3)) {res=NextStep(0);}
if (res==-1)
{
AfxMessageBox("Error!");
return;
}
if (Step!=4) WriteToLog(pDoc);
if (Step==4)
{
NEXT_ENABLED=false;
ALL_ENABLED=false;
USER_ENABLED=false;
//Step=0;List.clear();
//12NodeP=DiamNodeP;
//12NodeQ=DiamNodeQ;
WriteToLog(pDoc);
NodeP=NodeQ=0;
char ss[20];
gcvt(MaxDiameter,8,ss);
CString Out="Диаметр: ";Out+=ss;
AfxMessageBox(Out);
break;
}
}
Invalidate();
if (iter==10000) AfxMessageBox("Too many!");
}
void CDiameterView::OnUpdateAlgoritmAll(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(false);
pCmdUI->Enable(ALL_ENABLED);
}
void CDiameterView::OnAlgoritmFirst()
{
// TODO: Add your command handler code here
Step=0;List.clear();
NodeP=NodeQ=0;
NEXT_ENABLED=true;
ALL_ENABLED=true;
USER_ENABLED=true;
FIRST_ENABLED=false;
BUILD_CH_ENABLED=true;
UserNodeP=UserNodeQ=0;USER=false;
Invalidate();
}
void CDiameterView::OnUpdateAlgoritmFirst(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(false);
pCmdUI->Enable(FIRST_ENABLED);
}
void CDiameterView::OnVertNum()
{
// TODO: Add your command handler code here
VERT_NUM=!VERT_NUM;
Invalidate();
}
void CDiameterView::OnUpdateVertNum(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(VERT_NUM);
}
void CDiameterView::OnAlgoritmUser()
{
// TODO: Add your command handler code here
USER=!USER;
if (USER==true)
{
AfxMessageBox("Выберите две вершины, которые будут в алгоритме следующими",0);
}else
{
UserNodeP=UserNodeQ=0;
}
}
void CDiameterView::OnUpdateAlgoritmUser(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(USER_ENABLED);
if (USER_ENABLED==false)
{
UserNodeP=UserNodeQ=0;USER=false;
}
pCmdUI->SetCheck(USER);
}
void CDiameterView::OnLogShow()
{
// TODO: Add your command handler code here
CDiameterDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (lDialog.IsWindowVisible()==false)
{//показать диалог
lDialog.ShowWindow(SW_SHOWNORMAL);
} else
{//скрыть диалог
lDialog.ShowWindow(SW_HIDE);
}
}
void CDiameterView::OnUpdateLogShow(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(lDialog.IsWindowVisible());
}
void CDiameterView::OnButtonAlg()
{
// TODO: Add your command handler code here
ad.DoModal();
}
void CDiameterView::OnDrawLines()
{
// TODO: Add your command handler code here
DRAW_LINES=!DRAW_LINES;
Invalidate();
}
void CDiameterView::OnUpdateDrawLines(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(DRAW_LINES);
}
Соседние файлы в папке src