//*******************************************************
//捕捉鼠标左键按下消息,获得两个起始控制点的坐标
//*******************************************************
void CDrawCurvesView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
oldPoint = point;
newPoint = point;
CurveCtrlPoints[count++] = point;
SetCapture();
isLButtonDown = true;
CRect rect;
GetClientRect(&rect);
ClientToScreen(&rect); //用用户区坐标重新计算屏幕坐标
ClipCursor(&rect); //限制光标在用户区内
//默认处理,调用基类消息处理函数
CView::OnLButtonDown(nFlags, point);
}
//******************************************
//按下键盘清除客户区的内容,为下次绘制作准备
//******************************************
void CDrawCurvesView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
count = 0;
Invalidate();
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
//******************
//矩阵乘法
//******************
void CDrawCurvesView::MultiMatrix(int a[4][4],double b[4][2])
{
int i,j,k;
for(i=0;i<4;i++)
for(j=0;j<2;j++)
result[i][j] = 0;
for(i=0;i<2;i++)
for(j=0;j<4;j++)
for(k=0;k<4;k++)
result[j][i] += a[j][k]*b[k][i];
}
//***************************************
// 捕捉鼠标移动消息,绘制橡皮筋线,
//作为Hermite曲线的控制点处的切线
//***************************************
void CDrawCurvesView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(isLButtonDown)
{
CView::OnMouseMove(nFlags, point);
CClientDC dc(this);
dc.SetROP2(R2_NOT);
dc.MoveTo(newPoint);
dc.LineTo(oldPoint);
dc.MoveTo(newPoint);
dc.LineTo(point);
oldPoint = point;
}
}
//*****************************************************
//捕捉鼠标左键松开消息,并在捕捉到第四个控制点
//后,根据从菜单选择项的不同,开始绘制不同曲线
//******************************************************
void CDrawCurvesView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
isLButtonDown=false;//标志鼠标释放
ReleaseCapture();//释放鼠标捕捉
ClipCursor(NULL);//
CurveCtrlPoints[count++] = point;
if(count == 4)
{
CClientDC dc(this);
CPen pen;
pen.CreatePen(PS_SOLID,3,RGB(255,0,0));
dc.SelectObject(pen);
switch(type)
{
case HERMITE:
DrawHermiteCurve(dc,200);
break;
case BEZIER:
DrawBezierCurve(dc,400);
break;
}
pen.DeleteObject();
}
CView::OnLButtonUp(nFlags, point);
}
//*******************************************
//菜单响应函数,当菜单项选为Hermite时,
//绘制曲线的类型设置为HERMITE
//*******************************************
void CDrawCurvesView::OnHermite()
{
// TODO: Add your command handler code here
type = HERMITE;
}
//******************************************
//菜单响应函数,当菜单项选为Bezier时,
//绘制曲线的类型设置为BEZIER
//******************************************
void CDrawCurvesView::OnBezier()
{
// TODO: Add your command handler code here
type = BEZIER;
}
//**************************
//绘制hermite曲线的函数
//**************************
void CDrawCurvesView::DrawHermiteCurve(CDC &dc,int nPoints)
{
int a[4][4] =
{
{2,-2,1,1},
{-3,3,-2,-1},
{0,0,1,0},
{1,0,0,0}
};
double b[4][2] = {
{CurveCtrlPoints[0].x,CurveCtrlPoints[0].y},
{CurveCtrlPoints[2].x,CurveCtrlPoints[2].y},
{CurveCtrlPoints[1].x-CurveCtrlPoints[0].x,CurveCtrlPoints[1].y-CurveCtrlPoints[1].y},
{CurveCtrlPoints[3].x-CurveCtrlPoints[2].x,CurveCtrlPoints[3].y-CurveCtrlPoints[2].y}
};
CPoint *pt=new CPoint[nPoints];
double delt = 1.0/nPoints;
double u = 0.0;
MultiMatrix(a,b);
for(int i = 0; i < nPoints; i++)
{
pt[i].x =(int) (pow(u,3)*result[0][0] + pow(u,2)*result[1][0]
+ u*result[2][0] + result[3][0]);
pt[i].y =(int) (pow(u,3)*result[0][1] + pow(u,2)*result[1][1]
+ u*result[2][1] + result[3][1]);
u += delt;
}
dc.Polyline(pt,nPoints);
delete pt;
}
//************************
//绘制Bezier曲线的函数
//************************
void CDrawCurvesView::DrawBezierCurve(CDC &dc,int nPoints)
{
double t = 0.0,delt = 0.0;
delt = 1.0/(double)nPoints;
CPoint *points = new CPoint[nPoints+1];
for(int i=0; i<= nPoints;i++)
{
points[i] = Decas(4,t);
t += delt;
}
dc.Polyline(points,nPoints);
}
//********************************
//绘制Bezier曲线的辅助函数,
//主要完成t在某个值时,bezier
//曲线上的一个点的坐标的计算
//*********************************
CPoint CDrawCurvesView::Decas(int ptNum, double t)
{
CPoint *coeffa = new CPoint[ptNum+1],coeffa0;
for(int i=0;i<=ptNum;i++)
{
coeffa[i] = CurveCtrlPoints[i];
}
for(int r = 1;r <= ptNum;r++)
for(int j = 0;j < ptNum-r;j++)
{
coeffa[j].x=(int)(coeffa[j].x+t*(coeffa[j+1].x-coeffa[j].x));
coeffa[j].y=(int)(coeffa[j].y+t*(coeffa[j+1].y-coeffa[j].y));
}
coeffa0 = coeffa[0];
delete coeffa;
return coeffa0;
}
分享到:
相关推荐
MFC下曲线绘制(Bezier、三次B样条、Hermite),每种曲线一个工程,每个工程下都有简要使用说明
计算机图形学大作业: 一、主菜单的菜单项 基本图形绘制、图形变换、自由曲线绘制、图形裁剪或图形填充 二、二级子菜单基本图形绘制 1.直线绘制: 1)Bresenham绘制直线 2)DDA绘制直线 3)改进的Bresenham...
计算机图形学实验4-----Hermite-Bezier-B样条三种曲线的绘制.doc
使用MFC实现三条曲线,Bezier支持多次,B样条曲线默认为3次,可以修改。内附有说明文档。
mfc实现绘制Bezier曲线、B样条曲线和Hermite曲线,CAD实验题目,内含三个程序,每个程序实现一个要求
基于vc6.0 MFC编写的实现Hermite曲线和Bezier曲线的代码。
本程序代码可以绘制多种图形曲线,采用真彩工具条做界面,分别编写Bezier曲线,B-样条曲线,Hermit曲线;本程序采用c++
首先,启用“选择点”,然后根据需要选择任意数量的点。 要完成选择过程,必须选择fitsr点。 最后,通过选择任何类型的曲线,程序将绘制它。 注意:可以移动点,曲线将自动更改。
*MFC实现Hermite曲线,可以运行,有说明文档。
图形学大作业----内容 一、主菜单的菜单项 基本图形绘制、图形变换、自由曲线绘制、图形裁剪、图形填充 二、二级子菜单(基本图形绘制) 1.直线绘制: 1)Bresenham绘制直线 2)DDA绘制直线 3)改进的Bresenham绘制...
绘制bezier曲线的程序。包括bezier曲线,三次bezier样条,Hermite插值曲线等。
简单的实现了三次hermite曲线,可以点击绘制点进行动态的改变hermite曲线。
可分别在面板中绘制Hermite曲线,Bezier曲线和B样条曲线Java
C++ MFC程序设计 Bezier B样条 Hermite曲线 计算机图形学辅助设计程序设计课程设计 课设作业 visual c++ 绘图 CAD技术
三次Hermite样条曲线的绘制,在编辑菜单下有一个编辑的选项,可改动参数,其中有两个因任务需要已设为已知,遂只有6个参数。(是利用矩阵算的)
3.自由曲线绘制: 1次 Bezier曲线,2次 Bezier曲线,3次 Bezier曲线,3次B样条曲线,Hermite三次样条曲线,曲线拼接。 4.图形裁剪和图形填充: 多边形裁剪,绘制填充多边形,有效边表填充算法填充多边形。 建议...
多点插值的埃米尔特曲线、贝齐尔曲线及 B 样条曲线绘制。 通过鼠标输入型值点,根据用户输入的型值点,分别绘制 Hermite 曲线,三次 Bezier 曲线,四阶三次等距 B 样条曲线(可 通过菜单或工具条选择具体要绘制哪种...
VC++ 计算机图形学 三次Hermite样条曲线算法