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

Plu*_*tor 5 opengl

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

Dav*_*ave 9

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

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

从逆时针方向看x轴的第一段,它的两个端点是:

A = (r, 0)
B = (r . cos(th), r . sin(th))
Run Code Online (Sandbox Code Playgroud)

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))
Run Code Online (Sandbox Code Playgroud)

从原点到点的距离是

l = (r / 2) . sqrt((1 + cos(th))^2 + (sin(th))^2)
  = (r / 2) . sqrt(2) . sqrt(1 + cos(th))
Run Code Online (Sandbox Code Playgroud)

如果我们的线段表示是完美的,那么这个长度应该等于半径(线段的中点应该落在圆上).通常会有一些错误,这一点会略小于半径.错误是

e = r - l
  = r . (1 - sqrt(2) . sqrt(1 + cos(th)) / 2)
Run Code Online (Sandbox Code Playgroud)

重新排列,所以我们必须th在以下方面er

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)
Run Code Online (Sandbox Code Playgroud)

这让我们可以计算每个点之间可以达到的最大角度,以达到一定的误差.例如,假设我们正在绘制一个半径为100像素的圆,我们希望最大误差为0.5像素.我们可以算一算

th = arccos(2 . (1 - 0.5 / 100)^2 - 1))
   = 11.46 degrees
Run Code Online (Sandbox Code Playgroud)

这对应于ceil(360 / 11.46) = 32积分.因此,如果我们使用32个点绘制半径为100的圆,那么我们最差的像素将会偏离不到一半,这意味着我们绘制的每个像素都将位于正确的位置(忽略锯齿).

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

  • 你对我的回答是,在猜测可能的值之前,你需要很好地定义你的约束.我能想到的最好的就是使用椭圆的周长作为因素.然而,您的方法可以解决问题.我会尝试这个并尽快回来.谢谢.:-) (2认同)