www.pudn.com > VoronoiDAC.rar > VoronoiDACView.cpp, change:2007-01-12,size:15675b


// VoronoiDACView.cpp : implementation of the CVoronoiDACView class 
// 
#include "stdafx.h" 
#include "VoronoiDAC.h" 
#include "MainFrm.h" 
#include <math.h> 
 
#include "VoronoiDACDoc.h" 
#include "VoronoiDACView.h" 
#include "Shape.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
extern CGraphPara *p_GraphPara; 
 
/////////////////////////////////////////////////// 
//全局变量	 
CVoronoiDACView *p_View;  //当前活动视图 
 
/////////////////////////////////////////////////// 
//全局函数 
void DPtoVP(float x, float y, int *X, int *Y); 
void VPtoDP(int x, int y, float *X, float *Y); 
 
void FlashLine(int x1, int y1, int x2, int y2); 
///////////////////////////////////////////////////////////////////////////// 
// CVoronoiDACView 
 
IMPLEMENT_DYNCREATE(CVoronoiDACView, CView) 
 
BEGIN_MESSAGE_MAP(CVoronoiDACView, CView) 
	//{{AFX_MSG_MAP(CVoronoiDACView) 
	ON_WM_LBUTTONDOWN() 
	ON_WM_MOUSEMOVE() 
	ON_WM_LBUTTONUP() 
	ON_WM_SIZE() 
	ON_MESSAGE(WM_DRAWLINEMSG, OnDrawLineMsg) 
	ON_COMMAND(ID_OPERATION_RESET, OnOperationReset) 
	ON_UPDATE_COMMAND_UI(ID_OPERATION_RESET, OnUpdateOperationReset) 
	ON_COMMAND(ID_OPERATION_START, OnOperationStart) 
	ON_UPDATE_COMMAND_UI(ID_OPERATION_START, OnUpdateOperationStart) 
	ON_COMMAND(ID_OPERATION_CLEAR, OnOperationClear) 
	ON_UPDATE_COMMAND_UI(ID_OPERATION_CLEAR, OnUpdateOperationClear) 
	ON_COMMAND(ID_OPERATION_BACK, OnOperationBack) 
	ON_UPDATE_COMMAND_UI(ID_OPERATION_BACK, OnUpdateOperationBack) 
	ON_COMMAND(ID_OPERATION_STEP, OnOperationStep) 
	ON_UPDATE_COMMAND_UI(ID_OPERATION_STEP, OnUpdateOperationStep) 
	//}}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() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CVoronoiDACView construction/destruction 
 
CVoronoiDACView::CVoronoiDACView() : m_iSiteID(1), m_bPaintPt(TRUE), m_bIsStep(FALSE) 
{ 
	// TODO: add construction code here 
	m_pRedPen = new CPen(PS_SOLID, 2, RGB(255, 0, 0)); 
	m_pGreenPen = new CPen(PS_SOLID, 2, RGB(0, 255, 0)); 
	m_pBluePen = new CPen(PS_SOLID, 2, RGB(0, 0, 255)); 
	m_pWhitePen = new CPen(PS_SOLID, 2, RGB(255, 255, 255)); 
	m_pBlackPen = new CPen(PS_SOLID, 2, RGB(0, 0, 0)); 
    m_sPColor = 1; 
	m_sBKColor = 0; 
	m_sBColor = 1; 
	m_sLineWide = 4; 
	m_sLineType = PS_SOLID; 
	m_fBLC = 1.0; 
	m_fXStart = 0.0; 
	m_fYStart = 0.0; 
	//Init(); 
     
} 
 
CVoronoiDACView::~CVoronoiDACView() 
{ 
} 
 
 
void CVoronoiDACView::Init() 
{ 
    float minx, miny, maxx, maxy; 
	float bll; 
	minx = miny = 100.0; 
	maxx = 20000.0; 
	maxy = 10000.0; 
	bll = (maxx - minx) / m_iWScreen -20;  //横向比例 
	m_fBLC = (maxy - miny) / m_iHScreen -20;  //纵向比例 
	if (bll > m_fBLC) 
	{ 
		m_fBLC = bll; 
	} 
	m_fXStart = minx - 10 * m_fBLC; 
	m_fYStart = miny - 10 * m_fBLC; 
} 
 
