如何镶嵌贝塞尔三角形?

时间:2009-10-14 11:09:43

标签: rendering tesselation

我关心的是二次贝塞尔三角形,我试图用它来渲染它们。

我设法通过像维基百科页面中描述的那样递归地细分三角形来实现这一点。虽然我想更精确地细分。问题是,我要么得到的细分太少,要么太多,因为在该算法的每次迭代中,表面的数量都会翻倍。

特别是我需要一种自适应的tesselation算法,它允许我定义边缘的段数量。我不确定我是否可以得到它,所以我也想听听统一的细分技术。

最困难我在计算bezier曲面中某个点的法线方面遇到了麻烦,我不确定是否需要,但一直试图解决。

1 个答案:

答案 0 :(得分:1)

自适应细分。这有很多算法。但这是一个:

def line_angle((x0,y0),(x1,y1)):
    return atan2(y1-y0,x1-x0)

def adaptive_bezier(p0,p1,p2,lev=32):
    p01 = midpoint(p0,p1)
    p12 = midpoint(p1,p2)
    m = midpoint(p01, p12)
    da = abs(line_angle(p0,p1) - line_angle(p1,p2))
    if da <= max_tolerance or lev <= 0:
        yield m
    else:
        for p in adaptive_bezier(p0,p01,m,lev-1): yield p
        for p in adaptive_bezier(m,p12,p2,lev-1): yield p

对于以这种方式测试三角形,这个问题很复杂。您需要根据边缘贝塞尔角的角度来驱动自适应tesselator算法。在测试时,三角形可以分为三种独特的方式。

 2 edges      one edge     3 edges    
--------     ---------    --------
\  ...//     \   |   /    \ /  \ /
 \/___/       \  |  /      \____/
  \  /         \ | /        \  /
   \/           \|/          \/

定义这些模式的细分结果并且你很好。维基百科文章中仅描述了具有一条边的细分。

通过研究一个边缘分裂的情况,可以得到另外两个细分结果。

“2个边缘”可以通过分割第一个边缘然后分割另一个边缘而直接获得。

“3条边缘”需要更多的工作才能找到答案。但是你可以看到“2个边缘” - 为你带来一个中边缘。在二次贝塞尔曲线三角形的情况下,它是出现在那里的钻石的平均总和:

--------      /\
\      /     /  \
 \____/     -____-
  \  /       \  /
   \/         \/