使用OpenGL绘制椭圆或圆时,我们应该使用多少个顶点?

时间:2010-02-11 10:08:58

标签: opengl

我们应该盲目使用360顶点吗? 720似乎工作得更好,但我们在哪里停止?

2 个答案:

答案 0 :(得分:9)

取决于您可以容忍的误差(即视觉质量)和圆的大小(椭圆)。一个更大的圆圈将需要更多的点来达到相同的质量。您可以通过一些数学计算出给定错误所需的精确点数。

如果考虑由一系列线段表示的圆,则线段的端点恰好位于圆上(忽略像素网格)。实圆与线段表示之间的最大偏差发生在每个线段的中心,并且所有线段的误差相同。

从逆时针方向看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)

重新排列,以便我们the

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分。因此,如果我们使用32个点绘制一个半径为100的圆,那么我们最差的像素将会偏离不到一半,这意味着我们绘制的每个像素都将位于正确的位置(忽略锯齿)。

这种分析也可以用于省略号,但本着所有好的数学精神,留给读者练习;)(唯一的区别是确定最大错误发生的位置)。

答案 1 :(得分:2)

与您使用的分辨率一样多,或者视觉效果需要准确表示。这很难说,而且主要取决于你想要达到的目标。在CAD程序中,具有视觉上类似于八边形的圆可能是令人讨厌的。另一方面,如果你在iPhone上编写游戏,如果汽车的轮子看起来像八角形,那就没什么大不了的了。

您可以使用的一种可能策略是根据当前视图的分辨率评估每个线段的长度,如果长度超过3个像素,则增加您使用的顶点数量,但仅限于可见段。这样,您可以在放大时增加分辨率,但不必描述您不会绘制的顶点。