Bezier曲线绘制程序.docx

上传人:b****5 文档编号:11802785 上传时间:2023-04-02 格式:DOCX 页数:14 大小:63.21KB
下载 相关 举报
Bezier曲线绘制程序.docx_第1页
第1页 / 共14页
Bezier曲线绘制程序.docx_第2页
第2页 / 共14页
Bezier曲线绘制程序.docx_第3页
第3页 / 共14页
Bezier曲线绘制程序.docx_第4页
第4页 / 共14页
Bezier曲线绘制程序.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

Bezier曲线绘制程序.docx

《Bezier曲线绘制程序.docx》由会员分享,可在线阅读,更多相关《Bezier曲线绘制程序.docx(14页珍藏版)》请在冰豆网上搜索。

Bezier曲线绘制程序.docx

Bezier曲线绘制程序

Bezier曲线绘制程序:

#include"stdafx.h"

#include"Jjb.h"

#include"JjbDoc.h"

#include"JjbView.h"

#ifdef_DEBUG

#definenewDEBUG_NEW

#undefTHIS_FILE

staticcharTHIS_FILE[]=__FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

//CJjbView

IMPLEMENT_DYNCREATE(CJjbView,CView)

BEGIN_MESSAGE_MAP(CJjbView,CView)

//{{AFX_MSG_MAP(CJjbView)

ON_COMMAND(ID_BEZIER,OnBezier)

ON_WM_LBUTTONDOWN()

ON_WM_LBUTTONUP()

ON_WM_MOUSEMOVE()

ON_WM_RBUTTONDOWN()

//}}AFX_MSG_MAP

//Standardprintingcommands

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()

/////////////////////////////////////////////////////////////////////////////

//CJjbViewconstruction/destruction

doubleJ(intn,inti);

doubleC(intn,inti);

doubleN(doubleu,intn);

intJieCheng(intn);

//构造函数

CJjbView:

:

CJjbView()

{

//TODO:

addconstructioncodehere

m_bIsChoosed=false;

m_bStopDraw=false;

m_bMakeSure=false;

m_eChooseType=Bezier;

while(m_vInputPoint.size()!

=0)

{

m_vInputPoint.pop_back();

}

while(m_vControlPoint.size()!

=0)

{

m_vControlPoint.pop_back();

}

while(m_vXiShu.size()!

=0)

{

m_vXiShu.pop_back();

}

}

//析构函数

CJjbView:

:

~CJjbView()

{

while(m_vInputPoint.size()!

=0)

{

m_vInputPoint.pop_back();

}

while(m_vControlPoint.size()!

=0)

{

m_vControlPoint.pop_back();

}

while(m_vXiShu.size()!

=0)

{

m_vXiShu.pop_back();

}

}

BOOLCJjbView:

:

PreCreateWindow(CREATESTRUCT&cs)//定义窗口

{

//TODO:

ModifytheWindowclassorstylesherebymodifying

//theCREATESTRUCTcs

returnCView:

:

PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////////

//CJjbViewdrawing

//刷新时绘图

voidCJjbView:

:

OnDraw(CDC*pDC)

{

CJjbDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

GetClientRect(&rect);

if(m_eMouseStatus==MouseMove&&m_bStopDraw==false)

{

m_vInputPoint.push_back(m_cMovePoint);

}

CStringstr;

CClientDCd(this);

inti;

if(m_bIsChoosed==true)

{

if(m_bStopDraw==false)

{

str.Format("X=%d,y=%d]",m_cMovePoint.x,m_cMovePoint.y);

d.TextOut(m_cMovePoint.x+10,m_cMovePoint.y+10,str);

}

switch(m_eChooseType)//菜单选择

{

caseBezier:

//选择后的窗口状态

str.Format("Bezier曲线,点击右键表示确定,移动节点改变形状。

");

d.TextOut(200,10,str);

for(i=0;i

{

pDC->Ellipse(m_vInputPoint[i].x-4,m_vInputPoint[i].y-4,

m_vInputPoint[i].x+4,m_vInputPoint[i].y+4);

}

DrawBezier(pDC);//绘制显示Bezier曲线

break;

default:

break;

}

}

if(m_eMouseStatus==MouseMove&&m_bStopDraw==false)

{

m_vInputPoint.pop_back();

}

}

/////////////////////////////////////////////////////////////////////////////

//CJjbViewprinting

BOOLCJjbView:

:

OnPreparePrinting(CPrintInfo*pInfo)

{

//defaultpreparation

returnDoPreparePrinting(pInfo);

}

voidCJjbView:

:

OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)

{

//TODO:

addextrainitializationbeforeprinting

}

voidCJjbView:

:

OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)

{

//TODO:

addcleanupafterprinting

}

/////////////////////////////////////////////////////////////////////////////

//CJjbViewdiagnostics

#ifdef_DEBUG

voidCJjbView:

:

AssertValid()const

{

CView:

:

AssertValid();

}

voidCJjbView:

:

Dump(CDumpContext&dc)const

{

CView:

:

Dump(dc);

}

CJjbDoc*CJjbView:

:

GetDocument()//non-debugversionisinline

{

ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CJjbDoc)));

