这篇着重光栅化2D直线的算法实现
一、数据结构设置
//************************基本数据结构*******************
typedef struct { float x, y; } vector_t;
typedef vector_t point_t;//顶点
typedef struct { float r, g, b,a; } color_t;//颜色
目前还是2d,也不需要3d变换,暂时只需要x,y2个坐标数据
二、DDA画线算法
void DrawLineDDA2d(point_t v1, point_t v2,color_t c)//DDA画线算法
{
glColor4d(c.r, c.g, c.b,c.a);
float x1 = v1.x;
float y1 = v1.y;
float x2 =v2.x;
float y2 = v2.y;
float length = __max(abs(x1 - x2), abs(y1 - y2));
float dx = (x2 - x1) / length;
float dy = (y2 - y1) / length;
float x = x1 + 0.5;
float y = y1 + 0.5;
int i = 0;
while (i <= length)
{
glVertex2i((int)x, (int)y);
x += dx;
y += dy;
i++;
}
}
此算法参考《计算机图形学的算法基础》
利用公式完成绘制
三、中点画线算法
void DrawLineMid(point_t v1, point_t v2,color_t c)//中点画线算法
{
glColor4d(c.r, c.g, c.b, c.a);
float x1 = v1.x;
float y1 = v1.y;
float x2 = v2.x;
float y2 = v2.y;
float dx = x2 - x1;
float dy = y2 - y1;
float d = dy - dx;
int x = x1+0.5;
int y = y1+0.5;
glVertex2i((int)x1, (int)y1);
while (x < x2)
{
if (d >= 0)
{
glVertex2i(x++, y);
d -= dy;
}
else if (d < 0)
{
glVertex2i(x++, y++);
d += dy - dx;
}
}
}
这个算法仅限第一象限
希望扩展到全坐标系,参考无幻博客
http://blog.youkuaiyun.com/akof1314/article/details/5447652
四、Bresenham算法
void DrawLineBre(point_t v1, point_t v2, color_t c)//Bresenham算法
{
glColor4d(c.r, c.g, c.b, c.a);
float x1 = v1.x;
float y1 = v1.y;
float x2 = v2.x;
float y2 = v2.y;
int x = x1;
int y = y1;
float dx =abs(x1-x2);
float dy = abs(y2 - y1);
int s1 = Sgn(x2 - x1);
int s2 = Sgn(y2 - y1);
bool IntChange = false;
if (dy > dx)
{
swap(dy, dx);
IntChange = true;
}
float e = 2 * dy - dx;
for (int i = 0; i < dx; i++)
{
glVertex2i(x, y);
if(e>0)
{
if (IntChange)x += s1;
else x += s2;
e =e- 2*dx;
}
if (IntChange) y += s2;
else y += s1;
e += 2 * dy;
}
}
五、测试画线案例
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT); // 清屏幕
glPointSize(1);
glBegin(GL_POINTS);
point_t v1{ 10,15 };
point_t v2{ 400,405 };
point_t v3{ 100,405 };
color_t c{ 1.0,1.0,0,1.0 };//黄色
DrawLineBre(v1,v2,c);
glEnd();
glFlush(); // 将所有输出到显示屏上
}