直线中点Bresenham算法.docx
《直线中点Bresenham算法.docx》由会员分享,可在线阅读,更多相关《直线中点Bresenham算法.docx(11页珍藏版)》请在冰豆网上搜索。
直线中点Bresenham算法
学生:
学号:
班级:
网络
实验时间:
2012年12月19日
报告时间:
2012年12月20日
系别:
计算机系
学院:
电气与信息工程学院
实验:
直线中点Bresenham算法
一:
原理
1、输入直线的两端点p0(x0,y0)和p1(x1,y1)。
2、计算初始值△x,△y,d=△x-2△y,x=x0,y=y0。
3、绘制点(x,y)判断d的符号:
若d<0,则(x,y)更新为(x+1,y+1),d更新为d+2△x-2△y;否则(x,y)更新为(x+1,y),d更新为d-2△y。
4、当直线没有画完时,重复步骤3,否则结束。
二:
伪代码
voidCTestView:
:
myDrawLine()
{
CClientDCdc(this);
dc.MoveTo(20,30);
dc.LineTo(200,300);
}
voidCTestView:
:
OnMydrawline()
{
//TODO:
Addyourcommandhandlercodehere
myDrawLine();
}
三:
截图
实验:
多边形有效边表填充算法
一:
原理
多边形的有效边表填充算法的基本原理是按照扫描线从小到大的移动顺序,计算当前扫描线与多边形各边的交点,然后把这些交点按x值递减的顺序进行排序、配对,以确定填充区间,然后用指定颜色点亮填充区间内的所有像素,即完成填充工作。
1、定义多边形
2、初始化桶
3、建立边表
4、多边形填充
1)对每一条扫描线,将该扫描线上的边结点插入到临时AET表中,HeadE.
2)对临时AET表排序,按照x递增的顺序存放。
3)根据AET表中边表结点的ymax抛弃扫描完的边结点,即ymax>=scanline4)扫描AET表,填充扫描线和多边形相交的区间。
二:
伪代码
classCscanfillView:
publicCView
{
protected:
//仅从序列化创建
CscanfillView();
DECLARE_DYNCREATE(CscanfillView)
//属性
public:
CscanfillDoc*GetDocument()const;
//操作
public:
voidPolygonFill();//上闭下开填充多边形
voidCreatBucket();//建立桶节点
voidEt();//构造边表
voidAddEdge(AET*);//将边插入AET表
voidEdgeOrder();//对AET表进行排序
//重写
public:
virtualvoidOnDraw(CDC*pDC);//重写以绘制该视图
virtualBOOLPreCreateWindow(CREATESTRUCT&cs);
protected:
virtualBOOLOnPreparePrinting(CPrintInfo*pInfo);
virtualvoidOnBeginPrinting(CDC*pDC,CPrintInfo*pInfo);
virtualvoidOnEndPrinting(CDC*pDC,CPrintInfo*pInfo);
//实现
public:
virtual~CscanfillView();
#ifdef_DEBUG
virtualvoidAssertValid()const;
virtualvoidDump(CDumpContext&dc)const;
#endif
protected:
COLORREFGetColor;//调色板
CPointPoint[7];//定义多边形
Bucket*HeadB,*CurrentB;//桶的头结点和当前节点
AETE[Number],*HeadE,*CurrentE,*T1,*T2;//有效边表的节点
//生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msgvoidOnMenuAET();
};
#ifndef_DEBUG//scanfillView.cpp中的调试版本
inlineCscanfillDoc*CscanfillView:
:
GetDocument()const
{returnreinterpret_cast(m_pDocument);}
#endif
三:
截图
实验:
梁友栋-Barsky直线裁剪算法
一:
原理
梁友栋-Barsky算法进行线段裁剪的步骤
(1)输入直线段的两端点坐标以及窗口的四条边界坐标。
(2)若Δx=0则p1=p2=0。
进一步判断是否满足q1<0或q2<0若满足则该直线段不在窗口内转(7)。
否则满足q1>0且q2>0则进一步计算u1和u2。
转(5)。
(3)若Δy=0则p3=p4=0。
进一步判断是否满足q3<0或q4<0若满足则该直线段不在窗口内转(7)。
否则满足q1>0且q2>0则进一步计算u1和u2。
转(5)。
(4)若上述两条均不满足,则有pk≠0(k=1,2,3,4)。
此时计算u1和u2。
(5)求得u1和u2后,进行判断若u1>u2,则直线段在窗口外,转(7)。
若u1(6)利用直线的扫描转换算法绘
(7)算法结束
二:
伪代码
CTestView:
:
CTestView()
{
//TODO:
addconstructioncodehere
//设置多边形的7个顶点
Point[0]=CPoint(550,400);//P0
Point[1]=CPoint(350,600);//P1
Point[2]=CPoint(250,350);//P2
Point[3]=CPoint(350,50);//P3
Point[4]=CPoint(500,250);//P4
Point[5]=CPoint(600,50);//P5
Point[6]=CPoint(800,450);//P6
}
CTestView:
:
~CTestView()
{
}
BOOLCTestView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
returnCView:
:
PreCreateWindow(cs);
}
//CTestViewdrawing
voidCTestView:
:
OnDraw(CDC*pDC)
{
CTestDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
pDC->Polygon(Point,7);//绘制多边形
//输出多边形的顶点编号
pDC->TextOut(550,410,"P0");
pDC->TextOut(350,600,"P1");
pDC->TextOut(230,340,"P2");
pDC->TextOut(350,30,"P3");
pDC->TextOut(490,220,"P4");
pDC->TextOut(600,30,"P5");
pDC->TextOut(805,450,"P6");
}
三:
截图
实验:
三次B样条曲线算法
一:
原理
三次B样条曲线的n=3,k=0,1,2,3,控制多边形有4个控制点P0、P1、P2和P3,B样条曲线是三次多项式。
三次参数曲线可以表示成:
P(t)=A0(t)Q0+A1(t)Q1+A2(t)Q2+A3(t)Q3
(1)
A0(t),A1(t),A2(t),A3(t)是待定参数
P1由Q0,Q1,Q2,Q3确定
P2由Q1,Q2,Q3,Q4确定
P1
(1)=P2(0)P1
(1)=P2(0)
P1
(1)=P2(0)
A0(t)+A1(t)+A2(t)+A3(t)=1
A0(t),A1(t),A2(t),A3(t)≥0
确定A0(t),A1(t),A2(t),A3(t)代入
(1)式
对于B样条曲线来说,特征多边形每增加一个顶点,就相应增加一段B样条曲线。
因此,B样条曲线很好地解决了曲线段的连接问题。
二:
伪代码
voidCDrawYTQXView:
:
DrawB3_curves()//绘制B样条曲线
{
CClientDCdc(this);
inti,rate=10,m;
longlx,ly;
m=CtrlPoint-(3+1);
doubleF03,F13,F23,F33;
lx=ROUND((pt[0].x+4.0*pt[1].x+pt[2].x)/6.0);//t=0的起点x坐标
ly=ROUND((pt[0].y+4.0*pt[1].y+pt[2].y)/6.0);//t=0的起点y坐标
dc.MoveTo(lx,ly);
CPenMyPen2,*pOldPen2;
MyPen2.CreatePen(PS_SOLID,2,RGB(0,0,255));//颜色设置
pOldPen2=dc.SelectObject(&MyPen2);
for(i=1;i{
for(doublet=0;t<=1;t+=1.0/rate)
{
F03=(-t*t*t+3*t*t-3*t+1)/6;//计算F0,3(t)
F13=(3*t*t*t-6*t*t+4)/6;//计算F1,3(t)
F23=(-3*t*t*t+3*t*t+3*t+1)/6;//计算F2,3(t)
F33=t*t*t/6;//计算B3,3(t)
lx=ROUND(pt[i-1].x*F03+pt[i].x*F13+pt[i+1].x*F23+pt[i+2].x*F33);
ly=ROUND(pt[i-1].y*F03+pt[i].y*F13+pt[i+1].y*F23+pt[i+2].y*F33);
dc.LineTo(lx,ly);
}
}
dc.SelectObject(pOldPen2);
MyPen2.DeleteObject();
}
voidCDrawYTQXView:
:
DrawCharPolygon()//绘制控制多边形
{
CClientDCdc(this);
CPenMyPen,*pOldPen;
MyPen.CreatePen(PS_SOLID,2,RGB(0,0,0));//控制多边形
pOldPen=dc.SelectObject(&MyPen);
for(inti=0;i{
if(i==0)
{
dc.MoveTo(pt[i]);
dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2);
}
else
{
dc.LineTo(pt[i]);
dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2);
}
}
dc.SelectObject(pOldPen);
MyPen.DeleteObject();
}
voidCDrawYTQXView:
:
OnLButtonDown(UINTnFlags,CPointpoint)//获得屏幕控制点坐标
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
CView:
:
OnLButtonDown(nFlags,point);
if(Flag)
{
pt[CtrlPoint].x=point.x;
pt[CtrlPoint].y=point.y;
if(CtrlPointCtrlPoint++;
else
Flag=false;
DrawCharPolygon();
}
elseDrawCharPolygon1();
}
voidCDrawYTQXView:
:
OnRButtonDown(UINTnFlags,CPointpoint)//调用绘制函数
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
Flag=false;
if(Sign==0)Hermite();
if(Sign==1)DrawBezier();
if(Sign==2)DrawB3_curves();
CView:
:
OnRButtonDown(nFlags,point);
}
三:
截图