Мы должны просто вслепую использовать 360 вершин? 720, кажется, работает лучше, но где мы останавливаемся?
Это зависит от того, сколько ошибок вы можете допустить (т.е. визуального качества) и размера круга (эллипс). Для большего круга потребуется больше очков, чтобы добиться того же качества. Вы можете точно определить, сколько очков вам нужно для данной ошибки, с помощью математики.
Если вы рассматриваете круг, представленный серией линейных сегментов, конечные точки линейных сегментов лежат точно на окружности (без учета пиксельной сетки). Наибольшее отклонение между реальной окружностью и нашим представлением линейного сегмента происходит в центре каждого линейного сегмента, и эта ошибка одинакова для всех линейных сегментов.
Если смотреть на первый сегмент от оси 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 точек, наш худший пиксель будет смещен менее чем на половину, что должно означать, что каждый пиксель, который мы рисуем, будет в правильном месте (игнорируя сглаживание).
Этот вид анализа может быть выполнен и для эллипсов, но в духе всех хороших математических выкладок, которые оставлены в качестве упражнения для читателя;) (единственная разница заключается в определении, где возникает максимальная ошибка).
столько, сколько требует используемое вами разрешение, или столько, сколько требуется для точного представления визуального результата. Трудно сказать, и в основном это зависит от того, чего вы хотите добиться. В CAD-программе окружность, визуально похожая на восьмиугольник, может раздражать. С другой стороны, если вы программируете игру на iphone, если колесо автомобиля выглядит как восьмиугольник, это не так уж важно.
Возможная стратегия, которую вы можете использовать, заключается в оценке длины каждого сегмента относительно разрешения текущего вида, и если длина больше, чем, скажем, 3 пикселя, увеличьте количество используемых вершин, но только для видимых сегментов. Таким образом, вы увеличите разрешение при увеличении масштаба, но вам не придется описывать вершины, которые вы не собираетесь рисовать.