При рисовании эллипса или круга с OpenGL, сколько вершин мы должны использовать?

Мы должны просто вслепую использовать 360 вершин? 720, кажется, работает лучше, но где мы останавливаемся?

5
задан Plumenator 11 February 2010 в 10:08
поделиться

2 ответа

Это зависит от того, сколько ошибок вы можете допустить (т.е. визуального качества) и размера круга (эллипс). Для большего круга потребуется больше очков, чтобы добиться того же качества. Вы можете точно определить, сколько очков вам нужно для данной ошибки, с помощью математики.

Если вы рассматриваете круг, представленный серией линейных сегментов, конечные точки линейных сегментов лежат точно на окружности (без учета пиксельной сетки). Наибольшее отклонение между реальной окружностью и нашим представлением линейного сегмента происходит в центре каждого линейного сегмента, и эта ошибка одинакова для всех линейных сегментов.

Если смотреть на первый сегмент от оси x, идущий против часовой стрелки, его две конечные точки следующие:

A = (r, 0)
B = (r . cos(th), r . sin(th))

где r - радиус окружности, а th - это угол, охватываемый каждым линейным сегментом (например, если у нас есть 720 точек, тогда каждый линейный сегмент покрывает 0,5 градуса, поэтому th будет 0,5 градуса).

Середина этого линейного сегмента находится в точке

M = A + (B - A) / 2
  = (r, 0) + (r (cos(th) - 1) / 2, r . sin(th) / 2)
  = (r / 2) . (1 + cos(th), sin(th))

, а расстояние от начала координат до точки равно

l = (r / 2) . sqrt((1 + cos(th))^2 + (sin(th))^2)
  = (r / 2) . sqrt(2) . sqrt(1 + cos(th))

Если бы наше представление линейного сегмента было идеальным, то эта длина должна быть равна радиусу (средняя точка линейного сегмента должен упасть на круг). Обычно бывает некоторая ошибка, и эта точка будет немного меньше радиуса. Ошибка составляет

e = r - l
  = r . (1 - sqrt(2) . sqrt(1 + cos(th)) / 2)

Переупорядочивание, поэтому мы имеем th в терминах e и r

2 . e / r = 2 - sqrt(2) . sqrt(1 + cos(th))
sqrt(2) . sqrt(1 + cos(th)) = 2 . (1 - e / r)
1 + cos(th) = 2 . (1 - e / r)^2

th = arccos(2 . (1 - e / r)^2 - 1)

. Это позволяет нам вычислить максимальный угол, который мы можем иметь между каждой точкой для достижения некоторая ошибка. Например, предположим, что мы рисуем круг с радиусом 100 пикселей и нам нужна максимальная ошибка 0,5 пикселя. Мы можем вычислить

th = arccos(2 . (1 - 0.5 / 100)^2 - 1))
   = 11.46 degrees

. Это соответствует ceil (360 / 11,46) = 32 точек. Итак, если мы нарисуем круг радиуса 100 с использованием 32 точек, наш худший пиксель будет смещен менее чем на половину, что должно означать, что каждый пиксель, который мы рисуем, будет в правильном месте (игнорируя сглаживание).

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

9
ответ дан 13 December 2019 в 19:27
поделиться

столько, сколько требует используемое вами разрешение, или столько, сколько требуется для точного представления визуального результата. Трудно сказать, и в основном это зависит от того, чего вы хотите добиться. В CAD-программе окружность, визуально похожая на восьмиугольник, может раздражать. С другой стороны, если вы программируете игру на iphone, если колесо автомобиля выглядит как восьмиугольник, это не так уж важно.

Возможная стратегия, которую вы можете использовать, заключается в оценке длины каждого сегмента относительно разрешения текущего вида, и если длина больше, чем, скажем, 3 пикселя, увеличьте количество используемых вершин, но только для видимых сегментов. Таким образом, вы увеличите разрешение при увеличении масштаба, но вам не придется описывать вершины, которые вы не собираетесь рисовать.

2
ответ дан 13 December 2019 в 19:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: