Bezier曲线绘制程序Word文档格式.docx
《Bezier曲线绘制程序Word文档格式.docx》由会员分享,可在线阅读,更多相关《Bezier曲线绘制程序Word文档格式.docx(14页珍藏版)》请在冰点文库上搜索。
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()!
m_vControlPoint.pop_back();
while(m_vXiShu.size()!
m_vXiShu.pop_back();
}
//析构函数
~CJjbView()
BOOLCJjbView:
PreCreateWindow(CREATESTRUCT&
cs)//定义窗口
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
returnCView:
PreCreateWindow(cs);
//CJjbViewdrawing
//刷新时绘图
voidCJjbView:
OnDraw(CDC*pDC)
CJjbDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
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:
//选择后的窗口状态
Bezier曲线,点击右键表示确定,移动节点改变形状。
"
);
d.TextOut(200,10,str);
for(i=0;
i<
m_vInputPoint.size();
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:
}
//CJjbViewprinting
OnPreparePrinting(CPrintInfo*pInfo)
//defaultpreparation
returnDoPreparePrinting(pInfo);
OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
addextrainitializationbeforeprinting
OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
addcleanupafterprinting
//CJjbViewdiagnostics
AssertValid()const
CView:
AssertValid();
Dump(CDumpContext&
dc)const
Dump(dc);
CJjbDoc*CJjbView:
GetDocument()//non-debugversionisinline
ASSERT(m_pDocument->
IsKindOf(RUNTIME_CLASS(CJjbDoc)));
return(CJjbDoc*)m_pDocument;
#endif//_DEBUG
//CJjbViewmessagehandlers
//用户点击菜单“Bezier曲线”时对应的动作
OnBezier()
Addyourcommandhandlercodehere
m_bIsChoosed=true;
}
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(&
iResponse=cJianpan.DoModal();
//InvalidateRect(&
//处理左键按下
OnLButtonDown(UINTnFlags,CPointpoint)
Addyourmessagehandlercodehereand/orcalldefault
m_eMouseStatus=LButtonDown;
if(m_bIsChoosed==true)
if(m_bStopDraw==false)//点击无效
m_vInputPoint.push_back(point);
Else//显示点
PointOnInputPoint(point);
if(m_bPointChoosed)//捕捉点
{
m_vInputPoint[m_iItemOfEditPoint]=point;
m_bMakeSure=!
m_bMakeSure;
}
OnLButtonDown(nFlags,point);
OnLButtonUp(UINTnFlags,CPointpoint)
OnLButtonUp(nFlags,point);
//处理鼠标移动
OnMouseMove(UINTnFlags,CPointpoint)
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;
return;
InvalidateRect(&
OnMouseMove(nFlags,point);
//处理右键按下
OnRButtonDown(UINTnFlags,CPointpoint)
m_eMouseStatus=RButtonDown;
//右键取得鼠标状态
m_bStopDraw=true;
//终止下一个取点
OnRButtonDown(nFlags,point);
//处理点与点之间的关系与状态
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个坐标点
SetPixel(x2,y2,(COLORREF)0x000000FF);
SetPixel(x3,y3,(COLORREF)0x000000FF);
SetPixel(x4,y4,(COLORREF)0x000000FF);
pDC->
MoveTo(x1,y1);
//描这4个坐标点的连线
LineTo(x2,y2);
LineTo(x3,y3);
LineTo(x4,y4);
doublex=0,y=0,ax,ay,s1,s2,s3,u;
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);
LineTo((int)x,(int)y);
if(u==0||u==1)
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)
for(inti=0;
n;
sum*=u;
returnsum;
//绘制Bezier曲线
DrawBezier(CDC*pDC)
intiNumber=m_vInputPoint.size();
MoveTo(m_vInputPoint[0]);
if(iNumber==1)
SetPixel(m_vInputPoint[0],(COLORREF)0x000000FF);
iNumber-1;
SetPixel(m_vInputPoint[i],(COLORREF)0x000000FF);
//点颜色
SetPixel(m_vInputPoint[i+1],(COLORREF)0x000000FF);
LineTo(m_vInputPoint[i+1]);
//相邻点之间的直线
doubleu,x,y;
SetPixel(m_vInputPoint[0],RGB(255,0,0));
u=u+0.001)//Bezier曲线算法
x=0;
y=0;
for(inti=0;
iNumber;
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;
//Bezier曲线算法说明结束
//动态显示鼠标点的坐标
PointOnInputPoint(CPointCheckedPoint)
doubledDistence;
for(i=0;
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<
m_iItemOfEditPoint=i;
m_bPointChoosed=true;
return;
m_bPointChoosed=false;
deCasteljau算法思想
Bezier曲线上的点,可以使用Bezier曲线方程直接计算,但使用deCasteljau递推算法则要简单的多。
1.递推公式
给定空间n+1个控制点Pi(i=0,1,2n)及参数t,deCasteljau递推算法表述为:
当n=3时,有
三次Bezier曲线递推如下
第一级递推:
第二级递推:
第三级递推: