logo资料库

图形学课程设计--交互B样条曲线.docx

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
1.问题描述与数学模型 给定 10 个控制点:P0(100,300),P1(200,230),P2(300,360),P3(360,150), P4(480,520),P5(550,230),P6(660,30),P7(800,400),P8(850,400),P9(900, 500)。绘制颜色渐变的连续三次 B 样条曲线并用鼠标来确定控制点。 2.算法思想 基于对直线绘制类的使用,对 B 样条曲线进行变色处理,然后根据 B 样条的基函 数和 B 样条的分段参数表达式使用循环语句进行编译,再通过鼠标确定控制点绘 制 B 样条曲线。 3.程序设计步骤及流程图 (1)根据控制点坐标绘制控制多边形 (2)计算三次 B 样条基函数: F0,3(t)=(-t*t*t+3*t*t-3*t+1)/6 F1,3(t)=(3*t*t*t-6*t*t+4)/6 F2,3(t)=(-3*t*t*t+3*t*t+3*t+1)/6 F3,3(t)=t*t*t/6 (3)设置曲线段绘制起点以及起点处颜色 (4)开启第一重重循环,循环次数为 7 次,分别绘制 7 段三次 B 样条曲线 (5)开启第一重重循环,循环控制变量 t 从 0 到 1,循环中计算四个 B 样条基 函数 (6)计算 Pi,3(t)=P[i].x*F03+P[i+1].x*F13+P[i+2].x*F23+P[i+3].x*F33 使 用直线连接曲线上的每一点,并用 t 调节对应点的颜色 (7)当 t<=1 时,返回步骤(5) (8)当 i<=7 时,返回步骤(4)
4.实现源程序 //MY206XR.h class CP2//二维点类 { public: CP2(); virtual~CP2(); CP2(double,double); public : double x; double y; }; class CLine//直线绘制类 { public: CLine(); virtual~CLine(); void SetLineColor(COLORREF); void MoveTo(CP2); void MoveTo(double,double); void LineTo(CP2,CDC*); void LineTo(double,double,CDC*); public: CP2 P0; CP2 P1;
COLORREF clr; }; //MY206XRView.h void B3Spline(CDC*pDC);//绘制 B 样条曲线 //MY206XR.cpp CP2::CP2() { } x=0.0; y=0.0; CP2::~CP2() {} CP2::CP2(double x, double y) { } this->x=x; this->y=y; CLine::CLine() {} CLine::~CLine() {} void CLine::SetLineColor(COLORREF color) { } clr=color; void CLine::MoveTo(CP2 p0)//记录直线起点函数 { } P0=p0; void CLine::MoveTo(double x, double y) {
P0.x=x; P0.y=y; } void CLine::LineTo(double x, double y, CDC *pDC) { } CP2 p; p.x=x; p.y=y; LineTo(p,pDC); void CLine::LineTo(CP2 p1, CDC *pDC) { P1=p1; CP2 p,t; if(fabs(P0.x-P1.x)<1e-6) { if(P0.y>P1.y)//交换顶点,使得起始点低于终点 { } t=P0; P0=P1; P1=t; for(p=P0;p.ySetPixelV(Round(p.x),Round(p.y),clr); { } } else { double k,d; k=(P1.y-P0.y)/(P1.x-P0.x); if(k>1.0)//绘制 k>1 { if(P0.y>P1.y) { } t=P0; P0=P1; P1=t; d=1-0.5*k; for(p=P0;p.y
pDC->SetPixelV(Round(p.x),Round(p.y),clr); if(d>=0) { } p.x++; d+=1-k; else d+=1; { } } if(0.0<=k&&k<=1.0)//绘制 0<=k<=1 { if(P0.x>P1.x) { } t=P0; P0=P1; P1=t; d=0.5-k; for(p=P0;p.xSetPixelV(Round(p.x),Round(p.y),clr); if(d<0) { } p.y++; d+=1-k; else d-=k; } } if(k>=-1.0&&k<0.0)//绘制-1<=k<=0 { if(P0.x>P1.x) { } t=P0; P0=P1; P1=t; d=-0.5-k; for(p=P0;p.xSetPixelV(Round(p.x),Round(p.y),clr);
if(d>0) { } p.y--; d-=1+k; else d-=k; } } if(k<-1.0) { if(P0.yP1.y;p.y--) pDC->SetPixelV(Round(p.x),Round(p.y),clr); if(d<0) { } p.x++; d-=1+k; else d-=1; { } } } P0=p1; } //MY206XRView.cpp void CMy206XRView::B3Spline(CDC*pDC) { CP2 P[10]; P[0]=CP2(100,300); P[1]=CP2(200,230); P[2]=CP2(300,360); P[3]=CP2(360,150);
P[4]=CP2(480,520); P[5]=CP2(550,230); P[6]=CP2(660,30); P[7]=CP2(800,400); P[8]=CP2(850,400); P[9]=CP2(900,500); CLine*line=new CLine; line->SetLineColor(RGB(0,0,0)); line->MoveTo(P[0]); for(int i=1;i<10;i++) { } line->LineTo(P[i],pDC); CP2 ps,pe; ps.x=(P[0].x+4.0*P[1].x+P[2].x)/6.0; ps.y=(P[0].y+4.0*P[1].y+P[2].y)/6.0; line->SetLineColor(RGB(0,0,255)); line->MoveTo(ps); for(int i=0;i<7;i++) { double delt=1.0/10; double F03,F13,F23,F33; for(double t=0;t<=1;t+=delt) { F03=(-t*t*t+3*t*t-3*t+1)/6; F13=(3*t*t*t-6*t*t+4)/6; F23=(-3*t*t*t+3*t*t+3*t+1)/6; F33=t*t*t/6; pe.x=P[i].x*F03+P[i+1].x*F13+P[i+2].x*F23+P[i+3].x*F33; pe.y=P[i].y*F03+P[i+1].y*F13+P[i+2].y*F23+P[i+3].y*F33; line->SetLineColor(RGB(int(i/7.0*255),int(t*255),int((1-t)*255))); line->LineTo(pe,pDC); } } delete line; } void CMy206XRView::OnMouseMove(UINT nFlags,CPoint point) { if(TRUE==m_AbleToMove) P[m_i]=point; m_i=-1; int i; for(i=0;i<9;i++) {
if((point.x-P[i].x)*(point.x-P[i].x)+(point.y-P[i].y)*(point.y-P[i].y)<50) { } m_i=i; m_AbleToLeftBtn=TRUE; SetCursor(LoadCursor(NULL,IDC_SIZEALL)); break; } if(10==i) { } m_i=-1; Invalidate(FALSE); CView::OnMouseMove(nFlags,point); } void CMy206XRView::OnDraw(CDC*pDC) { } CMy206XRDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; B3Spline(pDC); // TODO: 在此处为本机数据添加绘制代码 5.典型测试结果
分享到:
收藏