标签:ati set swa 增加 cout 超出 根据 水平 结果
Line drawing algorithm 罗列了几种在屏幕像素上画直线的算法。
不过如果让我自己想的话,思维过程应该是这样:
算法的输入?两个实数点。
算法的输出?若干个自然数点。
怎么展示算法结果?屏幕上的像素可以抽象成一个二维数组,点作为坐标索引来定位,给二维数组赋值相当于给像素上色。
过程?
直线可以分为:水平的(斜率为零)、垂直的(斜率为无穷大),斜的(其他可能的斜率)。
给定两个实数点,可以算出一个实数域上的直线方程。但显然此方程的解不能直接作为算法的解,它还需要再通过一个函数过滤成自然数的解。
real = line_equation(p1, p2)
nature = func(real)
最直接的想法是每次迭代我都算出实数解,然后和上一个自然数解作比较。e.g. 当 x0 < x1, y0 < y1 时,和当前像素的 y 比较,大于半个像素时说明实数解远了,所以不该继续画在 y 上了,应该画在 y + 1 上。
x0 < x1, y0 < y1
function line(x0, y0, x1, y1)
real slope := (y1 - y0 / x1 - x0)
real realxy:= y0
int y := y0
for x from x0 to x1
realy := realy + slope
if realy - y ≥ 0.5 then
y := y + 1
plot(x, y)
当然根据斜率不同还有一些符号和边界问题,暂且不表。值得注意的是,因为 realy >= y + 0.5
所以 y+1 之后是可能比 realy 大的,但是大不过 0.5 。下次再算 realy 的时候,还可能比 y 小。不过也没关系,我们就继续画在 y 上就行。
计算的是每一像素点与该线之间的误差。误差应为每一点x中,其相对的像素点之y值与该线实际之y值的差距。每当x的值增加1,误差的值就会增加slope。每当误差的值超出0.5,线就会比较靠近下一个映像点,因此y的值便会加1,且误差减1。
x0 < x1, y0 < y1
function line(x0, y0, x1, y1)
real deltax := x1 - x0
real deltay := y1 - y0
real deltaerr := deltay / deltax
real error := 0.0 // No error at start
int y := y0
for x from x0 to x1
plot(x, y)
error := error + deltaerr
if error ≥ 0.5 then
y := y + 1
error := error - 1.0
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int width = 20;
const int height = 20;
const char clear_char = ‘ ‘;
const char mark_char = ‘*‘;
char screen[width][height];
struct point
{
int x, y;
point(int _x, int _y) : x(_x), y(_y) {}
};
struct testcase
{
point p1, p2;
void (*func_draw_line)(point&, point&);
testcase(point _p1, point _p2, void (*func)(point&, point&)) : p1(_p1), p2(_p2), func_draw_line(func) {}
void run() { func_draw_line(p1, p2); }
};
void show_screen()
{
for (int i = 0; i < width; ++i) cout << ‘=‘;
cout << endl;
for (int i = width - 1; i >= 0; --i)
{
for (int j = 0; j < height; ++j)
cout << screen[i][j];
cout << endl;
}
}
void native(point& p1, point& p2)
{
memset(screen, clear_char, sizeof(screen));
// horizontal line
if (p1.y == p2.y)
{
int dx = p1.x < p2.x ? 1 : -1;
for (int x = p1.x; x != p2.x; x += dx)
screen[x][p1.y] = mark_char;
}
// vertical line
else if (p1.x == p2.x)
{
int dy = p1.y < p2.y ? 1 : -1;
for (int y = p1.y; y != p2.y; y += dy)
screen[p1.x][y] = mark_char;
}
// slanted line
else
{
double slope = static_cast<double>(p1.x - p2.x) / (p1.y - p2.y);
int dx = slope > 0 ? 1 : -1;
int starty = p1.y;
int endy = p2.y;
double realx = p1.x;
if (p1.y > p2.y)
{
swap(starty, endy);
realx = p2.x;
}
int x = realx;
for (int y = starty; y <= endy; ++y)
{
screen[x][y] = mark_char;
realx += slope;
if (abs(realx - x) > 0.5) x = x + dx;
}
}
show_screen();
}
int main()
{
testcase tcs[] =
{
{ point(2, 3), point(2, 10), native },
{ point(11, 5), point(1, 5), native },
{ point(1, 1), point(8, 6), native },
{ point(3, 1), point(5, 16), native },
{ point(10, 1), point(1, 17), native },
};
for (testcase& t : tcs) t.run();
return 0;
}
标签:ati set swa 增加 cout 超出 根据 水平 结果
原文地址:https://www.cnblogs.com/tandandan/p/14725697.html