代码之家  ›  专栏  ›  技术社区  ›  Cheery

如何镶嵌bezier三角形?

  •  4
  • Cheery  · 技术社区  · 16 年前

    我关心的是二次贝塞尔三角形,我正试图将其细分以渲染它们。

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

    特别是,我需要一个自适应细分算法,它允许我定义边上的线段数量。我不确定我是否能做到这一点,所以我也想听听统一镶嵌技术。

    最困难的是,我在计算贝塞尔曲面上某点的法线时遇到了麻烦,我不确定是否需要,但一直在努力解决。

    1 回复  |  直到 16 年前
        1
  •  1
  •   Cheery    16 年前

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

    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
    

    对于以这种方式镶嵌三角形,问题会很复杂。您需要根据边Bezier的角度驱动自适应tesselator算法。有三种独特的方法可以在镶嵌时分割三角形。

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

    为这些模式定义细分结果,您就很顺利了。维基百科的文章中只描述了一条边的镶嵌关系。

    “2条边”可以通过先分割一条边,然后再分割另一条边直接获得。

    “3边”是一个有点多的工作,以找出。但是你可以看到“两条边”——案例给你带来了一条中间边。对于二次贝塞尔三角形,它是此处出现的菱形的平均和:

    --------      /\
    \      /     /  \
     \____/     -____-
      \  /       \  /
       \/         \/
    
    推荐文章