我有一个图形信息学考试,我正在尝试理解布雷森汉姆算法。我理解显示一条线和一个圆(我认为),但是当我做一个必须显示双曲函数的练习时,我无法使其正确。
双曲函数的方程 y = 100/x,我将其转换为 x*y - 100 = 0。我假设当前显示的像素位于屏幕上(x_p,y_p)。我计算了增量,发现当要显示的像素是右边的像素时,I = 2y_p - 1,当要显示的像素在右下角时,I = 2y_p - 2x_p - 5。但是现在我不知道如何初始化。在我的课程中,一条线的初始化是在 x_0 = 0,y_0 = 0 时进行的,对于半径为 R 的圆,它是 x_0 = 0,y_0 = R,但我的夸张是什么?
我想追踪从 x = 10 到 x = 20 的夸张
void trace (const int x1, const int y1, const int x2)
{
int x = x1;
int y = y1;
int FM = //what to put here ???
glVertex2i(x,y);
while (x < x2)
{
if (FM < 0)
{
++x; --y;
const int dSE = 2*y - 2*x - 5;
FM += dSE;
}
else
{
++x;
const int dE = 2*y - 1;
FM += dE;
}
glVertex2i(x,y);
}
}
所以我像这样调用这个函数:
glBegin(GL_POINTS);
trace(10,10,20);
glEnd();
我知道它是旧的OpenGL,我只是将其用于测试目的。
你可能知道,布雷森汉姆风格算法背后的基本思想是,你正在采取一系列固定的步骤,在每一步你都在做一个决定。 在这种特殊情况下,步骤是 10 到 20 之间的x
位置,决定下一个y
值是应该y
还是y - 1
。
要做出此决定,您需要选择最接近下一个坐标x
函数值的 y 值:100 / (x + 1)
。 因此,如果dist(y, 100 / (x + 1))
小于dist(y - 1, 100 / (x + 1))
,则选择y
...否则,请选择y - 1
。 该决定等效于确定以下表达式是否为负数:
err(x, y) = (y - 100 / (x + 1)) ^ 2 - (y - 1 - 100 / (x + 1)) ^ 2
= 2 * (y - 100 / (x + 1)) - 1
= 2 * y - 200 / (x + 1) - 1
由于x + 1
对于我们感兴趣的范围是正的,我们可以乘以它以获得等效的决策值:
err(x, y) = 2 * y * x + 2 * y - 200 - x - 1
= 2 * y * x + 2 * y - x - 201
这是您要用于每个步骤的决策值,因此它也是要用于计算初始决策值的公式。 然后,可以计算err(x + 1, y) - err(x, y)
和err(x + 1, y - 1) - err(x, y)
,以获取要在循环中使用的增量更新公式。
当然,还有其他公式也可以工作,如果您符合以下条件,则任何给定的公式都可能需要进行一些调整:
- 交换
y
的含义与y - 1
决定 - 决定使用
x
和y
的更新前值与更新后值计算决策值 - 想要绘制中心与坐标最近的像素
样品小提琴:https://jsfiddle.net/0e8fnk5h/
控制变量FM
必须初始化为曲线的第一个中点的距离。在这种情况下,您测量距离是隐式函数值的两倍,即我们有
FM = 2 * F(x1 + 1, y1 + 1/2)
= 2 * [(x1 + 1) * (y1 + 1/2) - 100]
= 2 * x1 * y1 + 2 * y1 + x1 - 199