【问题标题】:How to prepare the vertices of a sphere to be processed by a Delaunay triangulation algorithm?如何准备要由 Delaunay 三角剖分算法处理的球体顶点?
【发布时间】:2017-02-18 01:17:39
【问题描述】:

我正在做一个个人项目来创建一个简单的 3D 渲染程序。 到目前为止它可以渲染简单的固体,如立方体、长方体、四面体等......

该程序通过提供一组(CCW 有序)顶点来工作,然后使用 Delanuay 算法对这些顶点进行三角剖分。 我没有使用任何第三方库,所有内容都是从头开始用 VB.NET 编写的……我假设算法已正确实现。

这是为立方体提供顶点的代码(是的,我知道生成的实体的实际长度将是 2 * length):

Public Shared Function Cube(length As Double) As List(Of Point3d)
    '   G-----F
    '  /|    /|
    ' B-----A |
    ' | H---|-E
    ' |/    |/ 
    ' C-----D

    Dim A As New Point3d(length, length, -length)
    Dim B As New Point3d(-length, length, -length)
    Dim C As New Point3d(-length, -length, -length)
    Dim D As New Point3d(length, -length, -length)
    Dim E As New Point3d(length, -length, length)
    Dim F As New Point3d(length, length, length)
    Dim G As New Point3d(-length, length, length)
    Dim H As New Point3d(-length, -length, length)

    Return New List(Of Point3d) From {A, B, C, D, E, F, G, H}
End Function

对于球体,我想我可以为 XY 平面上的 180° 弧生成一组顶点,然后沿 X 轴旋转该弧。不幸的是,Delaunay 算法似乎创建了一个不符合欧拉封闭曲面公式的无效实体:V - E + F = 2

这是应该为球体生成顶点的代码:

Public Shared Function Sphere(radius As Double) As List(Of Point3d)
    Dim vertices As New List(Of Point3d)
    Dim arc As New List(Of Point3d)
    Dim p As New Point3d(0, 0, 0)
    Dim angleStep As Double = 45.0

    For ca As Double = 0.0 To 180.0 Step angleStep
        arc.Add(New Point3d(radius * Math.Cos((ca - 180.0) * Point3d.ToRad),
                               radius * Math.Sin((ca - 180.0) * Point3d.ToRad),
                               0))
    Next
    vertices.AddRange(arc)

    Dim v As Point3d
    For ax As Double = 0 To 360.0 Step angleStep
        For i As Integer = 0 To arc.Count - 1
            v = arc(i).RotateX(ax)

            Dim isDuplicate As Boolean = False
            For j As Integer = 0 To vertices.Count - 1
                If vertices(j).IsSimilar(v) Then
                    isDuplicate = True
                    Exit For
                End If
            Next
            If Not isDuplicate Then vertices.Add(v)
        Next
    Next

    Return vertices
End Function

有趣的是,如果我将每个顶点的角度步长设置为 90°,程序会如预期的那样生成一个有效的八面体。但是减小角度步长以使球体具有更多面,会产生无效的实体。

所以...问题是:我做错了什么?

更新(2016 年 10 月 10 日): 我已经在 GitHub 上发布了完整的源代码:https://github.com/morphx666/3DEngine

【问题讨论】:

  • XZ 平面的 Y=0。你的弧有 Z=0。 (另外,您的立方体的边长为Length * 2。)
  • 抱歉,打错了;我会更正帖子。至于长度问题,是的,我知道……不过,这些问题都不会对我遇到的问题产生任何影响。
  • 您的IsSimilar 功能可能有问题吗?如果您不删除重复的顶点,算法会起作用吗?对于某些面孔,您的 CCW 是否以 CW 结尾? - 也许从 -180 到 180 可以解决这个问题(尽管我对此表示怀疑)。
  • 另外,你能渲染面部的内部和外部,使用不同的颜色吗?查看对象旋转的动画可能会显示出问题所在。
  • 这是个好主意。渲染引擎目前无法做到这一点,但我认为这是值得的。完成必要的修改后,我会回复。

标签: c# vb.net 3d computational-geometry delaunay


【解决方案1】:

如果不知道 Delaunay 三角剖分的实现,就很难说出任何事情。但是,仅从标题来看,我怀疑存在稳健性问题。 * 球体上点的情况非常退化。 * 我猜你正在使用浮点运算,不是吗? 参见 https://hal.archives-ouvertes.fr/inria-00560388/ 以了解 CGAL 库 (www.cgal.org) 处理此类退化的方式。你可以阅读http://www.cgal.org/exact.html关于算术问题。

【讨论】:

  • 我正在准备将代码发布到 GitHub 上。但是,我相信@AndrewMorton 的假设是正确的,假设有些人脸朝后。
猜你喜欢
  • 2020-08-05
  • 1970-01-01
  • 2021-05-27
  • 2017-09-01
  • 2015-01-07
  • 1970-01-01
  • 2020-10-20
  • 2019-04-18
  • 2016-06-12
相关资源
最近更新 更多