专业做包装设计网站快乐麻花网站源码
news/
2025/10/9 13:35:19/
文章来源:
专业做包装设计网站,快乐麻花网站源码,免费国外代理网页,企业信息管理系统平台官网现在的计算机的图像的都是用像素表示的#xff0c;无论是点、直线、圆或其他图形最终都会以点的形式显示。人们看到屏幕的直线只不过是模拟出来的#xff0c;人眼不能分辨出来而已。那么计算机是如何画直线的呢#xff0c;其实有比较多的算法#xff0c;这里讲的是Bresenha… 现在的计算机的图像的都是用像素表示的无论是点、直线、圆或其他图形最终都会以点的形式显示。人们看到屏幕的直线只不过是模拟出来的人眼不能分辨出来而已。那么计算机是如何画直线的呢其实有比较多的算法这里讲的是Bresenham的算法是光栅化的画直线算法。直线光栅化是指用像素点来模拟直线比如下图用蓝色的像素点来模拟红色的直线。 给定两个点起点P1(x1, y1), P2(x2, y2),如何画它们直连的直线呢即是如何得到上图所示的蓝色的点。假设直线的斜率0k0,直线在第一象限Bresenham算法的过程如下 1.画起点(x1, y1). 2.准备画下一个点X坐标加1判断如果达到终点则完成。否则找下一个点由图可知要画的点要么为当前点的右邻接点要么是当前点的右上邻接点。 2.1.如果线段axbyc0与xx11的交点y坐标大于(y*y1))/2则选右上那个点 2.2.否则选右下那个点。 3.画点 4.跳回第2步 5.结束 算法的具体过程是怎样的呢其实就是在每次画点的时候选取与实现直线的交点y坐标的差最小的那个点例如下图 关键是如何找最近的点每次x都递增1y则增1或者不增1由上图假设已经画了d1点那么接下来x加1但是选d2 还是u点呢直观上可以知道d2与目标直线和x1直线的交点比较近即纵坐标之差小也即与(x1, y1)点纵坐标差大于0.5所当然是选d2其他点了是这个道理。 一、 算法原理简介 算法原理的详细描述及部分实现可参考 http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html 假设以(x, y)为绘制起点一般情况下的直观想法是先求m dy /dx即x每增加1 y的增量然后逐步递增x, 设新的点为x1 x j, 则y1 round(y j * m)。可以看到这个过程涉及大量的浮点运算效率上是比较低的特别是在嵌入式应用中DSP可以一周期内完成2次乘法一次浮点却要上百个周期。 下面我们来看一下Bresenham算法如Fig. 1,(x, y ε)的下一个点为(x, y ε m)这里ε为累加误差。可以看出当εm 0.5时绘制(x 1, y)点否则绘制(x 1, y 1)点。每次绘制后ε将更新为新值 ε ε m ,如果(ε m) . (或表示为2*(ε m) 1) ε ε m – 1, 其他情况 将上述公式都乘以dx, 并将ε*dx用新符号ξ表示可得 ξ ξ dy, 如果2*(ξ dy) dx ξ ξ dy – dx, 其他情况 可以看到此时运算已经全变为整数了。以下为算法的伪代码 ξ ← 0, y ← y1 For x ← x1 to x2 do Plot Point at (x, y) If (2(ξ dy) dx) ξ ←ξ dy Else y ← y 1,ξ ←ξ dy – dx End If End For 二、 算法的注意点 在实际应用中我们会发现当dy dx或出现Fig.2 右图情况时时便得不到想要的结果这是由于我们只考虑dx dy 且x, y的增量均为正的情况所致。经过分析需要考虑8种不同的情况如Fig. 3所示 当然如果直接在算法中对8种情况分别枚举 那重复代码便会显得十分臃肿因此在设计算法时必须充分考虑上述各种情况的共性后面将给出考虑了所有情况的实现代码。 三、 算法的实现 以下代码的测试是利用Opencv 2.0进行的,根据需要只要稍微修改代码便能适应不同环境 代码1 int CEnginApp::Draw_Line(int x0, int y0, // starting position int x1, int y1, // ending positionCOLORREF color, // color indexUNINT *vb_start, int lpitch) // video buffer and memory pitch
{// this function draws a line from xo,yo to x1,y1 using differential error// terms (based on Bresenahams work)
RECT cRect;//GetWindowRect(m_hwnd,m_x2d_ClientRect);
GetClientRect(m_hwnd, cRect);ClientToScreen(m_hwnd, (LPPOINT)cRect);ClientToScreen(m_hwnd, (LPPOINT)cRect1);vb_start vb_start cRect.left cRect.top*lpitch;int dx, // difference in xsdy, // difference in ysdx2, // dx,dy * 2dy2, x_inc, // amount in pixel space to move during drawingy_inc, // amount in pixel space to move during drawingerror, // the discriminant i.e. error i.e. decision variableindex; // used for looping// pre-compute first pixel address in video buffervb_start vb_start x0 y0*lpitch;// compute horizontal and vertical deltasdx x1-x0;dy y1-y0;// test which direction the line is going in i.e. slope angleif (dx0){x_inc 1;} // end if line is moving rightelse{x_inc -1;dx -dx; // need absolute value
} // end else moving left// test y component of slopeif (dy0){y_inc lpitch;} // end if line is moving downelse{y_inc -lpitch;dy -dy; // need absolute value
} // end else moving up// compute (dx,dy) * 2dx2 dx 1;dy2 dy 1;// now based on which delta is greater we can draw the lineif (dx dy){// initialize error termerror dy2 - dx; // draw the linefor (index0; index dx; index){// set the pixel*vb_start color;// test if error has overflowedif (error 0) {error-dx2;// move to next linevb_starty_inc;} // end if error overflowed// adjust the error termerrordy2;// move to the next pixelvb_startx_inc;} // end for
} // end if |slope| 1else{// initialize error termerror dx2 - dy; // draw the linefor (index0; index dy; index){// set the pixel*vb_start color;// test if error overflowedif (error 0){error-dy2;// move to next linevb_startx_inc;} // end if error overflowed// adjust the error termerrordx2;// move to the next pixelvb_starty_inc;} // end for
} // end else |slope| 1// return successreturn(1);} // end Draw_Line 代码2 int CEnginApp::Draw_Line2(int x1,int y1,int x2, int y2,COLORREF color,UNINT *vb_start, int lpitch)
{RECT cRect;//GetWindowRect(m_hwnd,m_x2d_ClientRect);
GetClientRect(m_hwnd, cRect);ClientToScreen(m_hwnd, (LPPOINT)cRect);ClientToScreen(m_hwnd, (LPPOINT)cRect1);vb_start vb_start cRect.left cRect.top*lpitch;int dx x2 - x1;int dy y2 - y1;int ux ((dx 0) 1) - 1;//x的增量方向取或-1int uy ((dy 0) 1) - 1;//y的增量方向取或-1int x x1, y y1, eps;//eps为累加误差
eps 0;dx abs(dx); dy abs(dy); if (dx dy) {for (x x1; x ! x2; x ux){Plot_Pixel_32(x,y,0,255,0,255,vb_start,lpitch);eps dy;if ((eps 1) dx){y uy; eps - dx;}}}else{for (y y1; y ! y2; y uy){Plot_Pixel_32(x,y,0,255,0,255,vb_start,lpitch);eps dx;if ((eps 1) dy){x ux; eps - dy;}}} return 1;
} 调用代码 DD_INIT_STRUCT(ddsd);if (FAILED(lpSface[PrimarySface]-Lock(NULL,ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL)))return false;int x1,y1,x2,y2;for (int i0;i100;i){srand(time(0));x1rand()%750;y1rand()%550;x2rand()%750;y2rand()%550;Draw_Line2(x1,y1,x2,y2,RGB(0,255,0),(UNINT *)ddsd.lpSurface,ddsd.lPitch2);}if (FAILED(lpSface[PrimarySface]-Unlock(NULL)))return false; 效果图 转载于:https://www.cnblogs.com/gamesky/archive/2012/08/21/2648623.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/932588.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!