BOOL CVoronoiDACView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CVoronoiDACView drawing 
 
void CVoronoiDACView::OnDraw(CDC* pDC) 
{ 
	CVoronoiDACDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
	pDoc->DrawAll(pDC, 0, m_sBKColor); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CVoronoiDACView printing 
 
BOOL CVoronoiDACView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CVoronoiDACView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CVoronoiDACView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CVoronoiDACView diagnostics 
 
#ifdef _DEBUG 
void CVoronoiDACView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CVoronoiDACView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CVoronoiDACDoc* CVoronoiDACView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVoronoiDACDoc))); 
	return (CVoronoiDACDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CVoronoiDACView message handlers 
 
void CVoronoiDACView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	//SetCapture(); 
 
//    voronoi *pvor = new voronoi(); 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	CClientDC dc(this); 
	float x, y; 
	int pID; 
 
	pID = pDoc->GetGraphID(1); 
 
	if (pDoc->m_PointArray.GetSize() != 0) 
	{ 
		for (int i = 0; i  pDoc->m_PointArray.GetSize(); i++) 
		{ 
			float prevX = pDoc->m_PointArray[i]->m_fX; 
			float prevY = pDoc->m_PointArray[i]->m_fY; 
 
			VPtoDP(point.x, point.y, &x, &y); 
 
			if ((prevX - x) * (prevX - x) + 
				(prevY - y) * (prevY - y) > 10) 
			{//排除重合的点 
				if (i == pDoc->m_PointArray.GetSize() - 1) 
				{ 
                    pDoc->AddPoint(x, y, pID, m_sPColor, m_sBColor, m_sLineWide,  
						m_sLineType)->Draw(&dc, 0, m_sBKColor); 
					break; 
				} 
 
			} 
			else 
			{ 
				break; 
			} 
 
		} 
	}  
	else 
	{ 
		VPtoDP(point.x, point.y, &x, &y); 
        pDoc->AddPoint(x, y, pID, m_sPColor, m_sBColor, m_sLineWide, m_sLineType)-> 
	          Draw(&dc, 0, m_sBKColor); 
	} 
	 
	m_iPrevX = point.x; 
	m_iPrevY = point.y; 
//	AddPoint(point); 
 
	 
//	RedrawGraph(); 
	CView::OnLButtonDown(nFlags, point); 
} 
 
void CVoronoiDACView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
 
	CString str; 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd; 
	CStatusBar *pStatus = &pFrame->m_wndStatusBar; 
	if (pStatus) 
	{ 
		str.Format("x = %d", point.x); 
		pStatus->SetPaneText(1, str); 
		pStatus->SetPaneInfo(1, 1, 1, 100); 
 
		str.Format("y = %d", point.y); 
		pStatus->SetPaneText(2, str); 
		//pStatus->SetPaneInfo(2, 2, 1, 100); 
 
		str.Format("点的个数:%d", pDoc->m_PointArray.GetSize()); 
		pStatus->SetPaneText(3, str); 
		pStatus->SetPaneInfo(3, 3, 2, 100); 
	} 
	 
	CView::OnMouseMove(nFlags, point); 
} 
 
void CVoronoiDACView::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
 
	CView::OnLButtonUp(nFlags, point); 
} 
 
void CVoronoiDACView::OnSize(UINT nType, int cx, int cy)  
{ 
	m_iWScreen = cx; 
	m_iHScreen = cy; 
	 
	CView::OnSize(nType, cx, cy); 
	 
	// TODO: Add your message handler code here 
	 
} 
 
void CVoronoiDACView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	p_View = this; 
	 
	CView::OnActivateView(bActivate, pActivateView, pDeactiveView); 
} 
 
