При рисовании эллипса или круга с помощью OpenGL, сколько вершин мы должны использовать? - PullRequest
5 голосов
/ 11 февраля 2010

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

Ответы [ 2 ]

9 голосов
/ 11 февраля 2010

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

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

Если смотреть на первый сегмент оси 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 точки, наш худший пиксель будет смещен менее чем на половину, что должно означать, что каждый нарисованный нами пиксель будет в правильном месте (игнорируя наложение).

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

2 голосов
/ 11 февраля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...