dtriangulationView.cpp
资源名称:package.rar [点击查看]
上传用户:chinasdcnc
上传日期:2022-07-02
资源大小:2702k
文件大小:28k
源码类别:
分形几何
开发平台:
Visual C++
- // dtriangulationView.cpp : CdtriangulationView 类的实现
- //
- #include "stdafx.h"
- #include "dtriangulation.h"
- #include "dcel.h"
- #include "dtriangulationDoc.h"
- #include "dtriangulationView.h"
- #include "GenPoints.h"
- #include "utility.h"
- #include <vector>
- #include "base.h"
- #include <stdlib.h>
- #include <time.h>
- #include <gl/GL.h>
- #include <gl/GLU.h>
- using namespace std;
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- #define MAXMANINPUTPOINTS 1000
- // CdtriangulationView
- IMPLEMENT_DYNCREATE(CdtriangulationView, CView)
- BEGIN_MESSAGE_MAP(CdtriangulationView, CView)
- // 标准打印命令
- ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
- ON_COMMAND(ID_GENERATEPOINTS, &CdtriangulationView::OnGeneratePoints)
- ON_COMMAND(ID_INPUTPOINTS, &CdtriangulationView::OnInputPoints)
- ON_WM_LBUTTONDOWN()
- ON_COMMAND(ID_TRIANGULATION, &CdtriangulationView::OnTriangulation)
- ON_COMMAND(ID_FILE_NEW, &CdtriangulationView::OnFileNew)
- ON_COMMAND(ID_FILE_OPEN, &CdtriangulationView::OnFileOpen)
- ON_COMMAND(ID_FILE_SAVE, &CdtriangulationView::OnFileSave)
- ON_WM_KEYDOWN()
- ON_WM_CREATE()
- ON_WM_DESTROY()
- ON_WM_ERASEBKGND()
- ON_WM_SIZE()
- ON_WM_LBUTTONUP()
- ON_COMMAND(ID_DCEL_TEST, &CdtriangulationView::OnDcelTest)
- ON_COMMAND(ID_CIRCLE_TEST, &CdtriangulationView::OnCircleTest)
- ON_WM_MOUSEMOVE()
- ON_COMMAND(ID_SHOW_ENLARGE, &CdtriangulationView::OnShowEnlarge)
- ON_COMMAND(ID_SHOW_REVERT, &CdtriangulationView::OnShowRevert)
- ON_WM_TIMER()
- ON_COMMAND(ID_DT_DEMO, &CdtriangulationView::OnDtDemo)
- END_MESSAGE_MAP()
- // CdtriangulationView 构造/析构
- CdtriangulationView::CdtriangulationView()
- {
- isManInputState = false;
- isLButtonDown = false;
- isTest = false;
- isCircleTest = false;
- isEnLarge = true;
- isOne = false;
- isPro = false;
- isDTDemo = false;
- circleTri = NULL;
- }
- CdtriangulationView::~CdtriangulationView()
- {
- testTris.clear();
- }
- BOOL CdtriangulationView::PreCreateWindow(CREATESTRUCT& cs)
- {
- // CREATESTRUCT cs 来修改窗口类或样式
- return CView::PreCreateWindow(cs);
- }
- // CdtriangulationView 绘制
- void CdtriangulationView::OnDraw(CDC* pDC)
- {
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- wglMakeCurrent(pDC->m_hDC, m_hRC);
- glClearColor(1.0, 1.0, 1.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- // draw points
- glColor4f(1.0, 0.0, 0.0, 1.0);
- glPointSize(3.0f);
- glBegin(GL_POINTS);
- for(int i = 0; i < pDoc->nPoints; ++i)
- glVertex2d(pDoc->point(i)->x, pDoc->point(i)->y);
- glEnd();
- // draw lines
- if(pDoc->myDT.isFinished)
- {
- drawDT(pDoc->myDT.maxEdge.le);
- drawDT(pDoc->myDT.maxEdge.re);
- resetVisitedState(pDoc->myDT.maxEdge.le);
- resetVisitedState(pDoc->myDT.maxEdge.re);
- }
- // draw dt demo
- if(isDTDemo)
- {
- std::vector<MaxEdge>::iterator iter;
- //while(!maxEdges.empty())
- //{
- for(iter = maxEdges.begin(); iter != maxEdges.end(); iter++)
- {
- drawDT((*iter).le);
- drawDT((*iter).re);
- resetVisitedState((*iter).le);
- resetVisitedState((*iter).re);
- }
- //}
- }
- // draw circle test
- if (isCircleTest && circleTri != NULL)
- {
- GLUquadric* qd = gluNewQuadric();
- glColor4f(0.4f, 0.0f, 1.0f, 0.4f);
- gluQuadricDrawStyle(qd, GLU_FILL);
- glPushMatrix();
- glTranslated(cirTestCenter.x, cirTestCenter.y, 0.0);
- gluDisk(qd, 0.0, cirTestRadius, 50, 4);
- glPopMatrix();
- gluDeleteQuadric(qd);
- }
- // draw DCEL test
- if(testTris.size() > 0 && isTest)
- {
- // draw tris
- Point2d ps[3];
- vector<Edge *>::iterator iter;
- Edge *initEdge, *circleEdge;
- int i;
- glColor4f(0.0, 1.0f, 0.0, 0.3f);
- glBegin(GL_TRIANGLES);
- if (!isPro)
- {
- for(iter = testTris.begin(); iter != testTris.end(); ++iter)
- {
- initEdge = *iter;
- circleEdge = initEdge;
- i = 0;
- do
- {
- ps[i].x = circleEdge->org2d().x;
- ps[i].y = circleEdge->org2d().y;
- ++i;
- circleEdge = circleEdge->lNext();
- }while(circleEdge != initEdge);
- glVertex2d(ps[0].x, ps[0].y);
- glVertex2d(ps[1].x, ps[1].y);
- glVertex2d(ps[2].x, ps[2].y);
- }
- }
- else
- {
- int tmp = 0;
- for(iter = testTris.begin(); iter != testTris.end(); ++iter)
- {
- if (tmp++ > tempCount)
- break;
- initEdge = *iter;
- circleEdge = initEdge;
- i = 0;
- do
- {
- ps[i].x = circleEdge->org2d().x;
- ps[i].y = circleEdge->org2d().y;
- ++i;
- circleEdge = circleEdge->lNext();
- }while(circleEdge != initEdge);
- glVertex2d(ps[0].x, ps[0].y);
- glVertex2d(ps[1].x, ps[1].y);
- glVertex2d(ps[2].x, ps[2].y);
- }
- }
- glEnd();
- }
- if (isTest)
- {
- // draw test line
- glColor4f(1.0, 0.0, 1.0, 1.0);
- glBegin(GL_LINES);
- glVertex2d(startTestPoint.x, startTestPoint.y);
- glVertex2d(finishTestPoint.x, finishTestPoint.y);
- glEnd();
- }
- if (isTest && isLButtonDown && isEnLarge)
- {
- // draw temp test line
- glColor4f(1.0, 0.0, 1.0, 1.0);
- glBegin(GL_LINES);
- glVertex2d(startTestPoint.x, startTestPoint.y);
- glVertex2d(tempTestPoint.x, tempTestPoint.y);
- glEnd();
- }
- else if (isLButtonDown && !isEnLarge && isOne)
- {
- // draw rectangle
- glColor4f(0.0f, 0.0, 1.0f, 0.4f);
- glBegin(GL_QUADS);
- glVertex2d(startRectPoint.x, startRectPoint.y);
- glVertex2d(startRectPoint.x, tempRectPoint.y);
- glVertex2d(tempRectPoint.x, tempRectPoint.y);
- glVertex2d(tempRectPoint.x, startRectPoint.y);
- glEnd();
- }
- glFlush();
- SwapBuffers(pDC->m_hDC);
- wglMakeCurrent(NULL, NULL);
- }
- // CdtriangulationView 打印
- BOOL CdtriangulationView::OnPreparePrinting(CPrintInfo* pInfo)
- {
- // 默认准备
- return DoPreparePrinting(pInfo);
- }
- void CdtriangulationView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- // TODO: 添加额外的打印前进行的初始化过程
- }
- void CdtriangulationView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- // TODO: 添加打印后进行的清除过程
- }
- void CdtriangulationView::resetVisitedState(Edge* e)
- {
- DCEL *pDcel;
- Edge *edge;
- std::stack<Edge *>dcelStack;
- dcelStack.push(e);
- while(!dcelStack.empty())
- {
- edge = dcelStack.top();
- pDcel = (DCEL *)(edge->qEdge());
- dcelStack.pop();
- if(pDcel->visited)
- {
- pDcel->visited = false;
- dcelStack.push(edge->oNext());
- dcelStack.push(edge->oPrev());
- dcelStack.push(edge->dNext());
- dcelStack.push(edge->dPrev());
- }
- }
- }
- void CdtriangulationView::drawDT(Edge* e)
- {
- CdtriangulationDoc* pDoc = GetDocument();
- DCEL *pDcel;
- Edge *edge;
- std::stack<Edge *>dcelStack;
- dcelStack.push(e);
- glColor4f(0.0, 0.0, 0.0, 0.5);
- glBegin(GL_LINES);
- while(!dcelStack.empty())
- {
- edge = dcelStack.top();
- pDcel = (DCEL *)(edge->qEdge());
- dcelStack.pop();
- if(!pDcel->visited)
- {
- glVertex2d(edge->org()->x, edge->org()->y);
- glVertex2d(edge->dest()->x, edge->dest()->y);
- pDcel->visited = true;
- dcelStack.push(edge->oNext());
- dcelStack.push(edge->oPrev());
- dcelStack.push(edge->dNext());
- dcelStack.push(edge->dPrev());
- }
- }
- glEnd();
- }
- // CdtriangulationView 诊断
- #ifdef _DEBUG
- void CdtriangulationView::AssertValid() const
- {
- CView::AssertValid();
- }
- void CdtriangulationView::Dump(CDumpContext& dc) const
- {
- CView::Dump(dc);
- }
- CdtriangulationDoc* CdtriangulationView::GetDocument() const // 非调试版本是内联的
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CdtriangulationDoc)));
- return (CdtriangulationDoc*)m_pDocument;
- }
- #endif //_DEBUG
- // CdtriangulationView 消息处理程序
- void CdtriangulationView::OnGeneratePoints(void)
- {
- isManInputState = false;
- isTest = false;
- isCircleTest = false;
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- CGenPoints genPointDlg;
- if (genPointDlg.DoModal() == IDOK)
- {
- pDoc->nPoints = genPointDlg.points;
- if (pDoc->points != NULL)
- {
- pDoc->myDT.destroy();
- delete[] pDoc->points;
- }
- testTris.clear();
- pDoc->points = new Point2d[pDoc->nPoints];
- CRect rect;
- GetClientRect(&rect);
- int maxHeight = rect.Height() - 5, maxWidth = rect.Width() - 5;
- srand(unsigned(time(NULL)));
- for (int i = 0; i < pDoc->nPoints; ++i)
- {
- double px = random(5, maxWidth) + random();
- double py = random(5, maxHeight) + random();
- pDoc->points[i].x = px;
- pDoc->points[i].y = py;
- }
- Invalidate();
- }
- }
- void CdtriangulationView::OnInputPoints(void)
- {
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- if (!isEnLarge)
- return;
- pDoc->nPoints = 0;
- testTris.clear();
- if (pDoc->points != NULL)
- {
- pDoc->myDT.destroy();
- delete[] pDoc->points;
- }
- pDoc->points = new Point2d[MAXMANINPUTPOINTS];
- isManInputState = true;
- isCircleTest = false;
- isTest = false;
- Invalidate();
- }
- void CdtriangulationView::OnTriangulation(void)
- {
- QueryPerformanceFrequency(&Freq);
- isManInputState = false;
- isCircleTest = false;
- isTest = false;
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- if (pDoc->nPoints <= 1)
- {
- MessageBox("Not enough points.", "warning");
- return;
- }
- QueryPerformanceCounter(&BeginTime);
- pDoc->myDT.initial(&(pDoc->nPoints), pDoc->points);
- pDoc->myDT.doDelaunayTriangulation();
- QueryPerformanceCounter(&EndTime);
- // output runtime of delaunay triangulation.
- CString s;
- s.Format("三角剖分用时:%d us", (EndTime.QuadPart - BeginTime.QuadPart) * 1000000 / Freq.QuadPart);
- CStatusBar* pStatusBar = (CStatusBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
- pStatusBar->SetPaneText(pStatusBar->CommandToIndex(ID_INDICATOR_RUNTIME),s);
- Invalidate();
- }
- void CdtriangulationView::OnFileNew(void)
- {
- isManInputState = false;
- isTest = false;
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- pDoc->nPoints = 0;
- pDoc->myDT.destroy();
- delete[] pDoc->points;
- testTris.clear();
- pDoc->points = NULL;
- CClientDC dc(this);
- wglMakeCurrent(dc.m_hDC, m_hRC);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- CRect rect;
- GetClientRect(&rect);
- int maxHeight = rect.Height(), maxWidth = rect.Width();
- gluOrtho2D(0, (double)maxWidth, (double)maxHeight, 0);
- glViewport(0, 0, maxWidth, maxHeight);
- wglMakeCurrent(NULL, NULL);
- isEnLarge = true;
- isCircleTest = false;
- isOne = false;
- Invalidate();
- }
- void CdtriangulationView::OnFileOpen(void)
- {
- CFileDialog pCFileDialog(true, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
- TEXT("POINT files (*.point)|*.point|ALL files (*.*)|*.*||"), NULL);
- pCFileDialog.m_ofn.lpstrTitle = TEXT("Open point file");
- USES_CONVERSION;
- if (pCFileDialog.DoModal() == IDOK)
- {
- CString strPathName = pCFileDialog.GetPathName();
- if (!GetDocument()->load(T2A(strPathName.GetBuffer(strPathName.GetLength()))))
- {
- MessageBox(TEXT("Failing to open this file."), TEXT("Warning"));
- }
- }
- isCircleTest = false;
- isTest = false;
- Invalidate();
- }
- void CdtriangulationView::OnFileSave(void)
- {
- CFileDialog pCFileDialog(false, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
- TEXT("POINT files (*.point)|*.point|ALL files (*.*)|*.*||"), NULL);
- pCFileDialog.m_ofn.lpstrTitle = TEXT("Save points file");
- USES_CONVERSION;
- if (pCFileDialog.DoModal() == IDOK)
- {
- CString strPathName = pCFileDialog.GetPathName();
- if (!GetDocument()->save(T2A(strPathName.GetBuffer(strPathName.GetLength()))))
- {
- MessageBox(TEXT("Failing to save this file."), TEXT("Warning"));
- }
- }
- isCircleTest = false;
- isTest = false;
- Invalidate();
- }
- void CdtriangulationView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- isTest = false;
- testTris.clear();
- if(0x0d == nChar)
- {
- isCircleTest = false;
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- if (pDoc->nPoints <= 1)
- pDoc->nPoints = 100;
- if (pDoc->points != NULL)
- {
- pDoc->myDT.destroy();
- delete[] pDoc->points;
- }
- pDoc->points = new Point2d[pDoc->nPoints];
- CRect rect;
- GetClientRect(&rect);
- int maxHeight = rect.Height() - 5, maxWidth = rect.Width() - 5;
- srand(unsigned(time(NULL)));
- for (int i = 0; i < pDoc->nPoints; ++i)
- {
- double px = random(5, maxWidth) + random();
- double py = random(5, maxHeight) + random();
- pDoc->points[i].x = px;
- pDoc->points[i].y = py;
- }
- QueryPerformanceFrequency(&Freq);
- QueryPerformanceCounter(&BeginTime);
- pDoc->myDT.initial(&(pDoc->nPoints), pDoc->points);
- pDoc->myDT.doDelaunayTriangulation();
- QueryPerformanceCounter(&EndTime);
- // output runtime of delaunay triangulation.
- CString s;
- s.Format("%d us", (EndTime.QuadPart - BeginTime.QuadPart) * 1000000 / Freq.QuadPart);
- CStatusBar* pStatusBar = (CStatusBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
- pStatusBar->SetPaneText(pStatusBar->CommandToIndex(ID_INDICATOR_RUNTIME),s);
- Invalidate();
- }
- CView::OnKeyDown(nChar, nRepCnt, nFlags);
- }
- int CdtriangulationView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CView::OnCreate(lpCreateStruct) == -1)
- return -1;
- CClientDC dc(this);
- PIXELFORMATDESCRIPTOR pdf;
- memset(&pdf, 0, sizeof(PIXELFORMATDESCRIPTOR));
- pdf.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- pdf.nVersion = 1;
- pdf.dwFlags = PFD_DRAW_TO_WINDOW |
- PFD_SUPPORT_OPENGL |
- PFD_DOUBLEBUFFER;
- pdf.iPixelType = PFD_TYPE_RGBA;
- pdf.cColorBits = 24;
- pdf.cDepthBits = 32;
- int pixelFormat = ChoosePixelFormat(dc.m_hDC, &pdf);
- SetPixelFormat(dc.m_hDC, pixelFormat, &pdf);
- m_hRC = wglCreateContext(dc.m_hDC);
- return 0;
- }
- void CdtriangulationView::OnDestroy()
- {
- CView::OnDestroy();
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(m_hRC);
- m_hRC = NULL;
- }
- BOOL CdtriangulationView::OnEraseBkgnd(CDC* pDC)
- {
- //return CView::OnEraseBkgnd(pDC);
- return true;
- }
- void CdtriangulationView::OnSize(UINT nType, int cx, int cy)
- {
- CView::OnSize(nType, cx, cy);
- CClientDC dc(this);
- wglMakeCurrent(dc.m_hDC, m_hRC);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
- CRect rect;
- GetClientRect(&rect);
- int maxHeight = rect.Height(), maxWidth = rect.Width();
- gluOrtho2D(0, (double)maxWidth, (double)maxHeight, 0);
- glViewport(0, 0, cx, cy);
- wglMakeCurrent(NULL, NULL);
- }
- void CdtriangulationView::OnLButtonDown(UINT nFlags, CPoint point)
- {
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- if (isManInputState)
- {
- if (pDoc->nPoints >= MAXMANINPUTPOINTS)
- {
- MessageBox("Too many input points!", "warning");
- }
- else
- {
- Point2d tp(point.x, point.y);
- pDoc->points[pDoc->nPoints++] = tp;
- Invalidate();
- }
- }
- else if (!isEnLarge)
- {
- startRectPoint.x = point.x;
- startRectPoint.y = point.y;
- isLButtonDown = true;
- }
- else if (isTest)
- {
- testTris.clear();
- startTestPoint.x = point.x;
- startTestPoint.y = point.y;
- finishTestPoint.x = point.x;
- finishTestPoint.y = point.y;
- isLButtonDown = true;
- }
- else if (isCircleTest)
- {
- if(pDoc->myDT.isFinished)
- {
- circleTri = locate(Point2d(point.x, point.y), pDoc->myDT.maxEdge.le);
- if (circleTri != NULL)
- {
- circumCircle(circleTri->org2d(), circleTri->next()->org2d(),
- circleTri->next()->dest2d(), &cirTestCenter,
- &cirTestRadius);
- Invalidate();
- }
- }
- }
- CView::OnLButtonDown(nFlags, point);
- }
- void CdtriangulationView::OnLButtonUp(UINT nFlags, CPoint point)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- if (isTest && isEnLarge)
- {
- finishTestPoint.x = point.x;
- finishTestPoint.y = point.y;
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if(pDoc->myDT.isFinished)
- {
- intersectedTris(startTestPoint, finishTestPoint, testTris, pDoc->myDT.maxEdge.le);
- isPro = true;
- int detal = 100;
- if (pDoc->nPoints > 500)
- detal = 50;
- else if (pDoc->nPoints > 5000)
- detal = 10;
- m_nTimer = SetTimer(1, detal, 0);
- tempCount = -1;
- Invalidate();
- }
- }
- else if (isOne && !isEnLarge)
- {
- endRectPoint.x = point.x;
- endRectPoint.y = point.y;
- CClientDC dc(this);
- wglMakeCurrent(dc.m_hDC, m_hRC);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- CRect rect;
- GetClientRect(&rect);
- int maxHeight = rect.Height(), maxWidth = rect.Width();
- double maxw = getMax(startRectPoint.x, endRectPoint.x);
- double minw = getMin(startRectPoint.x, endRectPoint.x);
- double maxh = getMax(startRectPoint.y, endRectPoint.y);
- double minh = getMin(startRectPoint.y, endRectPoint.y);
- gluOrtho2D(getMax(minw, 1.0), getMax(maxw, 1.0), getMax(maxh, 1.0), getMax(minh, 1.0));
- glViewport(0, 0, maxWidth, maxHeight);
- wglMakeCurrent(NULL, NULL);
- isOne = false;
- Invalidate();
- }
- isLButtonDown = false;
- CView::OnLButtonUp(nFlags, point);
- }
- void CdtriangulationView::OnDcelTest(void)
- {
- if (GetDocument()->nPoints <= 1 || !GetDocument()->myDT.isFinished || !isEnLarge)
- {
- MessageBox("Can not do DCEL test!", "warning");
- Invalidate();
- return;
- }
- isTest = true;
- isManInputState = false;
- isCircleTest = false;
- tempCount = -1;
- }
- void CdtriangulationView::OnCircleTest(void)
- {
- if (GetDocument()->nPoints <= 2 || !GetDocument()->myDT.isFinished || !isEnLarge) // delete !isEnlarge
- {
- MessageBox("Can not do circle test!", "warning");
- Invalidate();
- return;
- }
- isCircleTest = true;
- isTest = false;
- isManInputState = false;
- }
- void CdtriangulationView::OnMouseMove(UINT nFlags, CPoint point)
- {
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (isLButtonDown && !isEnLarge && isOne)
- {
- tempRectPoint.x = point.x;
- tempRectPoint.y = point.y;
- Invalidate();
- }
- if ((pDoc->myDT.isFinished && isTest && isLButtonDown))
- {
- tempTestPoint.x = point.x;
- tempTestPoint.y = point.y;
- Invalidate();
- }
- CView::OnMouseMove(nFlags, point);
- }
- void CdtriangulationView::OnShowEnlarge(void)
- {
- if (isEnLarge)
- {
- isEnLarge = false;
- isOne = true;
- isManInputState = false;
- CString s = "放大状态,不能进行其他操作";
- CStatusBar* pStatusBar = (CStatusBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
- pStatusBar->SetPaneText(pStatusBar->CommandToIndex(ID_INDICATOR_RUNTIME),s);
- }
- }
- void CdtriangulationView::OnShowRevert(void)
- {
- if (!isEnLarge)
- {
- CClientDC dc(this);
- wglMakeCurrent(dc.m_hDC, m_hRC);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- CRect rect;
- GetClientRect(&rect);
- int maxHeight = rect.Height(), maxWidth = rect.Width();
- gluOrtho2D(0, (double)maxWidth, (double)maxHeight, 0);
- glViewport(0, 0, maxWidth, maxHeight);
- wglMakeCurrent(NULL, NULL);
- isEnLarge = true;
- isOne = false;
- CString s = "视图状态恢复正常";
- CStatusBar* pStatusBar = (CStatusBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
- pStatusBar->SetPaneText(pStatusBar->CommandToIndex(ID_INDICATOR_RUNTIME),s);
- Invalidate();
- }
- }
- void CdtriangulationView::OnTimer(UINT_PTR nIDEvent)
- {
- if (nIDEvent == m_nTimer)
- {
- if (tempCount == testTris.size())
- {
- KillTimer(m_nTimer);
- isPro = false;
- }
- else
- {
- ++tempCount;
- }
- Invalidate();
- }
- CView::OnTimer(nIDEvent);
- }
- void CdtriangulationView::OnDtDemo()
- {
- // TODO: 在此添加命令处理程序代码
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- if (pDoc->nPoints <= 1)
- return;
- this->isTest = false;
- this->isCircleTest = false;
- this->isManInputState = false;
- this->isDTDemo = true;
- if (pDoc->myDT.nPoints >= 100000)
- {
- MessageBox("too many points!", "warning");
- return;
- }
- while(!maxEdges.empty())
- {
- maxEdges.clear();
- }
- pDoc->myDT.initial(&(pDoc->nPoints), pDoc->points);
- if (pDoc->myDT.nPoints >= 2)
- {
- pDoc->myDT.maxEdge = delaunayDemo(0, pDoc->myDT.nPoints - 1, 1000 / pDoc->nPoints);
- pDoc->myDT.isFinished = true;
- }
- this->isDTDemo = false;
- }
- MaxEdge CdtriangulationView::delaunayDemo(int begin, int end, int timeInterval)
- {
- // the number of points
- int size = end - begin + 1;
- // max edge
- MaxEdge ret;
- // doc
- CdtriangulationDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // delaunay triangulation
- if(size == 2) // only two points
- {
- // let s1, s2 be two sites in sorted order.
- // create an edge a from s1 to s2
- Edge* a = makeEdge();
- a->endPoints(pDoc->myDT.point(begin), pDoc->myDT.point(end));
- ret.le = a;
- ret.re = a->twin();
- maxEdges.insert(maxEdges.end(), ret);
- // demo
- Sleep(timeInterval);
- pDoc->myDT.maxEdge = ret;
- OnDraw(GetDC());
- return ret;
- }
- else if(size == 3) // only three points
- {
- // let s1, s2, s3 be the three sites, in sorted order,
- // create edges a connecting s1 to s2 and b connecting s2 to s3
- Edge* a = makeEdge();
- Edge* b = makeEdge();
- splice(a->twin(), b);
- a->endPoints(pDoc->myDT.point(begin), pDoc->myDT.point(begin + 1));
- b->endPoints(pDoc->myDT.point(begin + 1), pDoc->myDT.point(end));
- // close the triangle
- Edge* c;
- if(ccw(*pDoc->myDT.point(begin), *pDoc->myDT.point(begin + 1), *pDoc->myDT.point(end)))
- {
- c = connect(b, a);
- ret.le = a;
- ret.re = b->twin();
- }
- else if(ccw(*pDoc->myDT.point(begin), *pDoc->myDT.point(end), *pDoc->myDT.point(begin + 1)))
- {
- c = connect(b, a);
- ret.le = c->twin();
- ret.re = c;
- }
- else // the three points are collinear
- {
- ret.le = a;
- ret.re = b->twin();
- }
- maxEdges.insert(maxEdges.end(), ret);
- // demo
- Sleep(timeInterval);
- pDoc->myDT.maxEdge = ret;
- OnDraw(GetDC());
- return ret;
- }
- else // |sites| >= 4
- {
- Edge *ldo, *ldi; // left half result
- Edge *rdo, *rdi; // right half result
- // recursively delaunay triangulation L and R halves
- MaxEdge leftRet = delaunayDemo(begin, begin + (size / 2) - 1, timeInterval);
- MaxEdge rightRet = delaunayDemo(begin + (size / 2), end, timeInterval);
- ldo = leftRet.le;
- ldi = leftRet.re;
- rdi = rightRet.le;
- rdo = rightRet.re;
- // Compute the lower commom tangent of L and R
- while(1)
- {
- if(leftOf(*(rdi->org()), ldi))
- {
- ldi = ldi->lNext();
- }
- else if(rightOf(*(ldi->org()), rdi))
- {
- rdi = rdi->rPrev();
- }
- else
- {
- break;
- }
- }
- // create a first edge basel from rdi.org to ldi.org
- Edge* basel = connect(rdi->twin(), ldi);
- if((ldi->org()) == (ldo->org()))
- {
- ldo = basel->twin();
- }
- if((rdi->org()) == (rdo->org()))
- {
- rdo = basel;
- }
- // merge
- while(1)
- {
- // locate the first L point (lcand.Dest) to be encountered by the rising bubble
- // and delete L edges out of basel.Dest that fail the circle test
- Edge* lcand = basel->twin()->oNext();
- Edge* t;
- if(valid(lcand, basel))
- {
- while(inCircle(*(basel->dest()), *(basel->org()), *(lcand->dest()),
- *(lcand->oNext()->dest())))
- {
- t = lcand->oNext();
- deleteEdge(lcand);
- lcand = t;
- }
- }
- // symmetrically, locate the first R point to be hit, and delete R edges
- Edge* rcand = basel->oPrev();
- if(valid(rcand, basel))
- {
- while(inCircle(*(basel->dest()), *(basel->org()), *(rcand->dest()),
- *(rcand->oPrev()->dest())))
- {
- t = rcand->oPrev();
- deleteEdge(rcand);
- rcand = t;
- }
- }
- // if both lcand and rcand are invalid, then basel is the upper common tangent
- if((!valid(lcand, basel)) && (!valid(rcand, basel)))
- {
- break;
- }
- // the next cross edge is to be connected to either lcand.Dest or rcand.Dest
- // if both are valid, then choose the appropriate one using the inCircle test
- if((!valid(lcand, basel)) || (valid(rcand, basel)
- && inCircle(*(lcand->dest()), *(lcand->org()),
- *(rcand->org()), *(rcand->dest()))))
- {
- // add cross edge basel from rcand.Dest to basel.Dest
- basel = connect(rcand, basel->twin());
- }
- else
- {
- // add cross edge basel from basel.org to lcand.Dest
- basel = connect(basel->twin(), lcand->twin());
- }
- }
- ret.le = ldo;
- ret.re = rdo;
- maxEdges.erase(maxEdges.end() - 1);
- maxEdges.erase(maxEdges.end() - 1);
- maxEdges.insert(maxEdges.end(), ret);
- // demo
- Sleep(timeInterval);
- pDoc->myDT.maxEdge = ret;
- OnDraw(GetDC());
- return ret;
- }
- }