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

如何将粗2D线渲染为多边形?

  •  21
  • BenAlabaster  · 技术社区  · 17 年前

    易于理解的 周围的资源可以提供算法洞察力、代码或任何有关有效执行此操作的更多信息?

    我当然愿意自己编写代码,但有许多退化情况(小线段+厚宽度+锐角)会产生各种连接问题。哪怕是一点点帮助,我都可以省下几个小时来处理这些问题。

    编辑:这里有一个退化案例的例子,如果你只是从一个顶点到另一个顶点,它会导致丑陋。红色是原始路径。橙色块是以指定宽度绘制的矩形,在每个线段上对齐并居中。

    9 回复  |  直到 6 年前
        1
  •  4
  •   Nils Pipenbrinck    17 年前

    但是,您可以使用混合方法:

    为自己编写一个例程,检查连接是否可以从简单的几何图形中毫无问题地构造。为此,必须检查连接角度、线条宽度和连接线段的长度(小于其宽度的线段为PITA)。通过一些启发式方法,您应该能够将所有的琐碎情况分类。

    我不知道你的平均线数据是什么样子的,但在我的例子中,超过90%的宽线没有退化的情况。

    对于所有其他行:

    您很可能已经发现,如果您容忍过度拉伸,则生成几何体要容易得多。这样做,让多边形CSG算法和细分算法来完成这项艰巨的工作。

    我已经评估了大多数可用的tesselation软件包,最后使用了GLU tesselator。它快速、健壮,从未崩溃(与大多数其他算法不同)。它是免费的,许可证允许我将其纳入商业计划。镶嵌的质量和速度都很好。您将无法获得delaunay三角剖分质量,但因为您只需要渲染三角形,所以这不是问题。

    如果在PC上使用OpenGL进行渲染,则可能需要将tesselation/CSG作业从CPU移动到GPU,并使用模具缓冲区或z缓冲区技巧来删除过度绘制。这要容易得多,甚至可能比CPU细分更快。

        2
  •  3
  •   Boris Dalstein    11 年前

    我刚刚发现了这项惊人的工作:

    http://www.codeproject.com/Articles/226569/Drawing-polylines-by-tessellation

    它似乎能做你想做的事情,而且它的许可证甚至允许在商业应用中使用它。此外,作者在详细介绍他的方法方面做得非常出色。我可能会在某个时候尝试一下,以取代我自己的不太完美的实现。

        3
  •  2
  •   Neil N HLGEM    17 年前

        4
  •  1
  •   Mario S    13 年前

    最后我不得不把手弄脏,写了一个小的ribbonizer来解决类似的问题。

    对我来说,问题是我想要OpenGL中的粗线条,而这些线条没有我在iPhone上使用OpenGL看到的那种工件。在研究了各种解决方案之后;贝塞尔曲线和类似的东西——我认为这可能是最简单的,只做我自己的。有两种不同的方法。

    一种方法是找到两个线段之间的交角,然后沿该交线移动到离曲面一定距离的位置,并将其视为功能区顶点。我试过了,但它看起来并不直观;色带的宽度会有所不同。

    我用两种方法解决了锐角问题。Paul Bourke直线相交算法(我以未优化的方式使用)建议检测交点是否在线段内部。由于两个线段是相同的,我只需要测试其中一个线段的交点。然后我可以仲裁如何解决这个问题;无论是通过在两端之间捏造一个最佳点,还是通过戴上一个端盖(这两种方法看起来都不错),端盖方法都可能摆脱opengl的多边形正面/背面排序。

    http://paulbourke.net/geometry/lineline2d/

    请在此处查看我的源代码: https://gist.github.com/1474156

        5
  •  0
  •   Igor Brejc    17 年前

    我对此也很感兴趣,因为我想完善我的映射应用程序的( Kosmos http://wiki.openstreetmap.org/wiki/Kosmos_Rendering_Help#Rendering_Options

    我不确定这是否是你需要的。

        6
  •  0
  •   Cruachan    17 年前

    我想我应该用一种细分算法。的确,在大多数情况下,使用这些方法的目的是减少顶点的数量以优化渲染,但在您的情况下,您可以参数化以保留所有细节,并且优化的可能性可能会很有用。

    在web上有很多细分算法和代码——几年前我在DLL中封装了一个纯C语言,用于Delphi景观渲染器,对于高级图形编码教程和类似课程来说,它们并不少见。

        7
  •  0
  •   GSerg    17 年前
        8
  •  0
  •   kikito    16 年前

    工件是以这种方式屏蔽的,如果您可以使用“圆角”和一些过度拉伸,那么实现起来非常容易。

        9
  •  0
  •   Ketan    16 年前

    为什么不能使用GL_LINES原语来执行您想要执行的操作?您可以指定宽度、过滤、平滑度和纹理。可以使用glDrawArrays()渲染所有顶点。我知道这不是你想要的东西,但当你专注于2D绘图时,这可能是更容易的方法。(搜索纹理线条等)

    推荐文章