Как инициализировать алгоритм Брезенхема для отображения гиперболы - PullRequest
0 голосов
/ 09 апреля 2019

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

Гиперболическая функция имеет уравнение 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,Я использую это только для целей тестирования.

Ответы [ 2 ]

1 голос
/ 10 апреля 2019

Как вы, наверное, знаете, основная идея алгоритмов в стиле Брезенхема заключается в том, что вы делаете серию фиксированных шагов, и на каждом шаге вы принимаете решение.В этом конкретном случае шаги представляют собой 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/

0 голосов
/ 10 апреля 2019

Управляющая переменная FM должна быть инициализирована на расстоянии первой средней точки от кривой.В этом случае вы измеряете расстояние вдвое больше значения неявной функции, т.е. у нас есть

FM = 2 * F(x1 + 1, y1 + 1/2)
   = 2 * [(x1 + 1) * (y1 + 1/2) - 100]
   = 2 * x1 * y1 + 2 * y1 + x1 - 199
...