英文:
Circle triangulation
问题
我目前正在尝试使用OpenGL,并绘制了许多需要分解为三角形的圆(三角化圆)。
我通过递增的角度来计算三角形的顶点,并使用 cos()
和 sin()
来获取一个顶点的 x 和 y 值。
我在互联网上搜索了一些关于以最佳和最高效的方式执行此操作的信息,尽管可用的信息不多,但我意识到我目前的方法使用的是细长的三角形,不太好。一个更好的方法是从一个等边三角形开始,然后重复添加覆盖尚未覆盖的最大可能区域的三角形。
我想知道这是否是最高效的方法,如果是的话,如何在实际代码中实现它。
我找到该方法的网站:链接
英文:
I am currently experimenting with openGL, and I'm drawing a lot of circles that I have to break down to triangles (triangulate a circle).
I've been calculating the vertices of the triangles by having an angle that is incremented, and using cos()
and sin()
to get the x and y values for one vertex.
I searched a bit on the internet about the best and most efficient way of doing this, and even though there's not much information avaliable realized that thin and long triangles (my approach) are not very good. A better approach would be to start with an equilateral triangle and then repeatedly add triangles that cover the larges possible area that's not yet covered.
left - my method; right - new method
I am wondering if this is the most efficient way of doing this, and if yes, how would that be implemented in actual code.
The website where I found the method: link
答案1
得分: 1
两种三角剖分各有其优点和缺点。
三角形扇形(Triangle FAN)具有等大小的三角形,有时在使用纹理(和其他插值内容)时看起来更好,生成代码简单,使用参数化圆方程和循环即可。
逐渐增加细节的网格具有较少的三角形,可以轻松支持LOD,可能更快。但点的数量不是任意的(3、6、12、24、48……)。代码略微复杂,您可以:
-
从等边三角形开始,记住周长边缘
将三角形
(p0, p1, p2)
添加到网格,将边缘(p0, p1)、(p1, p2)、(p2, p0)
添加到周长。 -
对于周长上的每条边
(p0, p1)
计算:
p2 = 0.5*(p0+p1); // 中点 p2 = r*p2/|p2|; // 将其归一化为圆周,假设(0,0)为中心
将三角形
(p0, p1, p2)
添加到网格,并用(p0, p2)、(p2, p1)
替换p0, p1
边请注意,在当前细节级别中,
r/|p2|
对于所有边来说都是相同的,因此不需要一遍又一遍地计算昂贵的|p2|
。 -
跳转到步骤#2,直到您获得足够密集的三角剖分
所以有两个循环和一些动态列表(点、三角形、周长边缘,以及如果不进行原地操作,还有一些临时变量)。此方法也不需要三角函数(可以修改为生成三角形扇)。
这里有类似的内容:
英文:
both triangulations has their pros and cons
The Triangle FAN has equal sized triangles which sometimes looks better with textures (and other interpolated stuff) and the code to generate is simple for loop with parametric circle equation.
The increasing detail mesh has less triangles and can easily support LOD which might be faster. However number of points is not arbitrary (3,6,12,24,48,...). The code is slightly more complicated you could:
-
start with equilateral triangle remembering circumference edges
so add triangle
(p0,p1,p2)
to mesh and edges(p0,p1),(p1,p2),(p2,p0)
to circumference. -
for each edge
(p0,p1)
of circumferencecompute:
p2 = 0.5*(p0+p1); // mid point p2 = r*p2/|p2|; // normalize it to circle circumference assuming (0,0) is center
add triangle
(p0,p1,p2)
to mesh and replacep0,p1
edge with(p0,p2),(p2,p1)
edgesnote that
r/|p2|
will be the same for all edges in current detail level so no need to compute expensive|p2|
over and over again. -
goto #2 until you have enough dense triangulation
so 2 for loops and few dynamic lists (points,triangles,circumference_edges,and some temps if not doing this inplace). Also this method does not need goniometrics at all (can be modified to generate the triangle fan too).
Here similar stuff:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论