www.pudn.com > VoronoiDAC.rar > VoronoiDACDoc.cpp, change:2007-01-12,size:10837b
// VoronoiDACDoc.cpp : implementation of the CVoronoiDACDoc class
//
#include "stdafx.h"
#include "VoronoiDAC.h"
#include "VoronoiDACDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int MAXPOINT = 20000; //最多点数
extern void DPtoVP(float x, float y, int *X, int *Y);
extern void VPtoDP(int x, int y, float *X, float *Y);
extern void FlashLine(int x1, int y1, int x2, int y2);
/////////////////////////////////////////////////////////////////////////////
// CVoronoiDACDoc
IMPLEMENT_DYNCREATE(CVoronoiDACDoc, CDocument)
BEGIN_MESSAGE_MAP(CVoronoiDACDoc, CDocument)
//{{AFX_MSG_MAP(CVoronoiDACDoc)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVoronoiDACDoc construction/destruction
CVoronoiDACDoc::CVoronoiDACDoc()
{
// TODO: add one-time construction code here
m_Index = new int[MAXPOINT];
for (int i = 0; i MAXPOINT; i++)
{
m_Index[i] = 0;
//m_PointArray[i] = 0;
}
}
CVoronoiDACDoc::~CVoronoiDACDoc()
{
delete m_Index;
}
BOOL CVoronoiDACDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
CPt* CVoronoiDACDoc::AddPoint(float X, float Y, int ID, short ColorPen,
short ColorBrush, short LineWide, short LineType)
{
CPt *pPt = new CPt(X, Y, ID, ColorPen, ColorBrush, LineWide, LineType);
m_PointArray.Add(pPt);
// int i = m_PointArray.GetUpperBound();
return pPt;
}
CLine* CVoronoiDACDoc::AddLine(float X1, float Y1, float X2, float Y2, int ID,
short ColorPen, short ColorBrush, short LineWide,
short LineType)
{
CLine *pLine = new CLine(X1, Y1, X2, Y2, ID, ColorPen, ColorBrush, LineWide, LineType);
m_LineArray.Add(pLine);
return pLine;
}
CDraw* CVoronoiDACDoc::GetGraph(short Lb, int Index)
{
switch(Lb)
{
//根据图形类型,进行不同的操作
case 1:
//如果是基点
if (Index 0 || Index > m_PointArray.GetUpperBound())
{
return 0;
}
return m_PointArray.GetAt(Index);
break;
case 2:
//如果是全Voronoi图的边
if (Index 0 || Index > m_LineArray.GetUpperBound())
{
return 0;
}
return m_LineArray.GetAt(Index);
break;
case 3:
//如果是左边Voronoi图的边
if (Index 0 || Index > m_LeftLine.GetUpperBound())
{
return 0;
}
return m_LeftLine.GetAt(Index);
break;
case 4:
//如果是右边Voronoi图的边
if (Index 0 || Index > m_RightLine.GetUpperBound())
{
return 0;
}
return m_RightLine.GetAt(Index);
case 5:
//如果是中间的轮廓线的边
if (Index 0 || Index > m_Contour.GetUpperBound())
{
return 0;
}
return m_Contour.GetAt(Index);
case 6:
//如果是中间的裁减线的边
if (Index 0 || Index > m_ArrayToBeCutLine.GetUpperBound())
{
return 0;
}
return m_ArrayToBeCutLine.GetAt(Index);
default:
return 0;
break;
}
}
void CVoronoiDACDoc::DeleteGraph(short Lb, int Index)
{
switch(Lb)
{
//根据图形类型,进行不同操作
case 1:
//若是基点
if (Index 0 || Index > m_PointArray.GetUpperBound())
{
return;
}
m_PointArray.RemoveAt(Index);
break;
case 2:
//如果是全Voronoi图的边
if (Index 0 || Index > m_LineArray.GetUpperBound())
{
return;
}
m_LineArray.RemoveAt(Index);
break;
case 3:
//如果是左边Voronoi图的边
if (Index 0 || Index > m_LeftLine.GetUpperBound())
{
return;
}
m_LeftLine.RemoveAt(Index);
break;
case 4:
//如果是右边Voronoi图的边
if (Index 0 || Index > m_RightLine.GetUpperBound())
{
return;
}
m_RightLine.RemoveAt(Index);
case 5:
//如果是中间的轮廓线的边
if (Index 0 || Index > m_Contour.GetUpperBound())
{
return;
}
m_Contour.RemoveAt(Index);
case 6:
//如果是中间的轮廓线的边
if (Index 0 || Index > m_ArrayToBeCutLine.GetUpperBound())
{
return;
}
m_ArrayToBeCutLine.RemoveAt(Index);
default:
return;
break;
}
}
void CVoronoiDACDoc::DeleteAllGraph(short Lb)
{
switch(Lb)
{
//根据图形类型,进行不同操作
case 1:
//若是基点
m_PointArray.RemoveAll();
break;
case 2:
//如果是全Voronoi图的边
m_LineArray.RemoveAll();
break;
case 3:
//如果是左边Voronoi图的边
m_LeftLine.RemoveAll();
break;
case 4:
//如果是右边Voronoi图的边
m_RightLine.RemoveAll();
case 5:
//如果是中间的轮廓线的边
m_Contour.RemoveAll();
case 6:
//如果是中间的轮廓线的边
m_ArrayToBeCutLine.RemoveAll();
default:
return;
break;
}
}
int CVoronoiDACDoc::GetGraphNumb(short Lb)
{
switch(Lb)
{
case 1:
return m_PointArray.GetSize();
break;
case 2:
return m_LineArray.GetSize();
break;
case 3:
return m_LeftLine.GetSize();
break;
case 4:
return m_RightLine.GetSize();
break;
case 5:
return m_Contour.GetSize();
break;
case 6:
return m_ArrayToBeCutLine.GetSize();
break;
default:
return 0;
break;
}
}
int CVoronoiDACDoc::GetGraphUpperBound(short Lb)
{
switch(Lb)
{
case 1:
return m_PointArray.GetUpperBound();
break;
case 2:
return m_LineArray.GetUpperBound();
break;
case 3:
return m_LeftLine.GetUpperBound();
break;
case 4:
return m_RightLine.GetUpperBound();
break;
case 5:
return m_Contour.GetUpperBound();
break;
case 6:
return m_ArrayToBeCutLine.GetUpperBound();
break;
default:
return -1;
break;
}
}
int CVoronoiDACDoc::GetGraphID(short Lb)
{
int maxIndex = GetGraphUpperBound(Lb);
for (int i = 0; i maxIndex; i++)
{
if (GetGraph(Lb, i))
{
m_Index[GetGraph(Lb, i)->GetID()] = 1;
}
}
for (i = 0; i MAXPOINT; i++)
{
if (m_Index[i] == 0)
{
return i;
}
}
return -1;
}
void CVoronoiDACDoc::DrawAll(CDC *pDC, int DrawModel, short BackColor)
{
for (int i = 1; i 6; i++)
{
int maxIndex = GetGraphUpperBound(i) + 1;
while (maxIndex--)
{
GetGraph(i, maxIndex)->Draw(pDC, 0, 1);
}
}
}
void CVoronoiDACDoc::Draw(CDC *pDC, short Lb)
{
int maxIndex = GetGraphUpperBound(Lb) + 1;
while (maxIndex--)
{
GetGraph(Lb, maxIndex)->Draw(pDC, 0, Lb);
}
}
void CVoronoiDACDoc::DrawSpecialSite(CDC *pDc, int Low, int High)
{
CPen *pen = new CPen(PS_SOLID, 5, RGB(0, 100, 100));
CPen *OldPen = pDc->SelectObject(pen);
int x, y;
for (int i = Low; i = High; i++)
{
x = (int)m_SiteArray[i].x;
y = (int)m_SiteArray[i].y;
pDc->MoveTo(x, y);
pDc->LineTo(x, y);
}
pDc->SelectObject(OldPen);
}
void CVoronoiDACDoc::QuickSort(site *SiteArray, int Low, int High)
{
int i = Low, j = High;
site pivot;
if (Low >= High)
{
return;
}
else
{
pivot = SiteArray[Low];
while (i j)
{
while ((i j) && Prior(pivot, SiteArray[j]))
{
j--;
}
if (i j)
{
SiteArray[i++] = SiteArray[j];
}
while ((i j) && Prior(SiteArray[i], pivot))
{
i++;
}
if (i<j)
{
SiteArray[j--] = SiteArray[i];
}
}
SiteArray[i] = pivot;
QuickSort(SiteArray, Low, i-1);
QuickSort(SiteArray, i+1, High);
}
}
voronoi* CVoronoiDACDoc::CreateVoronoi(CDC *pDc,site *OrderedArray, int LowIndex, int HighIndex, BOOL IsStep)
{
int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
if (IsStep)
{
Sleep(500);
pDc->SelectStockObject(WHITE_BRUSH);
pDc->Rectangle(0, 0, ScreenWidth, ScreenHeight);
Draw(pDc, 1);
} //清屏
int siteNum = HighIndex - LowIndex;
if (siteNum == 1)
{
if (IsStep)
{
Sleep(500);
DrawSpecialSite(pDc, LowIndex, HighIndex);
}
return new voronoi(&OrderedArray[LowIndex], &OrderedArray[HighIndex]);
}
if (siteNum == 2)
{
if (IsStep)
{
Sleep(500);
DrawSpecialSite(pDc, LowIndex, HighIndex);
}
return new voronoi(&OrderedArray[LowIndex],
&OrderedArray[LowIndex + 1], &OrderedArray[HighIndex]);
}
int mid = (LowIndex + HighIndex) / 2;
voronoi *LeftVoronoi = CreateVoronoi(pDc, OrderedArray, LowIndex, mid, IsStep);
if (IsStep)
{
LeftVoronoi->PrintAll(&m_LeftLine);
Draw(pDc, 3);
Sleep(500);
pDc->SelectStockObject(WHITE_BRUSH);
pDc->Rectangle(0, 0, ScreenWidth, ScreenHeight);
Draw(pDc, 1);
DeleteAllGraph(3);
}
voronoi *RightVoronoi = CreateVoronoi(pDc, OrderedArray, mid + 1, HighIndex, IsStep);
if (IsStep)
{
RightVoronoi->PrintAll(&m_RightLine);
Draw(pDc, 4);
Sleep(500);
LeftVoronoi->PrintAll(&m_LeftLine);
Draw(pDc, 3);
//DeleteAllGraph(3);
DrawSpecialSite(pDc, LowIndex, HighIndex);
Sleep(500);
}
voronoi *MergedVoronoi = new voronoi();
LeftVoronoi->MergeWithRightVoronoi(RightVoronoi, MergedVoronoi,&m_ArrayToBeCutLine);
if (IsStep)
{
// CPoint start, end;
int ix1, iy1, ix2, iy2;
float fx1, fy1, fx2, fy2;
for (int i = 0; i m_ArrayToBeCutLine.GetSize(); i++)
{
CLine *pCurrLine = (CLine *)GetGraph(6, i);
fx1 = pCurrLine->m_fX1;
fy1 = pCurrLine->m_fY1;
fx2 = pCurrLine->m_fX2;
fy2 = pCurrLine->m_fY2;
DPtoVP(fx1, fy1, &ix1, &iy1);
DPtoVP(fx2, fy2, &ix2, &iy2);
FlashLine(ix1, iy1, ix2, iy2);
}
DeleteAllGraph(6);
MergedVoronoi->PrintAll(&m_Contour);
Draw(pDc, 5);
Sleep(500);
DeleteAllGraph(4);
RightVoronoi->PrintAll(&m_RightLine);
pDc->SelectStockObject(WHITE_BRUSH);
pDc->Rectangle(0, 0, ScreenWidth, ScreenHeight);
Draw(pDc, 1);
Draw(pDc, 4);
}
DeleteAllGraph(3);
DeleteAllGraph(4);
DeleteAllGraph(5);
return MergedVoronoi;
}
/////////////////////////////////////////////////////////////////////////////
// CVoronoiDACDoc serialization
void CVoronoiDACDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
for (int i = 1; i 6; i++)
{
int maxIndex = GetGraphUpperBound(i) + 1;
while (maxIndex --)
{
if (GetGraph(i, maxIndex)->IsDelete())
{
delete GetGraph(i, maxIndex);
DeleteGraph(i, maxIndex);
}
}
}
}
else
{
// TODO: add loading code here
}
m_PointArray.Serialize(ar);
m_LineArray.Serialize(ar);
}
/////////////////////////////////////////////////////////////////////////////
// CVoronoiDACDoc diagnostics
#ifdef _DEBUG
void CVoronoiDACDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CVoronoiDACDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CVoronoiDACDoc commands