⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 describedlg.cpp

📁 B3次样条拟合
💻 CPP
字号:
// DescribeDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BSpline.h"
#include "DescribeDlg.h"
#include "BSplineDoc.h"
#include "BSplineView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define OFFSET 20   //设定坐标轴、B样条曲线与绘图区左下角点的偏移量

/////////////////////////////////////////////////////////////////////////////
// CDescribeDlg dialog


CDescribeDlg::CDescribeDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDescribeDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDescribeDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CDescribeDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDescribeDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDescribeDlg, CDialog)
	//{{AFX_MSG_MAP(CDescribeDlg)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDescribeDlg message handlers

void CDescribeDlg::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	
	/*场景布置 以及设置画笔,主要是绘制B样条基函数时需要预先准备的东西*/
	static CRect rectDsrbZone;   //用于选取整个绘图区所在的矩形
	CWnd * pWnd = GetDlgItem(IDC_POS);   //获取绘图区的指针
	//pWnd->Invalidate();	
	pWnd->UpdateWindow();   //加了这行代码的原因未知!
    pWnd->GetClientRect(&rectDsrbZone);
	CDC * pEditDC = pWnd->GetDC();
	CPen BlackPen;
	CPen RedPen;
	CPen GRAY_PEN;
	CFont font,bigfont;
	BlackPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
	RedPen.CreatePen(PS_SOLID,1,RGB(255,0,0));
    GRAY_PEN.CreatePen(PS_SOLID,1,RGB(0x33,0x33,0x33));	
	VERIFY(font.CreatePointFont(90, "Arial", pEditDC));
	VERIFY(bigfont.CreatePointFont(120, "Arial", pEditDC));
	pEditDC->SelectObject(&font);
	pEditDC->Rectangle(&rectDsrbZone);   //绘制一个矩形框,该矩形框即是预先设定的绘图区

    /*调用文档类数据*/
	CBSplineView *pViewWnd = (CBSplineView *)GetParent()->GetWindow(GW_CHILD);
	CBSplineDoc* pDoc = pViewWnd->GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->UpdateData();

	/*绘制B样条基函数图*/
	int umaxindex = pDoc->t.GetUpperBound();   //获取最大节点索引号
	double u,ud,umax,u_interval;
	CPoint pt;

	if(umaxindex == -1)
	{
		pEditDC->TextOut(100,20,"请先输入控制点!");
		return;   //无节点时直接返回
	}
	
	umax = pDoc->t.GetAt(umaxindex);  //获取u的最大值
    u_interval = umax * 0.01;  //设置节点取值间距
    int m = rectDsrbZone.BottomRight().x;    //B样条绘图区右下角的x坐标值
	int	l = rectDsrbZone.BottomRight().y;    //B样条绘图区右下角的y坐标值

	pEditDC->SelectObject(&GRAY_PEN);
	for(int j = 0;j <= pDoc->Knot_Index(umax);j++)
	{
		u = pDoc->Knot_Value(j);
		ud = pDoc->Knot_Value(j + pDoc->m_degree+1);

		pt.x = OFFSET + (int)((m - 3*OFFSET) *  u / umax + 0.5);
		pt.y = l - OFFSET - (int)(pDoc->Basic_Spline(j,pDoc->m_degree,u) * 100 + 0.5);
		pEditDC->MoveTo(pt);

		for(;u < ud;u += u_interval)
		{
			pt.x = OFFSET + (int)((m - 3*OFFSET) *  u / umax + 0.5);
			pt.y = l - OFFSET - (int)(pDoc->Basic_Spline(j,pDoc->m_degree,u) * 100 + 0.5);
			pEditDC->LineTo(pt);
			pEditDC->MoveTo(pt);
		}
		pt.x = OFFSET + (int)((m - 3*OFFSET) *  u / umax + 0.5);
	    pt.y = l - OFFSET - (int)(pDoc->Basic_Spline(j,pDoc->m_degree,ud) * 100 + 0.5);
		pEditDC->LineTo(pt);
	}

    /*绘制坐标轴*/
	pEditDC->SelectObject(&BlackPen);
	pEditDC->MoveTo(CPoint(OFFSET,l-OFFSET));
	pEditDC->LineTo(CPoint(m - OFFSET,l - OFFSET));
	pEditDC->MoveTo(CPoint(m - OFFSET,l - OFFSET));
	pEditDC->LineTo(CPoint(m - OFFSET -6,l - OFFSET + 2));
	pEditDC->MoveTo(CPoint(m - OFFSET,l - OFFSET));
	pEditDC->LineTo(CPoint(m - OFFSET -6,l - OFFSET - 2));
	pEditDC->MoveTo(CPoint(OFFSET,l-OFFSET));
	pEditDC->LineTo(CPoint(OFFSET,OFFSET));
	pEditDC->MoveTo(CPoint(OFFSET,OFFSET));
	pEditDC->LineTo(CPoint(OFFSET + 2,OFFSET + 6));
	pEditDC->MoveTo(CPoint(OFFSET,OFFSET));
	pEditDC->LineTo(CPoint(OFFSET - 2,OFFSET + 6));



	/*附加信息绘制,主要是关于B样条基函数图的一些说明信息*/
	CString str,strl;
	int index = 0;
	for(int i = 0;i <= umaxindex;i++)
	{		
		pt.x = (int)((pDoc->t.GetAt(i) * (m - 3*OFFSET)) / pDoc->t.GetAt(umaxindex)) + OFFSET;
		pt.y = l - OFFSET;
		str.Format("%1.2f",pDoc->t.GetAt(i));
		pEditDC->TextOut(pt.x - 10,pt.y + 1,str);
		pEditDC->Ellipse(CRect(CPoint(pt.x-2,pt.y-2),CPoint(pt.x+2,pt.y+2)));
		str.Format("值为%1.2f的节点:",pDoc->t.GetAt(i));
		int x_value = 40,r_value = pDoc->r.GetAt(i);
		for(int j = 0;j < r_value;j++)
		{
			strl.Format("u%d ",index + j);
			str += strl;
		}
		index += r_value;
		if(i > 5) x_value = 220;
		if(i > 11) x_value = 360;
		if(i < 18) pEditDC->TextOut(x_value,40 + 20 * (i % 6),str);
	}

	pEditDC->SelectObject(&bigfont);
	str.Format("B样条基函数图(%d次%d控制点",pDoc->m_degree,pDoc->m_ptArray.GetSize());

    switch(pDoc->m_type) {
    case 1:
		strl.Format("均匀B样条曲线)");
    	break;
    case 2:
		strl.Format("准均匀B样条曲线)");
    	break;
	case 3:
		strl.Format("分段贝奇尔曲线)");
		break;
	case 4:
		if(pDoc->m_subtype = 1)  strl.Format("非均匀B样条曲线_里森费尔德方法)");
		else	strl.Format("非均匀B样条曲线_哈特利-贾德方法)");
		break;
    default:
		strl.Format(")");
    }
	str += strl;
	pEditDC->TextOut(80,10,str);


    //释放内存空间		
	BlackPen.DeleteObject();
	RedPen.DeleteObject();
	GRAY_PEN.DeleteObject();
	font.DeleteObject();
	bigfont.DeleteObject();
	// Do not call CDialog::OnPaint() for painting messages
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -