📄 convexhullview.cpp
字号:
// ConvexHullView.cpp : implementation of the CConvexHullView class
//
#include "stdafx.h"
#include "ConvexHull.h"
#include "MainFrm.h"
#include "ConvexHullDoc.h"
#include "ConvexHullView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CConvexHullView
IMPLEMENT_DYNCREATE(CConvexHullView, CView)
BEGIN_MESSAGE_MAP(CConvexHullView, CView)
//{{AFX_MSG_MAP(CConvexHullView)
ON_WM_MOUSEMOVE()
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_TIMER()
ON_WM_RBUTTONDOWN()
ON_WM_SETCURSOR()
ON_WM_SIZE()
ON_WM_DESTROY()
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CConvexHullView construction/destruction
//##ModelId=443378C802AC
CConvexHullView::CConvexHullView()
{
// TODO: add construction code here
m_AxisXOffset = 0;
m_AxisYOffset = 0;
m_ZoomRatio = 10;
m_IsDragging = FALSE;
m_ClientStatus = CLIENT_STATUS_NONE;
m_IsDemoPaused = FALSE;
m_BufferDCReady = FALSE;
m_pBufferOldBitmap = NULL;
m_BufferDC.CreateCompatibleDC(NULL);
m_ScaleFont.CreateFont(
12, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
"宋体"); // lpszFacename
}
//##ModelId=443378C803B0
CConvexHullView::~CConvexHullView()
{
}
//##ModelId=443378C8036D
BOOL CConvexHullView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CConvexHullView drawing
//##ModelId=443378C8036A
void CConvexHullView::OnDraw(CDC* pDC)
{
CRect r;
GetClientRect(r);
DrawView(&m_BufferDC, r);
pDC->BitBlt(0, 0, r.Width(), r.Height(), &m_BufferDC, 0, 0, SRCCOPY);
}
//##ModelId=443378C80357
void CConvexHullView::DrawView(CDC* pDC, CRect &r)
{
CConvexHullDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
dse::point2d p, p1;
CString s, fmtString;
CPen *oldPen;
CPen pen;
CBrush *oldBrush;
CBrush brush;
CFont *oldFont;
int scale_i;
dse::size_t i, count;
dse::vector<dse::pair<int, double> > clientScaleXs, clientScaleYs;
brush.CreateSolidBrush(0xffffff);
pDC->FillRect(r, &brush);
brush.DeleteObject();
pDC->SetBkMode(TRANSPARENT);
//计算主坐标轴在客户区的位置
AxisPointToClientPoint(dse::point2d(0,0), r, p);
double clientAxisX = p.x, clientAxisY = p.y;
//计算刻度所需的数据
ClientPointToAxisPoint(dse::point2d(0,0), r, p);
double axisLeft = p.x, axisTop = p.y; //可见坐标范围
ClientPointToAxisPoint(dse::point2d(r.Width(), r.Height()), r, p);
double axisRight = p.x, axisBottom = p.y; //可见坐标范围
ClientPointToAxisPoint(dse::point2d(60, 0), r, p);
double axisScale = p.x - axisLeft; //坐标刻度长度,以客户区的60个像素左右作为一个刻度
//对刻度长度进行修正,保证整的刻度
double n;
if(axisScale < 1)
{
for(n = 1; axisScale < 1; n *= 10)
axisScale *= 10;
axisScale = (int)axisScale;
axisScale /= n;
fmtString.Format("%%.%dlf", (int)log10(n));
}
else
{
for(n = 1; axisScale >= 10; n *= 10)
axisScale /= 10;
axisScale = (int)axisScale;
axisScale *= n;
fmtString.Format("%%.0lf");
}
//计算坐标刻度反映在客户区实际的实际长度
AxisPointToClientPoint(dse::point2d(axisScale, 0.0), r, p);
AxisPointToClientPoint(dse::point2d(0.0, 0.0), r, p1);
double clientScaleStep = p.x - p1.x;
//计算各个坐标在屏幕上对应的位置(pair.first),以及刻度(pair.second),并保存
for(scale_i = (int)((0 - clientAxisX) / clientScaleStep - 1); scale_i < ((double)r.Width() - clientAxisX) / clientScaleStep + 1; scale_i++)
clientScaleXs.push_back(dse::make_pair(
(int)(clientAxisX + clientScaleStep * scale_i),
axisScale * scale_i
)
);
for(scale_i = (int)((0 - clientAxisY) / clientScaleStep - 1); scale_i < ((double)r.Height() - clientAxisY) / clientScaleStep + 1; scale_i++)
clientScaleYs.push_back(dse::make_pair(
(int)(clientAxisY + clientScaleStep * scale_i),
- axisScale * scale_i
)
);
//绘制辅助坐标轴
pen.CreatePen(PS_SOLID, 1, 0x00e0e0e0);
oldPen = pDC->SelectObject(&pen);
for(i = 0; i < clientScaleYs.size(); i++)
{
pDC->MoveTo(0 , clientScaleYs[i].first);
pDC->LineTo(r.Width(), clientScaleYs[i].first);
}
for(i = 0; i < clientScaleXs.size(); i++)
{
pDC->MoveTo(clientScaleXs[i].first, 0);
pDC->LineTo(clientScaleXs[i].first, r.Height());
}
pDC->SelectObject(oldPen);
pen.DeleteObject();
//绘制主坐标轴和刻度
pen.CreatePen(PS_SOLID, 1, (ULONG)0x00000000);
oldFont = pDC->SelectObject(&m_ScaleFont);
oldPen = pDC->SelectObject(&pen);
if(0 <= clientAxisY && clientAxisY < r.Height())
{
pDC->MoveTo(0, (int)clientAxisY);
pDC->LineTo(r.Width(), (int)clientAxisY);
for(i = 0; i < clientScaleXs.size(); i++)
{
pDC->MoveTo(clientScaleXs[i].first, (int)clientAxisY);
pDC->LineTo(clientScaleXs[i].first, (int)clientAxisY + 10);
s.Format(fmtString, clientScaleXs[i].second);
pDC->TextOut(clientScaleXs[i].first - 2, (int)clientAxisY + 12, s);
}
}
if(0 <= clientAxisX && clientAxisX < r.Width())
{
pDC->MoveTo((int)clientAxisX, 0);
pDC->LineTo((int)clientAxisX, r.Height());
for(i = 0; i < clientScaleYs.size(); i++)
{
pDC->MoveTo((int)clientAxisX , clientScaleYs[i].first);
pDC->LineTo((int)clientAxisX - 10, clientScaleYs[i].first);
if(IS_ZERO(clientScaleYs[i].second))
continue;
s.Format(fmtString , clientScaleYs[i].second);
pDC->TextOut((int)clientAxisX - 40, clientScaleYs[i].first + 2, s);
}
}
pDC->SelectObject(oldPen);
pDC->SelectObject(oldFont);
pen.DeleteObject();
//凸包的点
dse::convex_hull &ch = pDoc->GetConvexHull();
//pen.CreatePen(PS_SOLID, 1, 0x00ffff);
pen.CreatePen(PS_SOLID, 1, 0x0000ff);
brush.CreateSolidBrush(0x0000ff);
oldBrush = pDC->SelectObject(&brush);
oldPen = pDC->SelectObject(&pen);
count = ch.get_points_count();
for(i = 0; i < count; i++)
{
AxisPointToClientPoint(ch.get_point(i), r, p);
pDC->Ellipse((int)p.x-3, (int)p.y-3, (int)p.x+3, (int)p.y+3);
}
pDC->SelectObject(oldBrush);
pDC->SelectObject(oldPen);
brush.DeleteObject();
pen.DeleteObject();
//凸包的边
pen.CreatePen(PS_SOLID, 1, 0xff0000);
oldPen = pDC->SelectObject(&pen);
count = ch.get_convex_points_count();
for(i = 1; i <= count; i++)
{
AxisPointToClientPoint(ch.get_convex_point(i-1), r, p);
pDC->MoveTo((int)p.x, (int)p.y);
if(i == count)
{
if(!ch.finished()) //如果没有完成,不必画最后一条边
break;
AxisPointToClientPoint(ch.get_convex_point(0), r, p);
}
else
AxisPointToClientPoint(ch.get_convex_point(i), r, p);
pDC->LineTo((int)p.x, (int)p.y);
}
pDC->SelectObject(oldPen);
pen.DeleteObject();
//如果是演示状态,并且有点需要处理,则用特殊颜色把当前处理的过程显示出来
if(IsClientStatus_Demo() && ch.has_next_point())
{
pen.CreatePen(PS_SOLID, 1, 0xff00ff);
brush.CreateSolidBrush(0x00ff00);
oldPen = pDC->SelectObject(&pen);
oldBrush = pDC->SelectObject(&brush);
count = ch.get_convex_points_count();
AxisPointToClientPoint(ch.get_convex_point(count - 1), r, p);
pDC->Ellipse((int)p.x-4, (int)p.y-4, (int)p.x+4, (int)p.y+4);
pDC->MoveTo((int)p.x, (int)p.y);
AxisPointToClientPoint(ch.get_point(ch.get_next_point_index()), r, p);
pDC->LineTo((int)p.x, (int)p.y);
pDC->Ellipse((int)p.x-4, (int)p.y-4, (int)p.x+4, (int)p.y+4);
pDC->SelectObject(oldBrush);
pDC->SelectObject(oldPen);
pen.DeleteObject();
brush.DeleteObject();
}
}
/////////////////////////////////////////////////////////////////////////////
// CConvexHullView printing
//##ModelId=443378C80393
BOOL CConvexHullView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
//##ModelId=443378C8039C
void CConvexHullView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
//##ModelId=443378C803A6
void CConvexHullView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CConvexHullView diagnostics
#ifdef _DEBUG
//##ModelId=443378C803B2
void CConvexHullView::AssertValid() const
{
CView::AssertValid();
}
//##ModelId=443378C803BB
void CConvexHullView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
//##ModelId=443378C8030B
CConvexHullDoc* CConvexHullView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CConvexHullDoc)));
return (CConvexHullDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CConvexHullView message handlers
//##ModelId=443378C80376
BOOL CConvexHullView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}
//##ModelId=443378C8038B
void CConvexHullView::OnInitialUpdate()
{
CView::OnInitialUpdate();
SetClientStatus(CLIENT_STATUS_NONE);
ZoomAdjust();
}
/*
坐标变换,从客户端窗口坐标变换到坐标轴坐标
*/
//##ModelId=443378C80342
VOID CConvexHullView::ClientPointToAxisPoint(dse::point2d &p, CRect &clientRect, dse::point2d &out)
{
double cmX, cmY;
cmX = clientRect.left + clientRect.Width() / 2;
cmY = clientRect.top + clientRect.Height() / 2;
double sX, sY;
sX = p.x - cmX;
sY = -(p.y - cmY);
sX /= m_ZoomRatio;
sY /= m_ZoomRatio;
sX -= m_AxisXOffset;
sY -= m_AxisYOffset;
out.x = sX;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -