📄 bsplineview.cpp
字号:
// BSplineView.cpp : implementation of the CBSplineView class
//
#include "stdafx.h"
#include "BSpline.h"
#include "BSplineDoc.h"
#include "BSplineView.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBSplineView
IMPLEMENT_DYNCREATE(CBSplineView, CView)
BEGIN_MESSAGE_MAP(CBSplineView, CView)
ON_WM_CONTEXTMENU()
//{{AFX_MSG_MAP(CBSplineView)
ON_COMMAND(ID_BSPLINE_SET, OnBsplineSet)
ON_COMMAND(ID_BSPLINE_INPUT, OnBsplineInput)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_DESCRIBE, OnDescribe)
ON_COMMAND(ID_BSPLINE_MODIFY, OnBsplineModify)
ON_COMMAND(ID_BSPLINE_DELETE, OnBsplineDelete)
ON_COMMAND(ID_CLEAN, OnClean)
ON_COMMAND(ID_BSPLINE_SELECT, OnBsplineSelect)
ON_COMMAND(ID_REFRESH, OnRefresh)
ON_UPDATE_COMMAND_UI(ID_BSPLINE_DELETE, OnUpdateBsplineDelete)
ON_UPDATE_COMMAND_UI(ID_BSPLINE_INPUT, OnUpdateBsplineInput)
ON_UPDATE_COMMAND_UI(ID_BSPLINE_MODIFY, OnUpdateBsplineModify)
ON_UPDATE_COMMAND_UI(ID_BSPLINE_SELECT, OnUpdateBsplineSelect)
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CBSplineView construction/destruction
CBSplineView::CBSplineView()
{
// TODO: add construction code here
m_state = 1; //控制点状态:0表示选择,1表示输入,2表示修改,3表示删除
m_isSelected = FALSE; //是否选择了一个控制点,用于修改和删除
}
CBSplineView::~CBSplineView()
{
}
BOOL CBSplineView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CBSplineView drawing
void CBSplineView::OnDraw(CDC* pDC)
{
CBSplineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
//绘制前的准备工作
CPen GRAY_PEN,BlackPen,REDPEN;
CBrush REDBRUSH;
REDBRUSH.CreateSolidBrush(RGB(255,0,0));
REDPEN.CreatePen(PS_SOLID,1,RGB(0xFF,0x00,0x00));
GRAY_PEN.CreatePen(PS_SOLID,1,RGB(0x99,0x99,0x99));
BlackPen.CreatePen(PS_SOLID,2,RGB(0x00,0x00,0x00));
pDC->SelectStockObject(BLACK_BRUSH);
pDC->SelectObject(&GRAY_PEN);
pDoc->UpdateData(); //根据控制点重新确定相异节点数组
//MenuHide();//隐藏已选择的菜单
//绘制控制多边形(可简化)
for(int i=0;i < pDoc->m_ptArray.GetSize()-1;i++)
{
CPoint pt = pDoc->m_ptArray.GetAt(i);
pDC->MoveTo(pt);
pDC->LineTo(pDoc->m_ptArray.GetAt(i+1));
pDC->Ellipse(CRect(CPoint(pt.x-2,pt.y-2),CPoint(pt.x+2,pt.y+2)));
}
int x = pDoc->m_ptArray.GetSize();
if(x > 0)
{
CPoint pt = pDoc->m_ptArray.GetAt(x-1);
pDC->Ellipse(CRect(CPoint(pt.x-2,pt.y-2),CPoint(pt.x+2,pt.y+2)));
}
//曲线绘制
pDC->SelectObject(&BlackPen);
int umaxindex = pDoc->m_ptArray.GetUpperBound();
int tmaxindex = pDoc->t.GetUpperBound();
if(umaxindex >= pDoc->m_degree)
{
double u,umax,u_interval;
umax = pDoc->Knot_Value(umaxindex + 1);
u_interval = umax * pDoc->m_length;
u = pDoc->Knot_Value(pDoc->m_degree);
CString str;
CPoint pt;
pDC->SelectStockObject(GRAY_BRUSH);
//用小直线段连接数据点,得到曲线
pDC->MoveTo(pDoc->Dbordv(u));
for(;u < umax;u += u_interval)
{
pt = pDoc->Dbordv(u);
pDC->LineTo(pt);
pDC->MoveTo(pt);
}
pDC->LineTo(pDoc->Dbordv(umax - 0.001 * u_interval));
//绘制曲线的连接点
pDC->SelectObject(&REDBRUSH);
pDC->SelectObject(&REDPEN);
if(pDoc->m_type != 1) //当曲线不为均匀B样条曲线时
{
for(int i = 1;i < tmaxindex;i++)
{
pt = pDoc->Dbordv(pDoc->t[i]);
pDC->Ellipse(CRect(CPoint(pt.x-2,pt.y-2),CPoint(pt.x+2,pt.y+2)));
}
}
else
{
for(int i = pDoc->m_degree+1;i < pDoc->m_ptArray.GetSize();i++)
{
pt = pDoc->Dbordv(pDoc->t[i]);
pDC->Ellipse(CRect(CPoint(pt.x-2,pt.y-2),CPoint(pt.x+2,pt.y+2)));
}
}
}
//当选择了一点之后,将此点变为红色
if(m_isSelected == TRUE)
{
pDC->SelectObject(&REDBRUSH);
pDC->SelectObject(&REDPEN);
CPoint pt = pDoc->m_ptArray[m_index];
pDC->Ellipse(CRect(CPoint(pt.x-3,pt.y-3),CPoint(pt.x+3,pt.y+3)));
}
REDBRUSH.DeleteObject();
REDPEN.DeleteObject();
GRAY_PEN.DeleteObject();
BlackPen.DeleteObject();
}
/////////////////////////////////////////////////////////////////////////////
// CBSplineView printing
BOOL CBSplineView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CBSplineView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CBSplineView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CBSplineView diagnostics
#ifdef _DEBUG
void CBSplineView::AssertValid() const
{
CView::AssertValid();
}
void CBSplineView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CBSplineDoc* CBSplineView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBSplineDoc)));
return (CBSplineDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CBSplineView message handlers
void CBSplineView::OnContextMenu(CWnd*, CPoint point)
{
// CG: This block was added by the Pop-up Menu component
{
if (point.x == -1 && point.y == -1){
//keystroke invocation
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
point = rect.TopLeft();
point.Offset(5, 5);
}
CMenu menu;
VERIFY(menu.LoadMenu(CG_IDR_POPUP_BSPLINE_VIEW));
pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
while (pWndPopupOwner->GetStyle() & WS_CHILD)
pWndPopupOwner = pWndPopupOwner->GetParent();
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
pWndPopupOwner);
}
}
void CBSplineView::OnBsplineSet()
{
// TODO: Add your command handler code here
m_dlg.DoModal();
}
void CBSplineView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CBSplineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
SetCursor(LoadCursor(NULL, IDC_CROSS));
if(m_state != 1)
{
for(int i = 0;i <= pDoc->m_ptArray.GetUpperBound();i++)
{
if(pDoc->m_ptArray[i].x - 5 <= point.x &&
point.x <= pDoc->m_ptArray[i].x + 5 &&
pDoc->m_ptArray[i].y - 5 <= point.y &&
point.y <= pDoc->m_ptArray[i].y + 5
)
{
m_isSelected == TRUE ? m_isSelected = FALSE : m_isSelected = TRUE;
//修改状态
m_index = i; //获得所选择点的索引值
//m_ptOrigin = point;
break;
}
}
}
CView::OnLButtonDown(nFlags, point);
}
void CBSplineView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CBSplineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
SetCursor(LoadCursor(NULL, IDC_CROSS));
if(m_state == 1) //输入控制点
{
//将控制点逐个输入数组中
pDoc->m_ptArray.Add(point);
}
else if(m_state == 2 && m_isSelected == TRUE) //修改控制点
{
pDoc->m_ptArray[m_index] = point;
m_isSelected = FALSE;
}
else if(m_state == 3 && m_isSelected == TRUE) //删除控制点
{
pDoc->m_ptArray.RemoveAt(m_index);
m_isSelected = FALSE;
}
//pDoc->UpdateData();
Invalidate();
CView::OnLButtonUp(nFlags, point);
}
void CBSplineView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CBSplineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
SetCursor(LoadCursor(NULL, IDC_CROSS));
if(m_state == 2 && m_isSelected == TRUE)
{
pDoc->m_ptArray[m_index] = point;
//pDoc->UpdateData();
Invalidate();
}
CView::OnMouseMove(nFlags, point);
}
void CBSplineView::OnClean()
{
// TODO: Add your command handler code here
CBSplineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDoc->m_ptArray.RemoveAll();
Invalidate();
}
void CBSplineView::OnRefresh()
{
// TODO: Add your command handler code here
Invalidate();
}
void CBSplineView::OnDescribe()
{
// TODO: Add your command handler code here
m_desdlg.DoModal();
}
void CBSplineView::OnBsplineSelect()
{
// TODO: Add your command handler code here
m_state = 0;
}
void CBSplineView::OnBsplineInput()
{
// TODO: Add your command handler code here
m_state = 1;
}
void CBSplineView::OnBsplineModify()
{
// TODO: Add your command handler code here
m_state = 2;
}
void CBSplineView::OnBsplineDelete()
{
// TODO: Add your command handler code here
m_state = 3;
CBSplineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(m_isSelected == TRUE) //删除控制点
{
pDoc->m_ptArray.RemoveAt(m_index);
m_isSelected = FALSE;
Invalidate();
}
}
void CBSplineView::OnUpdateBsplineSelect(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(m_state == 0) pCmdUI->Enable(FALSE);
}
void CBSplineView::OnUpdateBsplineInput(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(m_state == 1) pCmdUI->Enable(FALSE);
}
void CBSplineView::OnUpdateBsplineModify(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(m_state == 2) pCmdUI->Enable(FALSE);
}
void CBSplineView::OnUpdateBsplineDelete(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(m_state == 3) pCmdUI->Enable(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -