Как инициализировать алгоритм Брезенхема для отображения гиперболы

У меня экзамен по информатике графики, и я пытаюсь понять алгоритм Брезенхэма. Я понимаю отображение линии и круга (я думаю), но когда я выполняю упражнение, в котором мне нужно отобразить гиперболическую функцию, я не могу сделать это правильно.

Гиперболическая функция имеет уравнение 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
Другие вопросы по тегам