OpenGL 中圆的细分

Tesselation of the circle in OpenGL

我无法理解此函数背后的数学原理。我想听听这里写的公式背后的逻辑(尤其是这个切向和径向因子是什么)来创建稍后(当它将 vec3 数组发送到一个函数时)在 OpenGL 中形成一个圆的点。

void doTesselate(const Arc& arc, int slices, std::vector<glm::vec3>& vertices)
{
  double dang = (arc.endAngle() - arc.startAngle()) * Deg2Rad;

  double radius = arc.radius();
  double angIncr = dang / slices;

  double tangetial_factor = tan(angIncr);
  double radial_factor = 1 - cos(angIncr);

  double startAngle = arc.startAngle() * Deg2Rad;
  const glm::vec3& center = arc.center();

  double x = center.x - radius * cos(startAngle);
  double y = center.y - radius * sin(startAngle);

  ++slices;
  for (int ii = 0; ii < slices; ii++) {
    vertices.push_back(glm::vec3(x, y, center.z));

    double tx = center.y - y;
    double ty = x - center.x;

    x += tx * tangetial_factor;
    y += ty * tangetial_factor;

    double rx = center.x - x;
    double ry = center.y - y;

    x += rx * radial_factor;
    y += ry * radial_factor;
  }
}

思路如下:

从当前点开始,沿切线方向走一点,然后回到中心。

矢量(tx, ty)是当前点的切线,长度等于半径。为了达到新的角度,您必须沿切线移动 tan(angle) * radiusradius 已经包含在切线向量中,tan(angle)tangetial_factor(您可以直接从切线的定义中获得)。

之后,(rx, ry)就是指向中心的向量。该向量的长度为 l:

cos(angle) = radius / l
l = radius / cos(angle)

我们需要找到这个向量的倍数m,使得修正后的点再次位于给定半径的圆上。如果我们只检查长度,那么我们想找到:

target distance = current distance    - m * length of (rx, ry)
         radius = radius / cos(angle) - m * radius / cos(angle)
              1 = (1 - m) / cos(angle)
     cos(angle) = 1 - m
 1 - cos(angle) = m

这个倍数正好是radial_factor(你需要向中心移动才能进入圆圈的数量)。