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);
}