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) * radius
。 radius
已经包含在切线向量中,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
(你需要向中心移动才能进入圆圈的数量)。
我无法理解此函数背后的数学原理。我想听听这里写的公式背后的逻辑(尤其是这个切向和径向因子是什么)来创建稍后(当它将 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) * radius
。 radius
已经包含在切线向量中,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
(你需要向中心移动才能进入圆圈的数量)。