return(CJjbDoc*)m_pDocument;

}

#endif//_DEBUG

/////////////////////////////////////////////////////////////////////////////

//CJjbViewmessagehandlers

//用户点击菜单“Bezier曲线”时对应的动作

voidCJjbView:

:

OnBezier()

{

//TODO:

Addyourcommandhandlercodehere

m_eChooseType=Bezier;

m_bIsChoosed=true;

m_bStopDraw=false;

while(m_vInputPoint.size()!

=0)

{

m_vInputPoint.pop_back();

}

while(m_vControlPoint.size()!

=0)

{

m_vControlPoint.pop_back();

}

while(m_vXiShu.size()!

=0)

{

m_vXiShu.pop_back();

}

CInputDialogcInputDialog;

CJianPancJianpan;

intiResponse;

iResponse=cInputDialog.DoModal();

if(iResponse==IDOK)

{

iResponse=cJianpan.DoModal();

m_bStopDraw=true;

while(iResponse==IDOK)

{

m_vInputPoint.push_back(cJianpan.m_cInputPoint);

InvalidateRect(&rect);

iResponse=cJianpan.DoModal();

//InvalidateRect(&rect);

}

}

}

}

//处理左键按下

voidCJjbView:

:

OnLButtonDown(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

m_eMouseStatus=LButtonDown;

if(m_bIsChoosed==true)

{

if(m_bStopDraw==false)//点击无效

{

m_vInputPoint.push_back(point);

InvalidateRect(&rect);

}

Else//显示点

{

PointOnInputPoint(point);

if(m_bPointChoosed)//捕捉点

{

m_vInputPoint[m_iItemOfEditPoint]=point;

m_bMakeSure=!

m_bMakeSure;

}

}

}

CView:

:

OnLButtonDown(nFlags,point);

}

voidCJjbView:

:

OnLButtonUp(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

CView:

:

OnLButtonUp(nFlags,point);

}

//处理鼠标移动

voidCJjbView:

:

OnMouseMove(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

m_cMovePoint=point;

m_eMouseStatus=MouseMove;

if(m_bStopDraw==true)//判断鼠标捕捉点是否成功

{

if(m_bPointChoosed==true&&m_bMakeSure==false)//点坐标赋予给鼠标,随鼠标变化

{

m_vInputPoint[m_iItemOfEditPoint].x=point.x;

m_vInputPoint[m_iItemOfEditPoint].y=point.y;

InvalidateRect(&rect);

}

return;

}

InvalidateRect(&rect);

CView:

:

OnMouseMove(nFlags,point);

}

//处理右键按下

voidCJjbView:

:

OnRButtonDown(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

m_eMouseStatus=RButtonDown;//右键取得鼠标状态

m_bStopDraw=true;//终止下一个取点

InvalidateRect(&rect);

CView:

:

OnRButtonDown(nFlags,point);

}

//处理点与点之间的关系与状态

voidCJjbView:

:

DrawB(CDC*pDC,CPointpoint1,CPointpoint2,CPointpoint3,CPointpoint4)

