记录一下自己在原算法基础上,又新拓展个各个象限。其中中点算法没有考虑斜率小于零的情况,其实质和bresenham算法一样,可自行更改。同时没考虑垂直直线的情况,其实也很简单就没写。 代码赋下 c++
// 这里其实就是交换两个点的坐标, 用的异或运算,可自行更改
void SwapPoint(int& x0, int& y0, int& x1, int& y1)
{
x0 ^= x1; // x0 = x0 ^ x1 x0 = x0^ x1^ x1 x1 = x1^ x0 ^ x1 = x0
x1 = x0 ^ x1;
x0 ^= x1;
y0 ^= y1;
y1 = y0 ^ y1;
y0 ^= y1;
}
void DDA(int x0, int y0, int x1, int y1, TGAImage& image, TGAColor color)
{
bool steep = false;
if (abs(x1 - x0) < abs(y1 - y0)) // 过陡
{
steep = true;
std::swap(x0, y0);
std::swap(x1, y1);
}
if (x0 > x1) //处理反向 否则 x0 一直大于x1 不会终止条件
{
//std::swap(x0, x1);
//std::swap(y1, y0);
SwapPoint(x0, y0, x1, y1);
}
float y = y0;
float k = (float)(y1 - y0) / (x1 - x0);
for (; x0 <= x1; x0++)
{
if (steep)
{
image.set((y + 0.5f), x0, color);
}
else
{
image.set(x0, (y + 0.5f), color);
}
y += k;
}
}
// 在DDA基础上只需要(改进)进行整型运算
void HalfPoint(int x0, int y0, int x1, int y1, TGAImage& image, TGAColor color)
{
bool steep = false;
if (abs(x1 - x0) < abs(y1 - y0)) // 过陡
{
steep = true;
std::swap(x0, y0);
std::swap(x1, y1);
}
if (x0 > x1)
{
SwapPoint(x0, y0, x1, y1);
}
int a = y0 - y1, b = x1 - x0; // F(x,y) = ax + by + c (b> 0)
int d1 = 2 * a, d2 = 2 * (a + b); // 实则是 d0 = a+ 0.5, 但d 只是用来判断符号用的,所以转换为整型提升效率
int d = 2 * a + b, y = y0;
image.set(x0, y, color); // 第一个点
for (; x0 < x1; x0++)
{
if (d >= 0) // 中点在 直线 上方
{
d += d1;
}
else // 中点在下方, 则y+ 1
{
y++;
d += d2;
if (steep)
{
image.set(y, x0, color);
}
else {
image.set(x0, y, color);
}
}
}
}
void Bresenham(int x0, int y0, int x1, int y1, TGAImage& image, TGAColor color)
{
bool steep = false;
if (abs(x1 - x0) < abs(y1 - y0)) // 过陡
{
steep = true;
std::swap(x0, y0);
std::swap(x1, y1);
}
if (x0 > x1)
{
SwapPoint(x0, y0, x1, y1);
}
int dx = x1 - x0, dy = y1 - y0;
int uy = 1;
if (dy < 0) // 当 斜率为 小于0时, 这时 y坐标要减
{
dy = -dy;
uy = -1;
}
int e = -dx;
for (; x0 <= x1; x0++)
{
if (steep)
image.set(y0, x0, color);
else
image.set(x0, y0, color);
e += 2 * dy;
if (e > 0)
{
e -= 2 * dx;
y0 += uy;
}
}
}