【计算机图形学】实验二 · 绘制任意斜率的直线段
程序员文章站
2022-07-14 10:13:03
...
直线段的扫描转换算法【理论知识,学习必看】
一、实验任务
- 掌握任意斜率直线段的中点Bresenham扫描转换算法。
- 掌握CLine直线类的设计方法。
- 掌握状态栏编程方法。
二、实验要求
设计CLine直线类,其数据成员为直线段的起点坐标P0和终点坐标P1,成员函数为MoveTo()和LineTo()函数。
- CLine类的LineTo()函数使用中点Bresenham算法绘制任意斜率k的直线段,包括k=±∞、k>1、0≤k≤1、-1≤k<0和k<-1五种情况。
- 在屏幕客户区按下鼠标左键选择直线的起点,保持鼠标左键按下并移动鼠标到另一位置,弹起鼠标左键绘制任意斜率的直线段。
- 在状态栏动态显示鼠标光标移动时的位置坐标。
三、实验环境
- Visual Studio 2017
- C++ MFC
四、效果展示
四、核心代码
void CLine::MoveTo(CDC *, CPoint P) { P0 = P; } void CLine::LineTo(CDC *pDC, CPoint tP) { P1 = tP; double eps = 1e-6; CPoint p, t; if (fabs(P0.x - P1.x) < eps) { if (P0.y > P1.y) { t = P0; P0 = P1; P1 = t; } for (p = P0; p.y < P1.y; p.y++) { pDC->SetPixel(round(p.x), round(p.y), RGB(0.0, 0.0, 0.0)); } } else { double k, d; k = (P1.y - P0.y)*1.0 / (P1.x - P0.x); if (k > 1.0) { if (P0.y > P1.y) { t = P0; P0 = P1; P1 = t; } d = 1 - 0.5*k; for (p = P0; p.y < P1.y; p.y++) { pDC->SetPixel(round(p.x), round(p.y), RGB(0.0, 0.0, 0.0)); if (d >= 0) { p.x++; d += 1 - k; } else { d += 1; } } } else if (k >= 0 && k <= 1.0) { if (P0.x > P1.x) { t = P0; P0 = P1; P1 = t; } d = 0.5 - k; for (p = P0; p.x < P1.x; p.x++) { pDC->SetPixel(round(p.x), round(p.y), RGB(0.0, 0.0, 0.0)); if (d >= 0) { d -= k; } else { p.y++; d += 1 - k; } } } else if (k < 0 && k >= -1.0) { if (P0.x > P1.x) { t = P0; P0 = P1; P1 = t; } d = -0.5 - k; for (p = P0; p.x < P1.x; p.x++) { pDC->SetPixel(round(p.x), round(p.y), RGB(0.0, 0.0, 0.0)); if (d > 0) { p.y--; d -= 1 + k; } else { d -= k; } } } else if (k < -1.0) { if (P0.y < P1.y) { t = P0; P0 = P1; P1 = t; } d = -1 - 0.5*k; for (p = P0; p.y > P1.y; p.y--) { pDC->SetPixel(round(p.x), round(p.y), RGB(0.0, 0.0, 0.0)); if (d >= 0) { d -= 1; } else { p.x++; d -= 1 + k; } } } } P0 = tP; }