{

intx1,y1,x2,y2,x3,y3,x4,y4;//传递4个点坐标值

x1=point1.x;

y1=point1.y;

x2=point2.x;

y2=point2.y;

x3=point3.x;

y3=point3.y;

x4=point4.x;

y4=point4.y;

pDC->SetPixel(x1,y1,(COLORREF)0x000000FF);//用红颜色描这4个坐标点

pDC->SetPixel(x2,y2,(COLORREF)0x000000FF);

pDC->SetPixel(x3,y3,(COLORREF)0x000000FF);

pDC->SetPixel(x4,y4,(COLORREF)0x000000FF);

pDC->MoveTo(x1,y1);//描这4个坐标点的连线

pDC->LineTo(x2,y2);

pDC->LineTo(x3,y3);

pDC->LineTo(x4,y4);

doublex=0,y=0,ax,ay,s1,s2,s3,u;

pDC->SetPixel(x1,y1,RGB(255,0,0));

ax=(x1+4*x2+x3)/6.0;

ay=(y1+4*y2+y3)/6.0;

for(u=0;u<=1;u=u+0.001)

{

s1=u;

s2=s1*s1;

s3=s1*s1*s1;

x=ax+((x3-x1)/2.0)*s1+((x1-2*x2+x3)/2.0)*s2+((x4-3*x3+3*x2-x1)/6.0)*s3;

y=ay+((y3-y1)/2.0)*s1+((y1-2*y2+y3)/2.0)*s2+((y4-3*y3+3*y2-y1)/6.0)*s3;

if(u==0)

{

pDC->MoveTo((int)ax,(int)ay);

}

pDC->LineTo((int)x,(int)y);

if(u==0||u==1)

{

pDC->Ellipse(x-3,y-3,x+3,y+3);

}

}

return;

}

//求n!

,进入Bezier曲线算法说明开始

intJieCheng(intn)

{

if(n==1||n==0)

{

return1;

}

else

{

returnn*JieCheng(n-1);

}

}

//求组合排列

doubleC(intn,inti)

{

return((double)JieCheng(n))/((double)(JieCheng(i)*JieCheng(n-i)));

}

//求一个数u的num次方

doubleN(doubleu,intn)

{

doublesum=1.0;

if(n==0)

{

return1;

}

for(inti=0;i

{

sum*=u;

}

returnsum;

}

//绘制Bezier曲线

voidCJjbView:

:

DrawBezier(CDC*pDC)

{

intiNumber=m_vInputPoint.size();

pDC->MoveTo(m_vInputPoint[0]);

if(iNumber==1)

{

pDC->SetPixel(m_vInputPoint[0],(COLORREF)0x000000FF);

return;

}

for(inti=0;i

{

pDC->SetPixel(m_vInputPoint[i],(COLORREF)0x000000FF);//点颜色

pDC->SetPixel(m_vInputPoint[i+1],(COLORREF)0x000000FF);

pDC->LineTo(m_vInputPoint[i+1]);//相邻点之间的直线

}

doubleu,x,y;

pDC->SetPixel(m_vInputPoint[0],RGB(255,0,0));

pDC->MoveTo(m_vInputPoint[0]);

for(u=0;u<=1;u=u+0.001)//Bezier曲线算法

{

x=0;y=0;

for(inti=0;i

{

x+=C(iNumber-1,i)*N(u,i)*N((1-u),(iNumber-1-i))*m_vInputPoint[i].x;

y+=C(iNumber-1,i)*N(u,i)*N((1-u),(iNumber-1-i))*m_vInputPoint[i].y;

}

pDC->LineTo((int)x,(int)y);

}

return;

}

//Bezier曲线算法说明结束

//动态显示鼠标点的坐标

voidCJjbView:

:

PointOnInputPoint(CPointCheckedPoint)

{

doubledDistence;

inti;

for(i=0;i

{

dDistence=(CheckedPoint.x-m_vInputPoint[i].x)*(CheckedPoint.x-m_vInputPoint[i].x)+

(CheckedPoint.y-m_vInputPoint[i].y)*(CheckedPoint.y-m_vInputPoint[i].y)-4*4;

if(dDistence<=0)

{

m_iItemOfEditPoint=i;

m_bPointChoosed=true;

return;

}

}

m_bPointChoosed=false;

return;

}

deCasteljau算法思想

Bezier曲线上的点,可以使用Bezier曲线方程直接计算,但使用deCasteljau递推算法则要简单的多。

1.递推公式

给定空间n+1个控制点Pi(i=0,1,2n)及参数t,deCasteljau递推算法表述为:

 

当n=3时,有

 

三次Bezier曲线递推如下

第一级递推:

第二级递推:

第三级递推:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学研究 > 教学案例设计

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1