//====== Новый класс "Вещественная точка" class CDPoint { public: double x; double y; //===== Вещественные координаты //====== Конструктор по умолчанию CDPoint() { x=0.; y=0.; } //====== Конструктор копирования CDPoint(const CDPoint& pt) { x = pt.x; y = pt.y; } //====== Конструктор с параметрами CDPoint(double xx, double yy) { x = xx; y = yy; } //====== Операция умножения (увеличение в n раз) CDPoint operator*(UINT n) { return CDPoint (x*n, y*n); } //====== Операция присваивания CDPoint& operator=(const CDPoint& pt) { x = pt.x; y = pt.y; return *this; // Возвращаем свой адрес } //====== Операция сложения двух точек CDPoint operator+(CDPoint& pt) { return CDPoint(x + pt.x, y + pt.y); } //====== Операция вычитания двух точек CDPoint operator-(CDPoint& pt) { return CDPoint(x - pt.x, y - pt.y); } // Метод для преобразования к типу CPoint (целая точка) CPoint ToInt() { return CPoint(int(x),int(y)); } //====== Операция сложения с записью результата void operator+=(CDPoint& pt) { x += pt.x; y += pt.y; } //====== Операция вычитания с записью результата void operator-=(CDPoint& pt) { x -= pt.x; y -= pt.y; } //====== Операция вычисления нормы вектора, заданного точкой double operator! () { return fabs(x) + fabs(y); } }; typedef vector > VECPTS; CMyDoc::CMyDoc() { //====== Вспомогательные переменные double pi = 4. * atan(1.), //====== Углы a1 = pi / 10., a2 = 3. * a1, //====== 2 характерные точки x1 = cos(a1), y1 = sin(a1), x2 = cos(a2), y2 = sin(a2); //==== Вещественные (World) координаты углов звезды m_Points.push_back(CDPoint( 0., 1.)); m_Points.push_back(CDPoint(-x2, -y2)); m_Points.push_back(CDPoint( x1, y1)); m_Points.push_back(CDPoint(-x1, y1)); m_Points.push_back(CDPoint( x2, -y2)); } void CMyView::OnSize(UINT nType, int cx, int cy) { //========== Вызов родительской версии CView::OnSize(nType, cx, cy); if (cx==0 || cy==0) return; //========= Запоминаем размеры окна Вида m_szView = CSize (cx, cy); } public: afx_msg void OnSize(UINT nType, int cx, int cy); void CMyView::OnInitialUpdate() { CView::OnInitialUpdate(); //=== Создаем ссылку на контейнер World-координат точек VECPTS& pts = GetDocument()->m_Points; UINT size = pts.size(); //====== Задаем размер контейнера логических точек m_Points.resize(size); for (UINT i=0; i < size; i++) m_Points[i] = (pts[i] * m_nLogZoom).ToInt(); } void CMyView::OnDraw(CDC* pDC) { CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); //====== Узнаем размер контейнера точек UINT nPoints = m_Points.size(); if (!nPoints) // Уходим, если он пуст return; // Сохраняем текущее состояние контекста (инструменты GDI) pDC->SaveDC(); // Создаем перо Windows для прорисовки контура полигона CPen pen (PS_SOLID,2,RGB(0,96,0)); //====== Выбираем его в контекст устройства pDC->SelectObject (&pen); //=== Создаем кисть Windows для заливки внутренних частей CBrush brush (RGB(240,255,250)); pDC->SelectObject (&brush); //====== Задаем режим преобразования координат pDC->SetMapMode(MM_ISOTROPIC); //====== Сдвиг в логической системе pDC->SetWindowOrg(0,0); //====== Сдвиг в физической системе pDC->SetViewportOrg (m_szView.cx/2, m_szView.cy/2); //====== Знаменатель коэффициента растяжения pDC->SetWindowExt(3*m_nLogZoom,3*m_nLogZoom); //====== Числитель коэффициента растяжения pDC->SetViewportExt (m_szView.cx, -m_szView.cy); //====== Изображаем полигон pDC->Polygon (&m_Points[0], nPoints); // Восстанавливаем контекст (предыдущие инструменты GDI) pDC->RestoreDC(-1); }