ChildView.cpp
上传用户:shlanyl88
上传日期:2013-03-14
资源大小:147k
文件大小:5k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. // ChildView.cpp
  2. //
  3. #include "stdafx.h"
  4. #include "DelaunayDemo.h"
  5. #include "ChildView.h"
  6. #include "QPerformanceTimer.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. const int range = 1000;
  11. #define colVertex (RGB(255, 128, 0))
  12. #if(WINVER >= 0x0400)
  13. #define FONT DEFAULT_GUI_FONT
  14. #else
  15. #define FONT SYSTEM_FONT
  16. #endif
  17. inline int Int(REAL r) { return (int) floor(r + 0.5f); } // properly round of a REAL
  18. // Function object to draw a vertex; to be used in for_each algorithm.
  19. class drawVertex
  20. {
  21. public:
  22. drawVertex(CDC& dc, REAL hScale, REAL vScale) : m_DC(dc), m_hScale(hScale), m_vScale(vScale) {}
  23. void operator()(const vertex& v) const
  24. {
  25. const int halfSize = 2;
  26. CRect rc;
  27. rc.SetRectEmpty();
  28. rc.InflateRect(halfSize, halfSize);
  29. rc.OffsetRect(Int(m_hScale * v.GetX()), Int(m_vScale * v.GetY()));
  30. m_DC.FillSolidRect(& rc, colVertex);
  31. }
  32. protected:
  33. CDC& m_DC;
  34. REAL m_hScale;
  35. REAL m_vScale;
  36. };
  37. // Function object to draw an edge.
  38. class drawEdge
  39. {
  40. public:
  41. drawEdge(CDC& dc, REAL hScale, REAL vScale) : m_DC(dc), m_hScale(hScale), m_vScale(vScale) {}
  42. void operator()(const edge& e) const
  43. {
  44. m_DC.MoveTo(Int(m_hScale * e.m_pV0->GetX()), Int(m_vScale * e.m_pV0->GetY()));
  45. m_DC.LineTo(Int(m_hScale * e.m_pV1->GetX()), Int(m_vScale * e.m_pV1->GetY()));
  46. }
  47. protected:
  48. CDC& m_DC;
  49. REAL m_hScale;
  50. REAL m_vScale;
  51. };
  52. // Function object to draw a triangle.
  53. class drawTriangle
  54. {
  55. public:
  56. drawTriangle(CDC& dc, REAL hScale, REAL vScale) : m_DC(dc), m_hScale(hScale), m_vScale(vScale) {}
  57. void operator()(const triangle& tri) const
  58. {
  59. const vertex * v0 = tri.GetVertex(0);
  60. m_DC.MoveTo(Int(m_hScale * v0->GetX()), Int(m_vScale * v0->GetY()));
  61. const vertex * v1 = tri.GetVertex(1);
  62. m_DC.LineTo(Int(m_hScale * v1->GetX()), Int(m_vScale * v1->GetY()));
  63. const vertex * v2 = tri.GetVertex(2);
  64. m_DC.LineTo(Int(m_hScale * v2->GetX()), Int(m_vScale * v2->GetY()));
  65. m_DC.LineTo(Int(m_hScale * v0->GetX()), Int(m_vScale * v0->GetY()));
  66. }
  67. protected:
  68. CDC& m_DC;
  69. REAL m_hScale;
  70. REAL m_vScale;
  71. };
  72. ////////////////////
  73. // CChildView
  74. CChildView::CChildView()
  75. : m_nVertices(200)
  76. , m_nTime(0)
  77. {
  78. }
  79. CChildView::~CChildView()
  80. {
  81. }
  82. BEGIN_MESSAGE_MAP(CChildView, CWnd)
  83. ON_WM_PAINT()
  84. ON_WM_SIZE()
  85. ON_WM_CREATE()
  86. ON_COMMAND(ID_FILE_OPTIONS, OnFileOptions)
  87. END_MESSAGE_MAP()
  88. BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
  89. {
  90. if (!CWnd::PreCreateWindow(cs))
  91. return FALSE;
  92. cs.dwExStyle |= WS_EX_CLIENTEDGE;
  93. cs.style &= ~WS_BORDER;
  94. cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
  95. ::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);
  96. return TRUE;
  97. }
  98. void CChildView::OnPaint() 
  99. {
  100. CPaintDC dc(this);
  101. dc.SetViewportOrg(m_hMargin, m_vMargin);
  102. // for_each(m_Triangles.begin(), m_Triangles.end(), drawTriangle(dc, m_hScale, m_vScale)); // for debugging
  103. // If we simply draw all the triangles, most of the edges are drawn twice.
  104. // Therefore, we first eliminate the superfluous edges.
  105. edgeSet edges;
  106. Delaunay d;
  107. d.TrianglesToEdges(m_Triangles, edges);
  108. for_each(edges.begin(), edges.end(), drawEdge(dc, m_hScale, m_vScale));
  109. for_each(m_Vertices.begin(), m_Vertices.end(), drawVertex(dc, m_hScale, m_vScale));
  110. CGdiObject * pOldFont = dc.SelectStockObject(FONT);
  111. int oldBkMode = dc.SetBkMode(TRANSPARENT);
  112. CString s;
  113. s.Format(IDS_FORMAT, m_nVertices, m_nTime);
  114. dc.TextOut(0, m_yText, s);
  115. dc.SetBkMode(oldBkMode);
  116. if (pOldFont) dc.SelectObject(pOldFont);
  117. }
  118. void CChildView::OnSize(UINT nType, int cx, int cy)
  119. {
  120. const int marginFactor = 20;
  121. CWnd::OnSize(nType, cx, cy);
  122. if (cx == 0 || cy == 0) return;
  123. CClientDC dc(this);
  124. CGdiObject * pOldFont = dc.SelectStockObject(FONT);
  125. CSize sz = dc.GetTextExtent(_T("M"), 1);
  126. if (pOldFont) dc.SelectObject(pOldFont);
  127. m_hMargin = cx / marginFactor;
  128. m_vMargin = cy / marginFactor;
  129. int w = cx - 2 * m_hMargin;
  130. int h = cy - 2 * m_vMargin - sz.cy;
  131. m_hScale = (REAL) w / (REAL) range;
  132. m_vScale = (REAL) h / (REAL) range;
  133. m_yText = h + sz.cy / 2;
  134. }
  135. int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  136. {
  137. if (CWnd::OnCreate(lpCreateStruct) == -1)
  138. return -1;
  139. NewVertices();
  140. return 0;
  141. }
  142. void CChildView::NewVertices(void)
  143. {
  144. // Fill m_Vertices with a new set of random vertices and calculate the Delaunay-triangulation.
  145. m_Vertices.clear();
  146. m_Triangles.clear();
  147. for (int i = 0; i < m_nVertices; i++)
  148. {
  149. int x = rand() % range;
  150. int y = rand() % range;
  151. m_Vertices.insert(vertex(x, y));
  152. }
  153. { // Block defines measuring time.
  154. QPerformanceTimer timer(m_nTime);
  155. Delaunay d;
  156. d.Triangulate(m_Vertices, m_Triangles);
  157. }
  158. }
  159. void CChildView::OnFileOptions()
  160. {
  161. COptionsDlg dlg;
  162. dlg.m_nVertices = m_nVertices;
  163. if (dlg.DoModal() == IDOK)
  164. {
  165. m_nVertices = dlg.m_nVertices;
  166. NewVertices();
  167. Invalidate();
  168. }
  169. }
  170. /////////////////////
  171. // COptionsDlg
  172. IMPLEMENT_DYNAMIC(COptionsDlg, CDialog)
  173. COptionsDlg::COptionsDlg(CWnd* pParent /*=NULL*/)
  174. : CDialog(COptionsDlg::IDD, pParent)
  175. , m_nVertices(0)
  176. {
  177. }
  178. COptionsDlg::~COptionsDlg()
  179. {
  180. }
  181. void COptionsDlg::DoDataExchange(CDataExchange* pDX)
  182. {
  183. CDialog::DoDataExchange(pDX);
  184. DDX_Text(pDX, IDC_NVERTICES, m_nVertices);
  185. DDV_MinMaxInt(pDX, m_nVertices, 0, 2000);
  186. DDX_Control(pDX, IDC_SNVERICES, c_spinVertices);
  187. }
  188. BEGIN_MESSAGE_MAP(COptionsDlg, CDialog)
  189. END_MESSAGE_MAP()
  190. BOOL COptionsDlg::OnInitDialog()
  191. {
  192. CDialog::OnInitDialog();
  193. c_spinVertices.SetRange(0, 2000);
  194. return TRUE;
  195. }