Как инициализировать алгоритм Брезенхема для отображения гиперболы
У меня экзамен по информатике графики, и я пытаюсь понять алгоритм Брезенхэма. Я понимаю отображение линии и круга (я думаю), но когда я выполняю упражнение, в котором мне нужно отобразить гиперболическую функцию, я не могу сделать это правильно.
Гиперболическая функция имеет уравнение 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, но что это за гипербола?
Я хочу проследить гиперболу от х = 10 до х = 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, я использую его только для целей тестирования.
2 ответа
Как вы, наверное, знаете, основная идея алгоритмов в стиле Брезенхема заключается в том, что вы делаете серию фиксированных шагов, и на каждом шаге вы принимаете решение. В этом конкретном случае шаги x
позиции между 10 и 20, и решение является ли следующий y
значение должно быть y
или же y - 1
,
Чтобы принять это решение, вы хотите выбрать значение y, которое будет ближе к значению функции для следующего x
координата: 100 / (x + 1)
, Итак, вы выбираете y
если dist(y, 100 / (x + 1))
меньше чем dist(y - 1, 100 / (x + 1))
... в противном случае, выбрать 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