计算三角形多边形网格中的孔

时间:2012-10-31 06:31:55

标签: c# wpf 3d computational-geometry

我正在研究WPF中的可视化工具,它具有通过三维形状显示切割平面的功能。例如,像这样的三维几何:

Full Geometry

...用飞机切割。切割后,算法识别沿切割平面的所有唯一轮廓,并以CW或CCW缠绕顺序填充线段列表。任何简单的多边形都易于使用Cutting Ears算法进行三角测量和渲染,如下所示:

Cut Plane Image enter image description here

如果右侧的三角测量输入,左侧平面上可见的内部折线,是否有算法可以重新配置三角测量以构造折线勾勒出的孔?

如果已经使用C#或其他CLR语言编写了算法,我很乐意了解它们。我正在使用WPF调用的Point3D列表来描述MeshGeometry3D三角形网格,但是如果需要我可以显然填充任何数据结构,或者通过研究其他语言代码或伪代码来旋转我自己的类。

编辑:查看已接受的答案;我正在使用Poly2Tri的C#实现,这是一个受约束的Delaunay三角剖分。然而,(图像不按比例)Poly2Tri算法(中心)失败了780段折线,而Cutting Ears(右)没有,直到我剥离了他们的精度输入,提供单精度值upcast as double而不是double 。它现在产生与Cutting Ears不同的三角剖分,但是尊重外折线的边界。

ComplexPoly ComplexCDT ComplexEars

2 个答案:

答案 0 :(得分:2)

使用边界段作为约束来计算约束Delaunay三角剖分。确定内三角形。从那里开始,直到你到达边界。作为积极的副作用,这样的三角测量将具有更好的三角形。

Constrained Delaunay of a zone

答案 1 :(得分:0)

在SketchUp和3DSMax之间制作导出/导入插件时,必须解决完全相同的问题。 Sketchup使用概念或外部和内部循环,而3DS Max是纯几何。

可悲的是,我没有插件,所以我会尽力记住它:

foreach point in outerLoop
{
    // Loop over all other point to find the nearest valid one
    foreach otherPoint in both outerLoop and all innerLoops where otherPoint is not point
    {
        if otherPoint is adjacent to point
            reject otherPoint 

        if distance between point and otherPoint is bigger than previous distance
            reject otherPoint 

        // Test is vector is point outside the geometry in case of convexe shapes
        if cross product of vector from (point - adjacent point) and (point - nearest point) is pointing away from cross product of vectors of (point - both adjacents point)
            reject otherPoint 

        nearestPoint = otherPoint
    }

    for the two adjacentPoint of nearestPoint
    {
        if adjacentPoint is also adjacent to point
            make triangle(point, adjacentPoint, nearestPoint)
        if cross product of vector from (point - adjacent point) and (point - nearest point) is pointing in the same direction as cross product of vectors of (point - both adjacents point)
            make triangle(point, adjacentPoint, nearestPoint)
    }
}

repeat the above for innerLoops point while only checking against other innerLoops

make triangle function should check if the triangle already exist from previous iteration.

它不是非常漂亮,而且有点粗野,但它可以使用无限数量的内部循环,并始终创建最好的三角形。

我很确定会有提高性能的方法,但我从来没有给它足够的时间。