LRESULT CVoronoiDACView::OnDrawLineMsg(WPARAM wParam, LPARAM lParam) 
{ 
	if (m_bIsStep) 
	{ 
//		MessageBox("相应了自定义消息!!!!!!!!!!!!!"); 
		MessageStruct *pCurrMsg = (MessageStruct *)wParam; 
		int actionType = pCurrMsg->iActionType; 
		int side = pCurrMsg->iSide; 
		LONG sx = (LONG)pCurrMsg->x1; 
		LONG sy = (LONG)pCurrMsg->y1; 
		LONG ex = (LONG)pCurrMsg->x2; 
		LONG ey = (LONG)pCurrMsg->y2; 
 
		CPoint startPt(sx, sy); 
		CPoint endPt(ex, ey); 
 
		switch(actionType) 
		{ 
		case 1: 
			//CutLine(startPt, endPt); 
		//	DrawLine(startPt, endPt); 
			break; 
		case 2: 
			//FlashLine(startPt, endPt);		 
			//CutLine(startPt, endPt); 
			break; 
		case 3: 
			//CutLine(startPt, endPt); 
			DrawLineDynamic(startPt, endPt); 
			DrawCross(endPt); 
			break; 
		default: 
			break; 
		} 
	} 
	return 0; 
} 
////////////////////////////////////////////////// 
void DPtoVP(float x, float y, int *X, int *Y) 
{ 
    p_View->DPtoVP(x, y, X, Y); 
} 
 
void VPtoDP(int x, int y, float *X, float *Y) 
{ 
	p_View->VPtoDP(x, y, X, Y); 
} 
 
void FlashLine(int x1, int y1, int x2, int y2) 
{ 
	CPoint sPT(x1, y1); 
	CPoint ePT(x2, y2); 
	p_View->FlashLine(sPT, ePT); 
} 
//////////////////////////////////////////////////// 
void CVoronoiDACView::AddPoint(CPoint point) 
{ 
	Site inputSite; 
 
	if (m_pointArray.GetSize() != 0)   
	{ 
		for (int i = 0; i  m_pointArray.GetSize(); i++) 
		{ 
		    float fPreSiteX = m_pointArray[i].m_fX; 
		    float fPreSiteY = m_pointArray[i].m_fY; 
			 
		    if (((point.x - fPreSiteX) * (point.x - fPreSiteX) +  
				 (point.y - fPreSiteY) * (point.y - fPreSiteY)) > 100) 
			{//排除相同的点 
				if (i == (m_pointArray.GetSize()) - 1) 
				{ 
					m_bPaintPt = TRUE; 
					inputSite.m_iID = m_iSiteID; 
					m_iSiteID ++; 
					inputSite.m_fX = (float)point.x; 
					inputSite.m_fY = (float)point.y;		 
					m_pointArray.Add(inputSite); 
					break; 
				}//if (i == (m_pointArray.GetSize()) - 1) 
				 
			}// if (((point.x) != fPreSiteX) || ((point.y) != fPreSiteY)) 
		    else 
			{ 
			    m_bPaintPt = FALSE; 
				break; 
			}//else 
		} 
	} 
	else 
	{ 
		inputSite.m_iID = m_iSiteID; 
		inputSite.m_fX = (float)point.x; 
		inputSite.m_fY = (float)point.y; 
		m_iSiteID ++; 
		m_pointArray.Add(inputSite); 
	} 
} 
 
void CVoronoiDACView::DrawLineDynamic(CPoint sPT, CPoint ePT) 
{ 
	const int MAX = 1; 
	int nDistance = abs((sPT.x - ePT.x) + (sPT.y - ePT.y)); 
	if (nDistance > 50) 
	{ 
		nDistance = 50; 
	} 
	int nStep = MAX * nDistance; 
	CPoint currPT, prevPT; 
	CClientDC dc(this); 
	CPen *pOldPen = dc.SelectObject(m_pBluePen); 
 
	for (int i = 1; i = nStep; i++) 
	{ 
		int dx = (int)((ePT.x - sPT.x) * i) / nStep; 
		int dy = (int)((ePT.y - sPT.y) * i) / nStep; 
		currPT.x = sPT.x + dx; 
		currPT.y = sPT.y + dy; 
		prevPT.x = currPT.x - (int)(ePT.x - sPT.x) / nStep; 
		prevPT.y = currPT.y - (int)(ePT.y - sPT.y) / nStep; 
		dc.MoveTo(prevPT); 
	    dc.LineTo(currPT); 
//		dc.SetPixel(currPT, RGB(0,0,255)); 
		Sleep(50); 
	} 
	dc.SelectObject(pOldPen); 
} 
 
