部分凸包

Partial Convex Hull

我有一个顶点为 P1、P2、P3、.....P11 的多边形。我的顶点坐标数据类型是double。

我在P1,P7之间也有一条线

我想在 P1 和 P7 之间创建一个部分凸包,并在 P7 之后保留我原来的多边形顶点。

所以最终的多边形如下;

到目前为止,我将整个多边形转换为凸包,删除凸包中的顶点并添加包顶点。它适用于小多边形,但当顶点数量增加时,以这种方式管理起来并不容易。

我试图寻找可用于部分凸包的 c# 算法,但除了一些研究外我找不到任何东西。

有什么想法吗?

从多边形中删除顶点 P8 到 P11 并将它们存储起来,然后 运行 对剩下的(P1 到 P7)进行凸包转换。之后,重新插入顶点 P8 到 P11(在 P7 和 P1 之间)。

我使用 DotSpatial 裁剪了多边形

internal static IGeometry Polygonize(IGeometry geometry)
        {
            var lines = LineStringExtracter.GetLines(geometry);
            var polygonizer = new Polygonizer();
            polygonizer.Add(lines);
            var polys = polygonizer.GetPolygons();
            var polyArray = GeometryFactory.ToGeometryArray(polys);
            return geometry.Factory.CreateGeometryCollection(polyArray);
        }

        internal static IGeometry PolygonizeForClip(IGeometry geometry, IPreparedGeometry clip)
        {
            var lines = LineStringExtracter.GetLines(geometry);
            var clippedLines = new List<IGeometry>();
            foreach (ILineString line in lines)
            {
                if (clip.Contains(line))
                    clippedLines.Add(line);
            }
            var polygonizer = new Polygonizer();
            polygonizer.Add(clippedLines);
            var polys = polygonizer.GetPolygons();
            var polyArray = GeometryFactory.ToGeometryArray(polys);
            return geometry.Factory.CreateGeometryCollection(polyArray);
        }

        internal static IGeometry SplitPolygon(IGeometry polygon, IGeometry line)
        {
            var nodedLinework = polygon.Boundary.Union(line);
            var polygons = Polygonize(nodedLinework);

            // only keep polygons which are inside the input
            var output = new List<IGeometry>();
            for (var i = 0; i < polygons.NumGeometries; i++)
            {
                var candpoly = (IPolygon)polygons.GetGeometryN(i);
                if (polygon.Contains(candpoly.InteriorPoint))
                    output.Add(candpoly);
            }

            return polygon.Factory.BuildGeometry(output);
        }

        internal static IGeometry ClipPolygon(IGeometry polygon, IPolygonal clipPolygonal)
        {
            var clipPolygon = (IGeometry)clipPolygonal;
            var nodedLinework = polygon.Boundary.Union(clipPolygon.Boundary);
            var polygons = Polygonize(nodedLinework);


            // only keep polygons which are inside the input
            var output = new List<IGeometry>();
            for (var i = 0; i < polygons.NumGeometries; i++)
            {
                var candpoly = (IPolygon)polygons.GetGeometryN(i);
                var interiorPoint = candpoly.InteriorPoint;
                if (polygon.Contains(interiorPoint) &&

                    clipPolygon.Contains(interiorPoint))
                    output.Add(candpoly);
            }

            return polygon.Factory.BuildGeometry(output);
        }

然后

var Splitted = SplitPolygon(Polygon, Line);

然后添加部分。