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