void CVoronoiDACView::FlashLine(CPoint sPT, CPoint ePT) 
{ 
    CClientDC dc(this); 
	//int timer = SetTimer(1, 500, 0); 
	//CPen *pNewPen = new CPen(PS_SOLID, 1, RGB(200,0,150)); 
	CPen *pOldPen = dc.SelectObject(m_pBluePen); 
	for (int i = 0; i  3; i++) 
	{ 
		dc.MoveTo(sPT); 
		dc.LineTo(ePT); 
		dc.SelectObject(m_pRedPen); 
		Sleep(100); 
		dc.MoveTo(sPT); 
		dc.LineTo(ePT); 
		dc.SelectObject(m_pBluePen); 
		Sleep(100); 
	} 
	//KillTimer(1); 
	dc.SelectObject(m_pWhitePen); 
	dc.MoveTo(sPT); 
	dc.LineTo(ePT); 
	dc.SelectObject(pOldPen); 
} 
 
void CVoronoiDACView::DrawCross(CPoint pt) 
{ 
	//在点上画X,表示从这点截断线段 
	CClientDC dc(this); 
	CPen *pNewPen = new CPen(PS_SOLID, 3, RGB(0,0,0)); 
	CPen *pOldPen = dc.SelectObject(pNewPen); 
	dc.MoveTo(pt.x+5, pt.y-5); 
    dc.LineTo(pt.x-5, pt.y+5); 
	dc.MoveTo(pt.x-5, pt.y-5); 
	dc.LineTo(pt.x+5, pt.y+5); 
	dc.SelectObject(pOldPen); 
	//RedrawGraph(); 
} 
 
void CVoronoiDACView::CutLine(CPoint sPT, CPoint ePT) 
{ 
    CClientDC dc(this); 
	CPen *pOldPen = dc.SelectObject(m_pBlackPen); 
	dc.MoveTo(sPT); 
	dc.LineTo(ePT); 
	dc.SelectObject(pOldPen); 
} 
 
void CVoronoiDACView::DrawLine(CPoint sPT, CPoint ePT) 
{ 
    CClientDC dc(this); 
	CPen *pOldPen = dc.SelectObject(m_pBlackPen); 
	dc.MoveTo(sPT); 
	dc.LineTo(ePT); 
	dc.SelectObject(pOldPen); 
} 
 
void CVoronoiDACView::VPtoDP(int x, int y, float *X, float *Y) 
{ 
/*	*X = m_fXStart + x * m_fBLC;  //点的实际坐标横坐标 
	 
	if (m_iMapMode == 1) 
	{ 
		//如果是MM_TEXT映射方式 
		*Y = m_fYStart + m_fBLC * (m_iHScreen - y); 
	}  
	else 
	{ 
		*Y = m_fYStart + m_fBLC * (m_iHScreen + y); 
	}*/ 
	*X = (float)x; 
	*Y = (float)y; 
} 
 
void CVoronoiDACView::DPtoVP(float x, float y, int *X, int *Y) 
{ 
	/**X = (int)((x - m_fXStart) / m_fBLC); 
	if (m_iMapMode == 1) 
	{ 
		*Y = m_iHScreen - (int)((y - m_fYStart) / m_fBLC); 
	}  
	else 
	{ 
		*Y = (int)((y - m_fYStart) / m_fBLC) - m_iHScreen; 
	}*/ 
	*X = (int)x; 
	*Y = (int)y; 
} 
void CVoronoiDACView::RedrawGraph() 
{ 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	pDoc->UpdateAllViews(this); 
	Invalidate(); 
} 
 
void CVoronoiDACView::OnOperationReset()  
{ 
	// TODO: Add your command handler code here 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	pDoc->m_LineArray.RemoveAll(); 
	RedrawGraph(); 
} 
 
