예제 #1
0
 // 给定弧段计算夹角并加入拓扑结构
 static void VertexTopo(GeomArc arc, LineSegment seg)
 {
     if (!vertPool.ContainsKey(seg.Item1))
     {
         vertPool[seg.Item1] = new SortedDictionary <double, GeomArc>();
     }
     vertPool[seg.Item1][seg.Angle] = arc;
 }
예제 #2
0
        // 从三角序列创建矢量图层
        static GeomLayer FromTriangles(IEnumerable <Triangle> triangles, List <GeomPoint> originalPoints)
        {
            // 创建字典用于反查
            var pt_mapper = new Dictionary <Vector2, GeomPoint>();

            foreach (GeomPoint tmp in originalPoints)
            {
                pt_mapper[tmp] = tmp;
            }

            // 构造矢量图层
            GeomLayer result = new GeomLayer(GeomType.Polygon);
            var       g_points = new Dictionary <Vector2, GeomPoint>();
            var       g_arcs = new Dictionary <Edge, GeomArc>();
            int       point_cnt = 0, arc_cnt = 0, poly_cnt = 0;

            foreach (Triangle tri in triangles)
            {
                // 按需创建点
                foreach (Vector2 tmp in tri.Points())
                {
                    if (!g_points.ContainsKey(tmp))
                    {
                        var new_point = pt_mapper[tmp].Copy(); // 反查原始数据
                        new_point.id  = ++point_cnt;
                        g_points[tmp] = new_point;
                    }
                }

                // 去重获取三边
                var arcs = new List <GeomArc>();
                foreach (var tmp in tri.Edges())
                {
                    GeomArc cur_arc;
                    if (g_arcs.ContainsKey(tmp))
                    {
                        cur_arc = g_arcs[tmp];
                    }
                    else
                    {
                        cur_arc     = new GeomArc(new GeomPoint[] { g_points[tmp.Item1], g_points[tmp.Item2] }, ++arc_cnt);
                        g_arcs[tmp] = g_arcs[tmp.Reverse()] = cur_arc;
                    }
                    arcs.Add(cur_arc);
                }

                // 创建三角形
                GeomPoly tri_poly = new GeomPoly(arcs, ++poly_cnt);
                result.polygons.Add(tri_poly);
            }

            // 加入点集、边集
            result.points.AddRange(g_points.Values);
            result.arcs.AddRange(g_arcs.Values);

            return(result);
        }
예제 #3
0
        // 2.1 从指定弧段与端点开始搜索相连多边形
        static void PolyTopoGroup(GeomPoint pt, GeomArc arc)
        {
            inners = new HashSet <GeomPoly>();
            stack  = new LinkedList <Tuple <GeomPoint, GeomArc> >();
            stack.AddFirst(new Tuple <GeomPoint, GeomArc>(pt, arc));

            while (stack.Count > 0)
            {
                var data = stack.First;
                stack.RemoveFirst();
                PolyTopoUnit(data.Value);
            }

            if (inners.Count == 0)
            {
                return;
            }

            // 获取并删除外包多边形(面积最大)
            GeomPoly outer = null;

            if (inners.Count > 1)
            {
                outer = null;
                foreach (var poly in inners)
                {
                    if (outer == null || outer.OuterArea < poly.OuterArea)
                    {
                        outer = poly;
                    }
                }
                inners.Remove(outer);
            }
            else
            {
                outer = inners.First();
            }

            // 加入待处理孔洞列表
            holesGroup.Add(new Tuple <GeomPoly, HashSet <GeomPoly> >(outer, inners));

            cPoly.AddRange(inners);
        }
예제 #4
0
        // 2.1.1 搜索相连多边形:单元操作,返回当前搜索
        static void PolyTopoUnit(Tuple <GeomPoint, GeomArc> data)
        {
            if (arcUsed.Contains(data))
            {
                return;
            }
            var res = new List <Tuple <GeomPoint, GeomArc> >();

            // 搜索直到首尾相接
            while (true)
            {
                // 加入当前弧段
                res.Add(data);
                arcUsed.Add(data);
                // 获取下一弧段
                GeomPoint prevPt  = data.Item1;
                GeomArc   prevArc = data.Item2;
                GeomPoint nextPt  = prevArc.First;
                if (nextPt == prevPt)
                {
                    nextPt = prevArc.Last;
                }
                GeomArc nextArc = vertNext[nextPt][data.Item2];
                data = new Tuple <GeomPoint, GeomArc>(nextPt, prevArc); // 同弧段不同顶点
                if (!arcUsed.Contains(data))
                {
                    stack.AddFirst(data);
                }
                data = new Tuple <GeomPoint, GeomArc>(nextPt, nextArc);
                // 首尾相接时跳出
                if (data.Equals(res[0]))
                {
                    break;
                }
            }

            // 创造多边形
            var newPoly = new GeomPoly(from pair in res select pair.Item2);

            inners.Add(newPoly);
        }