题目:
武汉工业学院
《计算机图形学》课程设计
绘制三次Bezier曲线,三次B样条曲线和Cantor图
指导老师:刘文涛 姓 名:庞璐 学 号:070505129
院 (系):计算机与信息工程系
专 业:软件工程
完成日期: 2010年1 月4 日
一.课题题目介绍
设计任务9:
1)给定下图所示的四个控制点:P0=(228,456),P1=(294,247),P2=(452,123),P3=(705,197)。分别绘制三次Bezier曲线和三次B样条曲线。
2)使用VC编程,在窗口中一次绘制n=0~5的所有Cantor
图。
二.整体功能及设计
1)主模块:Bezier,B样条,cantor集算法的实现。 2)响应模块:a.Bezier,B样条,cantor集的鼠标响应;
b.Bezier,B样条,cantor集的菜单和提示对话框响应。 c. Bezier,B样条,cantor集的快捷按钮响应。
3)附加功能模块:曲线颜色的选择。
绘图 主模块 响应模块 附加功能模块 算法描述:
Bezier曲线 功能描述:
点击相应菜单,弹出提示对话框,继而可以实现鼠标取点,绘出Bezier曲线和B样条曲线;选择cantor集菜单在弹出的对话框中输入n的值,随即绘出cantor集图形。
三.编程实现
1.属性和方法的定义:
class CMy070505129View : public CView {
protected: // create from serialization only CMy070505129View();
DECLARE_DYNCREATE(CMy070505129View)
// Attributes
bool mousestate;//鼠标状态标志 CPoint cp[4];//顶点 int i;//控制多边形顶点 int m;//判断函数
int MaxX,MaxY;//屏幕x和y的最大坐标 int n;//递归深度
COLORREF ccolor;//设置颜色值 public:
CMy070505129Doc* GetDocument();
// Operations
void DrawBezier();//Bezier函数 void DrawByangtiao();//B样条函数
void Cantor(double,double,double,double,int);//cantor函数
2.头文件:
#include \
#include \
#include \#include \#include \#include \#include \
#define ROUND(x) int(x+0.5)//四舍五入
3.方法实现:
CMy070505129View::CMy070505129View() {//部分数据初始化
mousestate=false; i=0;
cp[0].x=0; cp[0].y=0; cp[1].x=0; cp[1].y=0; cp[2].x=0; cp[2].y=0; cp[3].x=0; cp[3].y=0; }
void CMy070505129View::DrawBezier()//Bezier函数 {
CClientDC dc(this);//设备上下文 double t=0.0;
//Bezier算法实现 while(t<1.0) { double
ptx=((-(t*t*t))+3*t*t-3*t+1)*(double)cp[0].x+(3*t*t*t-6*t*t+3*t)*(double)cp[1].x+((-(3*t*t*t))+3*t*t)*(double)cp[2].x+t*t*t*(double)cp[3].x; double
pty=((-(t*t*t))+3*t*t-3*t+1)*(double)cp[0].y+(3*t*t*t-6*t*t+3*t)*(double)cp[1].y+((-(3*t*t*t))+3*t*t)*(double)cp[2].y+t*t*t*(double)cp[3].y;
dc.SetPixel((int)(ptx+0.5),(int)(pty+0.5),ccolor);//ccolor为颜色变量 t+=1/10000.0;//步长 } }
void CMy070505129View::DrawByangtiao()//B样条函数 {
CClientDC dc(this);//设备上下文
double t=0.0,x,y;//局部变量t为步长,x,y为每次曲线相应的点 dc.MoveTo(cp[0]);//绘制四个控制点组成的四条线 for(int i=1;i<4;i++) {
dc.LineTo(cp[i]); }
//B样条算法实现 while(t<1.0) {
double F0=(-(t*t*t)+3*t*t-3*t+1)/6.0; double F1=(3*t*t*t-6*t*t+4)/6.0;
double F2=(-3*(t*t*t)+3*t*t+3*t+1)/6.0; double F3=t*t*t/6.0;
x=cp[0].x*F0+cp[1].x*F1+cp[2].x*F2+cp[3].x*F3; y=cp[0].y*F0+cp[1].y*F1+cp[2].y*F2+cp[3].y*F3;
dc.SetPixel((int)(x+0.5),(int)(y+0.5),ccolor);//ccolor为颜色变量 t+=1/1000.0;//步长
} }
void CMy070505129View::Cantor(double ax,double ay,double bx,double by,int x)//cantor函数 {
double cx,dx,cy,dy;//cantor中间点座标 CClientDC dc(this);//设备上下文 if(x==0) { dc.MoveTo(ROUND(ax),ROUND(ay+MaxY/2)); dc.LineTo(ROUND(bx),ROUND(by+MaxY/2)); return; }
//递归
cx=ax+(bx-ax)/3;cy = ay ;
Cantor(ax,ay,cx,cy,x-1);
dx=ax+2*(bx-ax)/3;dy = by ; Cantor(dx,dy,bx,by,x-1); }
void CMy070505129View::OnBezier()//菜单响应函数 {
// TODO: Add your command handler code here mousestate=true;//重新设制鼠标状态 CBezier bezier;//定义对话框类对象 bezier.DoModal();//响应
m=1;//标记值,双击时调用相应的函数 Invalidate(); }
void CMy070505129View::OnByangtiao()//菜单响应函数 {
// TODO: Add your command handler code here mousestate=true;//重新设制鼠标状态
CByangtiao Byangtiao;//定义对话框类对象 Byangtiao.DoModal();//响应
m=2;//标记值,双击时调用相应的函数 Invalidate(); }
void CMy070505129View::OnLButtonDown(UINT nFlags, CPoint point)//单击获取控制点函数 {
if(mousestate) { //获取x坐标 cp[i].x=point.x; //获取y坐标 cp[i].y=point.y;
//存四个控制点放入cp[4] if(i<4) i++; else mousestate=false; }
CView::OnLButtonDown(nFlags, point); }
void CMy070505129View::OnBUTTONBezier()//Bezier快捷按钮函数 {