void CVoronoiDACView::OnUpdateOperationReset(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	pCmdUI->Enable(pDoc->m_PointArray.GetSize() >= 2);	 
} 
 
void CVoronoiDACView::OnOperationStart()  
{ 
	// TODO: Add your command handler code here 
	CClientDC dc(this); 
	m_bIsStep = FALSE; 
	CVoronoiDACDoc *pDoc = GetDocument(); 
       	CFile saveFile; 
 	saveFile.Open("C:\\test.vor", CFile::modeCreate | CFile::modeWrite); 
	CArchive ar(&saveFile, CArchive::store); 
	pDoc->Serialize(ar); 
	ar.Close(); 
	saveFile.Close(); 
	 
	int low = 0, high = pDoc->m_PointArray.GetUpperBound(); 
	site tempSite; 
	for (int i = low; i = high; i++) 
	{ 
        tempSite.id = pDoc->m_PointArray[i]->GetID(); 
		tempSite.x = pDoc->m_PointArray[i]->GetX(); 
		tempSite.y = pDoc->m_PointArray[i]->GetY(); 
		tempSite.pFace = NULL; 
		pDoc->m_SiteArray[i] = tempSite; 
	} 
	pDoc->QuickSort(pDoc->m_SiteArray, low, high); 
 
	voronoi *ResultVoronoi = pDoc->CreateVoronoi(&dc, pDoc->m_SiteArray, low, high, m_bIsStep); 
	ResultVoronoi->PrintAll(&(pDoc->m_LineArray)); 
    RedrawGraph(); 
} 
 
void CVoronoiDACView::OnUpdateOperationStart(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	pCmdUI->Enable(pDoc->m_PointArray.GetSize() >= 2); 
} 
 
void CVoronoiDACView::OnOperationClear()  
{ 
	// TODO: Add your command handler code here 
	CVoronoiDACDoc *pDoc = GetDocument(); 
//	for (int i = 0; i  pDoc->m_PointArray.GetSize(); i++) 
//	{ 
		pDoc->m_PointArray.RemoveAll(); 
		pDoc->m_LineArray.RemoveAll(); 
 
	RedrawGraph(); 
} 
 
void CVoronoiDACView::OnUpdateOperationClear(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	pCmdUI->Enable(pDoc->m_PointArray.GetSize() > 0); 
} 
 
void CVoronoiDACView::OnOperationBack()  
{ 
	// TODO: Add your command handler code here 
	CVoronoiDACDoc *pDoc = GetDocument();	 
	int maxInd = pDoc->m_PointArray.GetSize(); 
	pDoc->m_PointArray.RemoveAt(maxInd - 1); 
	RedrawGraph(); 
} 
 
void CVoronoiDACView::OnUpdateOperationBack(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	pCmdUI->Enable(pDoc->m_PointArray.GetSize() > 0);	 
} 
 
void CVoronoiDACView::OnOperationStep()  
{ 
	// TODO: Add your command handler code here 
	CClientDC dc(this); 
	m_bIsStep = TRUE; 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	int low = 0, high = pDoc->m_PointArray.GetUpperBound(); 
		site tempSite; 
	for (int i = low; i = high; i++) 
	{ 
        tempSite.id = pDoc->m_PointArray[i]->GetID(); 
		tempSite.x = pDoc->m_PointArray[i]->GetX(); 
		tempSite.y = pDoc->m_PointArray[i]->GetY(); 
		tempSite.pFace = NULL; 
//		tempSite.type =  
		pDoc->m_SiteArray[i] = tempSite; 
	} 
	pDoc->QuickSort(pDoc->m_SiteArray, low, high); 
 
	voronoi *ResultVoronoi = pDoc->CreateVoronoi(&dc, pDoc->m_SiteArray, low, high, m_bIsStep); 
	ResultVoronoi->PrintAll(&(pDoc->m_LineArray)); 
    RedrawGraph(); 
} 
 
void CVoronoiDACView::OnUpdateOperationStep(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	CVoronoiDACDoc *pDoc = GetDocument(); 
	pCmdUI->Enable(pDoc->m_PointArray.GetSize() >= 2); 
}