直线生成算法——中点画线法(Middpoint)
2015-11-25 21:56
309 查看
我们将平面划分成十个部分,从第一象限的x轴开始做逆时针旋转,每隔45度角为一部分,由此类推到第八部分。Y轴正向为第九部分,负向为第十部分。
当直线斜率在[0,1]时,假设x坐标为xp的各像素点中,与直线最近者已经确定为P(xp,yp)。则下一个与直线最近的像素只能是正右方的P1(xp+1,yp),或右上方的P2(xp+1,yp+1)。以M为P1和P2的中点,则M的坐标为(xp+1,yp+0.5)。又假设Q是理想直线与垂直线x=xp+1的交点。显然,若M在Q的下方,则P2离直线近,应取P2为下一像素点;若M在Q的上方,则P1离直线近,应取P1为下一像素点。
当d>=0时,取正右方像素,下一个像素的增量为a;反之为a+b。整数化后d0=2*a+b,△d1=2*a,△d2=2*(a+b)。
同理于斜率在[1,+∞]和负数的情况,当斜率的绝对值大于1时,优先考虑x轴方向的中点情况。
程序实现时,依旧划分为8+2个共10个区域,但是这次引入对换方法实现,由于8个区域内存在4对4的斜率相同的情况,即,八个两两中心对称的区域斜率相同,只是始末点不同。同时因为直线的无向性,所以我们以y轴为届,x轴正向的情况通过公式导出,x轴负向的通过其中心对称区域的点互换数值实现直线画图。同时依旧使用if和switch语句实现。
当直线斜率在[0,1]时,假设x坐标为xp的各像素点中,与直线最近者已经确定为P(xp,yp)。则下一个与直线最近的像素只能是正右方的P1(xp+1,yp),或右上方的P2(xp+1,yp+1)。以M为P1和P2的中点,则M的坐标为(xp+1,yp+0.5)。又假设Q是理想直线与垂直线x=xp+1的交点。显然,若M在Q的下方,则P2离直线近,应取P2为下一像素点;若M在Q的上方,则P1离直线近,应取P1为下一像素点。
当d>=0时,取正右方像素,下一个像素的增量为a;反之为a+b。整数化后d0=2*a+b,△d1=2*a,△d2=2*(a+b)。
同理于斜率在[1,+∞]和负数的情况,当斜率的绝对值大于1时,优先考虑x轴方向的中点情况。
程序实现时,依旧划分为8+2个共10个区域,但是这次引入对换方法实现,由于8个区域内存在4对4的斜率相同的情况,即,八个两两中心对称的区域斜率相同,只是始末点不同。同时因为直线的无向性,所以我们以y轴为届,x轴正向的情况通过公式导出,x轴负向的通过其中心对称区域的点互换数值实现直线画图。同时依旧使用if和switch语句实现。
OnMiddpointline() { *pDC = GetDC(); tempx=0,<span style="font-family: Arial, Helvetica, sans-serif;">tempy = 0;</span>
if (x0 > x1) { tempx = x0; x0 = x1; x1 = tempx; tempy = y0; y0 = y1; y1 = tempy; } float a, b, x, y; x = x0; y = y0; a = y0 - y1; b = x1 - x0; float na; //做差 na = y1 - y0; float d1, d11, d12; d1 = 2 * a - b; d11 = 2 * (a - b); d12 = 2 * a; float d2, d21, d22; d2 = a - 2 * b; d21 = -2 * b; d22 = 2 * (a - b); float d7, d71, d72; d7 = 2 * b + a; d71 = 2 * (a + b); d72 = 2 * b; float d8, d81, d82; d8 = 2 * a + b; d81 = 2 * a; d82 = 2 * (a + b); float Dx, Dy; Dx = abs(b); Dy = abs(na); int state = 0; //直线所处状态 pDC->SetPixel(x, y, c); if (b > 0) { if (na < 0) { if (Dx >= Dy) state = 1; else state = 2; } else { if (Dx >= Dy) state = 8; else state = 7; } } else if (b < 0) { if (na < 0) { if (Dx <= Dy) state = 3; else state = 4; } else { if (Dx <= Dy) state = 6; else state = 5; } } else if (na < 0) state = 9; else state = 10; switch (state) { case 1:case 5: while (x < x1) { if (d1 < 0) { x++; d1 += d12; } else { x++; y--; d1 += d11; } pDC->SetPixel(x, y, c); } break; case 2:case 6: while (x < x1) { if (d2 < 0) { x++; y--; d2 += d22; } else { y--; d2 += d21; } pDC->SetPixel(x, y, c); } break; case 3: case 7: while (x < x1) { if (d7 < 0) { y++; d7 += d72; } else { x++; y++; d7 += d71; } pDC->SetPixel(x, y, c); } break; case 4: case 8: while (x < x1) { if (d8 < 0) { x++; y++; d8 += d82; } else { x++; d8 += d81; } pDC->SetPixel(x, y, c); } break; case 9: while (y >= y1) { y--; pDC->SetPixel(x, y, c); } break; case 10: while (y <= y1) { y++; pDC->SetPixel(x, y, c); } break; default: break; } ReleaseDC(pDC); }
相关文章推荐
- Struts2_Constant标签认识以及查文件源码和api文档[6]
- Socket 通信原理机制
- Android Studio打包.so文件教程
- 几个主流的Java连接池整理 (转) (2012-01-04 23:48:02)转载▼
- 快速上手php:使用PhpStrom部署项目
- ServletContext对象
- 115.Oracle数据库SQL开发之 PLSQL编程——循环
- MapReduce编程实例之自定义分区
- 交叉编译构建环境搭建
- ubuntu环境下安装R
- BZOJ 3916: [Baltic2014]friends( hash )
- Openstack学习历程_1_视频
- 泛型通配符
- yum源的本地配置方法(对于虚拟机来说)
- 114.Oracle数据库SQL开发之 PLSQL编程——变量和类型
- Python数据类型-----数字&字符串
- c++ primer第五版(中文)习题答案 第三章第六节-多维数组
- 前端之路——2015-11-25
- 安卓设备保持屏幕灯常亮的方法。
- 113.Oracle数据库SQL开发之 PLSQL编程——块结构