1、=y1,其他情形可以类推) 1.1.1、待扫描转换生成直线段: 1.1.2、直线的表达形式:,其中 1.1.3、划分区间:1.1.4、计算纵坐标:1.1.5、对计算的纵坐标取整:2、中点算法扫描转换直线段: 2.1、中点算法简介: 2.1.1、待扫描转换生成直线段: ; 2.1.2、直线的表达形式: 且假定直线段的斜率 2.1.3、直线段的隐式方程:; 2.1.4、递推计算纵坐标为:,其中M为 2.1.5、令2.1.4中的的2倍为判别式,即取判别式为: 并且有递推计算公式如下: 2.1.6、算法的初始条件为3、Breshenham算法扫描转换直线段: 3.1、Breshenham算法简介: 3
2、.1.1、前序几步与前面两者的思想一样,不同的是在确定下一个点的纵坐标的值的时候,算法不同; 3.1.2、设点Q为斜线段与直线的交点,分别为点Q距上下平行线距离。可求出的长度 3.1.3、推得,且令 3.1.4、则有递推公式也即: 3.1.5、得到纵坐标的递推求值为:二、扫描转换圆弧1、扫描转换生成圆 1.1、算法简介: 1.1.1、利用圆的八对称性; 1.1.2、利用重点算法扫描转换: 1.1.3、取判别数:,其中,即圆的隐函数在中点的函数值; 1.1.4、递推求下一个点的纵坐标值: 1.15、给定算法的初始条件如下:上机实现及源代码:实验中,在给定两个点之后,根据算法的思想扫描生成一条直线
3、,二两个端点的给定可以通过捕获鼠标信息来获取:当鼠标左键按下的时候,调用OnLButtonDown()函数来获取直线段的起点,当释放鼠标左键的时候,调用OnLButtonUp()函数来获取直线段的终点。在扫描转换圆弧中,当鼠标左键按下的时候,调用OnLButtonDown()函数来获取一个点,作为所要画的圆的圆心,当释放左键时,调用OnLButtonUp()函数获取一个点,取两个点之间的的距离作为所要画的圆的半径R,调用switch语句实现不同算法画直线和圆。void CAmyGraphView:OnDda() / TODO: 在此添加命令处理程序代码 m_ndrawtype=1;OnMid(
4、) m_ndrawtype=2;OnBresenham() m_ndrawtype=3; void CAmyGraphView:OnLButtonDown(UINT nFlags, CPoint point) 在此添加消息处理程序代码和/或调用默认值 m_start=point; CView:OnLButtonDown(nFlags, point);OnLButtonUp(UINT nFlags, CPoint point) m_end=point; CDC* pDC=GetDC(); CPoint P0,P1; P0=m_start; P1=m_end; float x(P0.x),y(P0
5、.y); float dx,dy; dx=P1.x-P0.x; dy=P1.y-P0.y; float m; m=dy/dx; switch(m_ndrawtype) /DDA算法,并且假定x0x1 case 1: if(abs(m)1) for (x=P0.x;x=P1.x;x+) if(P0.ySetPixel(x,(int)(y+0.5),RGB(255,0,0); Sleep(1); /0=m1 elseSetPixel(x,(int)(y-0.5),RGB(255,0,0); /-1=1) if(P0.y for(y=P0.y;ySetPixel(int)(x+0.5),y,RGB(
6、255,0,0); Sleep(1); else for(y=P0.y;yy-) x=x-1/m;TextOutW(P1.x,P1.y,_T(DDA算法); ReleaseDC(pDC); break; /中点算法生成直线,假定x0x1,0m case 2: int E,NE,d; d=dx-2*dy; /初始化判别式d E=-2*dy; /取像素E时判别式的增量 NE=2*(dx-dy);/取像素NE时判别式的增量SetPixel(x,y,RGB(0,255,0); while(x0) d+=E; d+=NE; y+; x+;中点算法 /Bresenham算法,假定x0 case 3: in
7、t p,twoDy,twoDyDx,xEND; p=2*dy-dx; twoDy=2*dy; twoDyDx=2*(dy-dx);SetPixel(x,y,RGB(0,0,255);P1.x) if(pX)/八分之一圆弧 if(DSelectObject(&newpen); pset0=CPoint(100,100); pset1=CPoint(200,80); pset2=CPoint(320,100); pset3=CPoint(250,250); pset4=CPoint(100,250); pset5=CPoint(150,200); pset6=CPoint(90,180); pse
8、t7=CPoint(150,150); pset8=CPoint(100,100);Polyline(pset,9);SelectObject(old);OnLButtonDblClk(nFlags, point);OnSeedfill() int fill=RGB(0,255,0); int boundary=RGB(255,0,0); s_point.x=200;s_point.y=150;/定义种子点 int x,y,pmin,pmax; /求多边形的最大最小值 for(int m=1;9;m+) for(int n=0;n9-m;n+) if(psetn.yGetPixel(x,y);
9、 while(current!=boundary)&(current!=fill) pDC-SetPixel(x,y,fill); x+; current=pDC- /判断循环是否继续 x=s_point.x; x-; x-; x=s_point.x; x=s_point.x; y=s_point.y-1;pmin+1;y-) (实验二 区域填充种子扫描线算法)第三篇 二维直线段与多边形裁剪在第一篇中已经提到,二维图形在现实之前都需要进行两个重要的处理步骤,其一是扫描转换,其二是裁剪。当二维图形只能在某一可见窗口显示的时候,就需要对其进行裁剪。现今最要的二位图形的裁剪算法有直线段的裁剪有Coh
10、en-Sutherland算法、Nicholl-Lee-Nicholl算法、中点分割算法以及梁友栋-Barsky算法;多边形裁剪的算法有Sutherland-Hodgman算法,Weiler-Atherton算法。本实验将利用Cohen-Sutherland算法上机实现直线段裁剪。一、直线段裁剪1、Cohen-Sutherland算法的简介就不做叙述,可以参加文献一第六章。2、上机实现操作的基本思想:2.1、首先定义一个数组存储线段的起点和终点坐标,并定义裁剪窗口。2.2、添加鼠标消息响应函数OnLButtonDblClk()显示要裁剪的线段2.3、编写“线段裁剪”菜单项,添加事件处理函数来实
11、现直线段裁剪。3、算法程序源代码及示例如下:#define LEFT 1#define RIGHT 2#define BOTTOM 4#define TOP 8#define XL 100#define XR 300#define YT 100#define YB 250#define N 11public:CPoint psetN;void CCohenSutherland算法View: CCohenSutherland算法Doc* pDoc = GetDocument();Rectangle(CRect(XL,YT,XR,YB);/剪切窗口 pset0=CPoint(200,140); p
12、set1=CPoint(200,200); pset2=CPoint(10,225); pset3=CPoint(350,225); pset4=CPoint(280,170); pset5=CPoint(150,10); pset6=CPoint(200,50); pset7=CPoint(120,150); pset8=CPoint(310,100); pset9=CPoint(350,280);双击鼠标左键,出现要剪切的线段OnLinecut() CPen newpen(PS_SOLID,1,RGB(0,0,255); float x,y; int i; int code1,code2;
13、 RedrawWindow(); / 求两端点所在区号code for(i=0;iN;i+,i+) int c=0; if(pseti.xXR)c=c|RIGHT; if(pseti.yYB) c=c|BOTTOM; else if(pseti.yYT) c=c|TOP; code1=c; c=0; if(pseti+1.xXR) c=c|RIGHT; if(pseti+1.y else if(pseti+1.y code2=c; /线段与区域的相交情况 if(code1!=0&code2!(code1&code2)=0) /按位与非0时一定位于裁剪窗口外的某一侧,p2p3线段 if(LEFT
14、&code1)!=0) /线段与左边界相交 x=XL; y=(float)pseti.y+(pseti+1.y-pseti.y)*(XL-pseti.x)/(pseti+1.x-pseti.x); else if(RIGHT&=0) /线段与右边界相交 x=XR; y=(float)pseti.y+(pseti+1.y-pseti.y)*(XR-pseti.x)/(pseti+1.x-pseti.x); else if(BOTTOM&=0) /线段与下边界相交 y=YB; x=(float)pseti.x+(pseti+1.x-pseti.x)*(YB-pseti.y)/(pseti+1.y-pseti
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1