Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="allLines">         //allLines是连续的线</param>
        public List <List <Line3D> > FindAllFloorOutLines(List <Line3D> allLines)
        {
            //  List<Line3D> resultDecomposedLinesTT = DecomposeLines(allLines);

            List <Line3D> resultDecomposedLines = new List <Line3D>();

            DecomposeCurves(allLines, resultDecomposedLines);


            //查找外框线
            List <Line3D> sortOutLines = GraphicAlgorithm.ClosedLookup(allLines, true, false).FirstOrDefault();

            List <Line3D> decomposedOutlines = new List <Line3D>();

            foreach (var line in resultDecomposedLines)
            {
                if (IsLineContained(line, sortOutLines))
                {
                    decomposedOutlines.Add(line);
                }
            }

            decomposedOutlines = decomposedOutlines.SortLinesByCounterClockwise(Vector3D.BasisZ);


            List <List <Line3D> > curveArrarys = new List <List <Line3D> >();
            List <Line3D>         usedLines    = new List <Line3D>();

            FindLineArrarys(resultDecomposedLines, decomposedOutlines, usedLines, curveArrarys);

            return(curveArrarys);
        }
Пример #2
0
        /// <summary>
        /// 合并可以合并的线段
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MergeTestBtn_Click(object sender, RoutedEventArgs e)
        {
            List <Geometry2D> gss   = this.drawingKernel.GeometryShapes;
            List <Line2D>     lines = new List <Line2D>();

            foreach (var g in gss)
            {
                if (g is DrawingKernel.Geometries.Primitives.LineGeometry)
                {
                    DrawingKernel.Geometries.Primitives.LineGeometry line = g as DrawingKernel.Geometries.Primitives.LineGeometry;
                    lines.Add(Line2D.Create(line.Start, line.End));
                }
                if (g.GeometryId == "tp")
                {
                    this.drawingKernel.RemoveGeometryShape(g);
                }
            }

            List <Line2D> mergeLines = GraphicAlgorithm.Merge(lines);

            if (mergeLines != null)
            {
                mergeLines.ForEach(x =>
                {
                    DrawingKernel.Geometries.Primitives.LineGeometry lg = new DrawingKernel.Geometries.Primitives.LineGeometry(x.Start, x.End);
                    lg.PenColor   = KernelProperty.GetRandomColor();
                    lg.GeometryId = "tp";
                    this.drawingKernel.AddShape(lg);
                });
            }
        }
Пример #3
0
        /// <summary>
        /// 用于创建当前的数据线段
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public static List <LineModel> Create(List <Line2D> lines)
        {
            //打断所有的线段
            List <Line2D> decomposeLines = lines.Decompose();

            //查找最外边缘
            List <Line2D> outerLines = GraphicAlgorithm.FindClosedLines(decomposeLines, true, false);

            if (outerLines == null)
            {
                throw new Exception("当前没有一个封闭区域");
            }
            for (int i = 0; i < outerLines.Count; i++)
            {
                Line2D line = decomposeLines.Find(x => x.IsAlmostEqualTo(outerLines[i]));
                decomposeLines.Remove(line);
            }
            //查找内墙
            List <Line2D> innerLines = new List <Line2D>(decomposeLines);

            //数据模型
            List <LineModel> lineModels = new List <LineModel>();

            //组建数据源
            outerLines.ForEach(x => {
                lineModels.Add(new LineModel(x, 1, LineType.outer));
            });

            //内装线添加
            innerLines.ForEach(x => {
                lineModels.Add(new LineModel(x, 2, LineType.inner));
            });

            return(lineModels);
        }
Пример #4
0
        /// <summary>
        /// 图形的内缩小
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ElasticityTestBtn_Click(object sender, RoutedEventArgs e)
        {
            List <Geometry2D> gss   = this.drawingKernel.GeometryShapes;
            List <Line2D>     lines = new List <Line2D>();

            foreach (var g in gss)
            {
                if (g is DrawingKernel.Geometries.Primitives.LineGeometry)
                {
                    DrawingKernel.Geometries.Primitives.LineGeometry line = g as DrawingKernel.Geometries.Primitives.LineGeometry;
                    lines.Add(Line2D.Create(line.Start, line.End));
                }
                if (g.GeometryId == "tp")
                {
                    this.drawingKernel.RemoveGeometryShape(g);
                }
            }
            //查找封闭区域
            List <List <Line2D> > nn = GraphicAlgorithm.ClosedLookup(lines, true, true);

            if (nn != null && nn.Count > 0)
            {
                List <Line2D> nt = nn[0];

                List <Line2D> wtn = GraphicAlgorithm.Elastic(nt, -20);

                PolygonGeometry pg = new PolygonGeometry();
                wtn.ForEach(y => { pg.PPoints.Add(y.Start); });
                pg.FillColor  = KernelProperty.GetRandomColor();
                pg.GeometryId = "tp";
                this.drawingKernel.AddShape(pg);
            }
        }
Пример #5
0
        private void ClosetTestBtn2_Click(object sender, RoutedEventArgs e)
        {
            //封闭区域测试
            List <Geometry2D> gss = this.drawingKernel.GeometryShapes;

            List <Line2D> lines = new List <Line2D>();

            //转换图形
            foreach (var g in gss)
            {
                if (g is DrawingKernel.Geometries.Primitives.LineGeometry)
                {
                    DrawingKernel.Geometries.Primitives.LineGeometry line = g as DrawingKernel.Geometries.Primitives.LineGeometry;
                    lines.Add(Line2D.Create(line.Start, line.End));
                }
                if (g.GeometryId == "tp")
                {
                    this.drawingKernel.RemoveGeometryShape(g);
                }
            }
            //查找封闭区域
            List <List <Line2D> > nn = GraphicAlgorithm.ClosedLookup(lines, false, true);

            if (nn != null)
            {
                nn.ForEach(x =>
                {
                    PolygonGeometry pg = new PolygonGeometry();
                    x.ForEach(y => { pg.PPoints.Add(y.Start); });
                    pg.FillColor  = KernelProperty.GetRandomColor();
                    pg.GeometryId = "tp";
                    this.drawingKernel.AddShape(pg);
                });
            }
        }
Пример #6
0
        /// <summary>
        /// 一个多边形和另外一个多边形之间的关系
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PolygonInsideTestBtn_Click(object sender, RoutedEventArgs e)
        {
            List <Geometry2D>     gss   = this.drawingKernel.GeometryShapes;
            List <List <Line2D> > lines = new List <List <Line2D> >();

            foreach (var g in gss)
            {
                if (g is PolygonGeometry)
                {
                    List <Line2D>   nlines = new List <Line2D>();
                    PolygonGeometry poly   = g as DrawingKernel.Geometries.Primitives.PolygonGeometry;
                    g.FillColor = Colors.Azure;
                    g.Opacity   = 0.3;
                    poly.Update();
                    nlines.AddRange(poly.Lines);
                    lines.Add(nlines);
                }
                if (g.GeometryId == "tp")
                {
                    this.drawingKernel.RemoveGeometryShape(g);
                }
            }

            //计算多边形和多边形之间的关系
            if (lines.Count == 2)
            {
                List <List <Line2D> > ins = new List <List <Line2D> >();
                var result = GraphicAlgorithm.PolygonInsideOfRegion(lines[0], lines[1], ins);

                if (result == 1)
                {
                    ins.ForEach(x => {
                        PolygonGeometry pg = new PolygonGeometry();
                        x.ForEach(y => { pg.PPoints.Add(y.Start); });
                        pg.FillColor  = Colors.Green;
                        pg.GeometryId = "tp";
                        this.drawingKernel.AddShape(pg);
                    });
                }
                else if (result == 0)
                {
                    ins.ForEach(x => {
                        PolygonGeometry pg = new PolygonGeometry();
                        x.ForEach(y => { pg.PPoints.Add(y.Start); });
                        pg.FillColor  = Colors.Red;
                        pg.GeometryId = "tp";
                        this.drawingKernel.AddShape(pg);
                    });
                }
                else
                {
                    MessageBox.Show("相离");
                }
            }
            else
            {
                MessageBox.Show("不表现多个多边形的情况");
            }
        }
        /// <summary>
        /// 获取无法形成封闭区域的线
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public List <Line2D> WeedLess(List <Line2D> ilines)
        {
            var           lines = GraphicAlgorithm.Decompose(ilines);
            List <Line2D> mweed = new List <Line2D>(lines);
            //去掉了无端点线段
            List <Line2D> weeds    = this.Weed(mweed);
            var           weedLess = lines.FindAll(x => !weeds.Contains <Line2D>(x, new Line2DEqualityComparer()));

            return(weedLess);
        }
Пример #8
0
        /// <summary>
        /// 图形的扩张与收缩,存在BUG,需要再处理
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public List <Line3D> Elastic(List <Line3D> lines, double range, List <Line3D> neverOffset)
        {
            List <Line3D> NLList = new List <Line3D>();
            //获取当前线段的顺时针排序
            List <Line3D> sortLines = GraphicAlgorithm.Sort(lines);

            //获取当前连续的顶点
            List <Vector3D> PList = new List <Vector3D>();

            //当前直线的方向
            List <Vector3D> DList = new List <Vector3D>();

            //记录所有的点
            sortLines.ForEach(x => {
                PList.Add(x.Start);
                DList.Add(x.Direction);
            });

            //所有点的列表
            List <Vector3D> NPList = new List <Vector3D>();

            int startIndex, endindex;

            //获取所有的点
            for (int i = 0; i < DList.Count; i++)
            {
                startIndex = i == 0 ? DList.Count - 1 : i - 1;
                endindex   = i;
                //两个线之间的夹角
                double sina = DList[startIndex].Cross(DList[endindex]).Modulus();

                //由于偏移出是平行四边形,则要移动的长度为
                var moveLen = -range / sina;

                //移动的方向为
                var movedir = DList[endindex] - DList[startIndex];

                Vector3D np = DList[i] + movedir * moveLen;
                //添加新点
                NPList.Add(np);
            }

            ///形成新的线
            for (int i = 0; i < NPList.Count; i++)
            {
                var index = i == (DList.Count - 1) ? 0 : i + 1;
                NLList.Add(Line3D.Create(NPList[i], NPList[index]));
            }

            return(NLList);
        }
Пример #9
0
        /// <summary>
        /// 查找最大和最小封闭区域
        /// </summary>
        /// <param name="searchLines"></param>
        /// <param name="isLargeRegion"></param>
        /// <param name="isDecompose"></param>
        /// <returns></returns>
        public List <List <Line2D> > Lookup(List <Line2D> searchLines, bool isLargeRegion, bool isDecompose = false)
        {
            //最少有三条线,不然无法组成封闭区域
            if (searchLines.Count < 3)
            {
                return(null);
            }
            List <List <Line2D> > closets = new List <List <Line2D> >();

            //需要处理的所有线
            List <Line2D> readyLines = new List <Line2D>(searchLines);

            //对线进行打断
            if (isDecompose)
            {
                readyLines = GraphicAlgorithm.Decompose(readyLines);
            }

            //剔除有一个点没有连接点的点
            readyLines = GraphicAlgorithm.Weed(readyLines);
            //去除相同的元素
            readyLines = readyLines.Distinct(new Line2DEqualityComparer()).ToList();

            if (readyLines == null || readyLines.Count == 0)
            {
                return(null);
            }
            List <Line2D> Large = null;

            //查找最大的多边形
            FindMaxOne(readyLines, ref Large);

            if (isLargeRegion)
            {
                if (Large != null)
                {
                    closets.Add(Large);
                }
                return(closets);
            }
            else
            {
                if (Large != null)
                {
                    FindMins(readyLines, Large, closets);
                }

                return(closets);
            }
        }
        private void GetBlockAfterMerge(List <Line2D> orderAddedLines, List <Rectangle2D> minimumRectangles, List <Line2D> leftLines)
        {
            List <Line2D> remainLines = new List <Line2D>();

            Merge(orderAddedLines, minimumRectangles, leftLines);
            remainLines.AddRange(leftLines);
            GraphicAlgorithm.MergeLine(leftLines);
            GraphicAlgorithm.OrderLinesByLength(leftLines);
            if (remainLines.Count != leftLines.Count)
            {
                orderAddedLines = new List <Line2D>(leftLines);
                GetBlockAfterMerge(orderAddedLines, minimumRectangles, leftLines);
            }
        }
        private List <Line3D> GetCutRegion(List <List <Line3D> > cellList, List <Line3D> openningOutLines)
        {
            List <Line3D> resultLines = new List <Line3D>();

            foreach (List <Line3D> lines in cellList)
            {
                Vector3D centriod = GetCentriod(lines);
                int      a        = GraphicAlgorithm.InsideOfRegion(centriod, openningOutLines);
                if (a == 1)
                {
                    resultLines = lines;
                    break;
                }
            }
            return(resultLines);
        }
Пример #12
0
        /// <summary>
        /// 合并相关墙体
        /// </summary>
        /// <param name="spatialWalls"></param>
        private List <LineModel> MergeSpatialLines(List <LineModel> spatialLines, List <LineModel> separateInterior, out List <Line2D> boundary)
        {
            List <LineModel> interiorLines = new List <LineModel>();

            List <Line2D> Line3ds = new List <Line2D>();

            foreach (LineModel v in spatialLines)
            {
                //获取当前所有的线段
                Line3ds.Add(v.Line);
            }
            //排除不需要合并的点
            List <Vector2D> withoutpoint = new List <Vector2D>();

            separateInterior.ForEach(x =>
            {
                withoutpoint.Add(x.Line.Start);
                withoutpoint.Add(x.Line.End);
            });
            //合并所有的线段
            List <Line2D> mergeLines = GraphicAlgorithm.MergeLinesWithoutpoints(Line3ds, withoutpoint);

            boundary = mergeLines;

            //循环所有的合并后的线段
            for (int i = 0; i < mergeLines.Count; i++)
            {
                //键值信息
                List <LineModel> kvps = new List <LineModel>();

                foreach (LineModel v in spatialLines)
                {
                    if (v.Line.IsPartOf(mergeLines[i]))
                    {
                        kvps.Add(v);
                    }
                }
                kvps.ForEach(x => { spatialLines.Remove(x); });

                List <LineModel> mergeW = this.CreateMergeInteriorLine(kvps, mergeLines[i]);
                interiorLines.AddRange(mergeW);
            }


            return(interiorLines);
        }
        private Rectangle2D Rebuild(List <Rectangle2D> targets)
        {
            Rectangle2D   rec1     = targets[0];
            Rectangle2D   rec2     = targets[1];
            List <Line2D> recEdges = new List <Line2D> {
                rec1.Bottom, rec1.Top, rec1.Left, rec1.Right, rec2.Bottom, rec2.Top, rec2.Left, rec2.Right
            };
            List <Line2D>      leftLines   = new List <Line2D>();
            List <Rectangle2D> newRec      = new List <Rectangle2D>(targets);
            List <Line2D>      sortedLines = new List <Line2D>(recEdges);

            foreach (var edge in recEdges)
            {
                if (IsRectangleEdge(edge, rec1) && IsRectangleEdge(edge, rec2))
                {
                    sortedLines.Remove(edge);
                }
            }
            GraphicAlgorithm.MergeLine(sortedLines);
            GraphicAlgorithm.HuntCurveByStartPoint(sortedLines, sortedLines.First().Start, leftLines);
            return(new Rectangle2D(leftLines));
        }
Пример #14
0
        /// <summary>
        /// 进行矩形划分出任意多个矩形元素
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public List <List <Line2D> > Division(List <Line2D> lines)
        {
            if (lines != null && lines.Count > 4)
            {
                //首先要把所有的线打断
                List <Line2D> decomposesLines = GraphicAlgorithm.Decompose(lines);
                //查找最大的封闭区域,且不需要打断
                List <List <Line2D> > large = GraphicAlgorithm.ClosedLookup(decomposesLines, true, false);

                if (large != null && large.Count > 0)
                {
                    //获取所有外部的线段
                    List <Line2D> outerSide = large.FirstOrDefault();

                    //获取所有无端点的线段
                    List <Line2D> weeds = GraphicAlgorithm.WeedLess(decomposesLines);

                    //获取内部线段,要去掉
                    //List<Line2D> innerSide = GraphicAlgorithm.RejectLines(decomposesLines,);
                }
            }
            return(null);
        }
        /// <summary>
        /// 剔除端点无效的点
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public List <Line2D> Weed(List <Line2D> ilines)
        {
            var lines = GraphicAlgorithm.Decompose(ilines);

            if (lines != null)
            {
                List <Line2D> rets = new List <Line2D>();
                for (int i = 0; i < lines.Count; i++)
                {
                    var start = lines[i].Start;
                    var end   = lines[i].End;

                    var one = lines.FindAll(x => x.Start.IsAlmostEqualTo(start) || x.End.IsAlmostEqualTo(start));
                    var two = lines.FindAll(x => x.Start.IsAlmostEqualTo(end) || x.End.IsAlmostEqualTo(end));

                    if (one.Count == 1 || two.Count == 1)
                    {
                        //添加一个需要移除的图形元素
                        rets.Add(lines[i]);
                    }
                }

                if (rets.Count > 0)
                {
                    rets.ForEach(x =>
                    {
                        lines.Remove(x);
                    });

                    Weed(lines);
                }

                return(lines);
            }
            return(null);
        }
        /// <summary>
        /// 获取重合区域的图形
        /// </summary>
        /// <param name="clines"></param>
        /// <param name="outLines"></param>
        /// <returns></returns>
        private List <List <Line2D> > GetSuperposition(List <Line2D> clines, List <Line2D> outLines)
        {
            List <Line2D> mgslines = new List <Line2D>(clines);

            mgslines.AddRange(outLines);
            //查找到所有最小的封闭区域
            var closelines = GraphicAlgorithm.ClosedLookup(mgslines, false, true);

            List <List <Line2D> > closeIntersets = new List <List <Line2D> >();

            //只要指定区域的一个点,不在任何一个给定的图形内部,则剔除
            closelines.ForEach(x => {
                List <List <Line2D> > nlines = null;
                int r1 = Check(x, clines, out nlines);
                int r2 = Check(x, outLines, out nlines);

                if (r1 == 1 && r2 == 1)
                {
                    closeIntersets.Add(x);
                }
            });

            return(closeIntersets);
        }
Пример #17
0
        /// <summary>
        /// 按照指定的高度和宽度,对规则矩形进行划分,当前算法,运行的前提条件是,传入的图形是矩形元素
        /// </summary>
        /// <param name="square"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public List <List <Line2D> > Partition(List <Line2D> square, double width, double height, Vector2D offset)
        {
            //根据板子宽度和高度,重新定义偏移量
            var loffset = this.LayoutOffset(width, height, offset);
            //获取要划分的矩形裕兴
            List <Line2D> lines = new List <Line2D>(square);

            //获取当前的划分多边形
            List <List <Line2D> > result = new List <List <Line2D> >();

            //获取图形中的最小点
            List <Vector2D> vst = new List <Vector2D>();

            square.ForEach(x =>
            {
                vst.Add(x.Start);
                vst.Add(x.End);
            });

            //排除相同点
            vst = vst.Distinct(new Vector2DEqualityComparer()).ToList();

            //查找最小角点
            var origin = vst.OrderBy(a =>
            {
                return(Math.Round(a.X, 7));
            }).ThenBy(b =>
            {
                return(Math.Round(b.Y, 7));
            }).FirstOrDefault();
            ////查找最小角点
            //var origin = vst.OrderBy(a => a.X).ThenBy(c => c.Y).FirstOrDefault();
            //逆时针排序,排列出
            List <Line2D> sequeeLines = GraphicAlgorithm.Sort(lines, origin, 1);

            //获取当前矩形的实际宽度和高度
            double sw = sequeeLines[0].Length + loffset.X;
            double sh = sequeeLines[1].Length + loffset.Y;

            //代表需要水平偏移的个数
            var lnx = Math.Ceiling(sw / width);
            //代表垂直偏移的个数
            var lny = Math.Ceiling(sh / height);

            for (int i = 0; i < lnx; i++)
            {
                for (int j = 0; j < lny; j++)
                {
                    Vector2D startPoint = null;
                    if (loffset != null)
                    {
                        startPoint = origin - loffset;
                    }
                    //代表顶点的偏移
                    Vector2D v1 = startPoint.Offset(width * i * sequeeLines[0].Direction).Offset(height * j * sequeeLines[1].Direction);

                    //最右边的顶点偏移
                    Vector2D v2 = startPoint.Offset(width * (i + 1) * sequeeLines[0].Direction).Offset(height * j * sequeeLines[1].Direction);

                    //偏移Y方向的区域,假如超过边界,则取边界值
                    Vector2D v4 = startPoint.Offset(width * i * sequeeLines[0].Direction).Offset(height * (j + 1) * sequeeLines[1].Direction);

                    if (v1.X < origin.X)
                    {
                        v1.X = origin.X;
                    }
                    if (v1.Y < origin.Y)
                    {
                        v1.Y = origin.Y;
                    }
                    //假如超出边界,则取边界值
                    if (v2.X > (origin.X + sequeeLines[0].Length))
                    {
                        v2 = Vector2D.Create(origin.X + sequeeLines[0].Length, v2.Y);
                    }

                    if (v2.Y < origin.Y)
                    {
                        v2.Y = origin.Y;
                    }
                    if (v4.Y > (origin.Y + sequeeLines[1].Length))
                    {
                        v4 = Vector2D.Create(v1.X, origin.Y + sequeeLines[1].Length);
                    }

                    if (v4.X < origin.X)
                    {
                        v4.X = origin.X;
                    }
                    if (v4.Y < origin.Y)
                    {
                        v4.Y = origin.Y;
                    }
                    //计算对角点
                    Vector2D v3 = Vector2D.Create(v2.X, v4.Y);


                    //获取划分的小多边形
                    List <Line2D> line2ds = new List <Line2D>()
                    {
                        Line2D.Create(v1, v2),
                        Line2D.Create(v2, v3),
                        Line2D.Create(v3, v4),
                        Line2D.Create(v4, v1)
                    };
                    result.Add(line2ds);
                }
            }
            return(result);
        }
Пример #18
0
        /// <summary>
        /// 查找最小区域
        /// </summary>
        /// <param name="interiorWalls"></param>
        /// <param name="separateInterior"></param>
        /// <param name="spatials"></param>
        /// <param name="sortOutLines"></param>
        private void FindSpatialFromLinesModel(List <LineModel> interiorLines, List <LineModel> separateLines, List <SpatialModel> spatialModels, List <LineModel> outModels)
        {
            //查找一个任意起点
            Line2D startLine = null;

            //从外边缘线开发查找
            if (outModels.Count > 0)
            {
                startLine = outModels[0].Line;
            }

            //查找内装墙体
            if (startLine == null)
            {
                if (tick >= interiorLines.Count)
                {
                    return;
                }
                startLine = interiorLines.OrderByDescending(x => x.UseAge).ElementAtOrDefault(tick).Line;
                tick++;
            }


            //需要处理的墙体
            List <Line2D> remainingLines = new List <Line2D>();

            //记录需要查找的线
            interiorLines.ForEach(x =>
            {
                remainingLines.Add(x.Line);
            });



            //查找和这个墙相关的封闭区域
            List <LineModel> spatialLines = new List <LineModel>();


            List <Line2D> Lines = null;

            try
            {
                //查找最小封闭区域
                Lines = GraphicAlgorithm.FindClosedLines(remainingLines, false, false, startLine);
            }
            catch (Exception ex)
            {
                string message = ex.Message;
            }

            //假如出现查找不到的情况,会继续查找
            if (Lines == null)
            {
                if (remainingLines.Count > 0)
                {
                    FindSpatialFromLinesModel(interiorLines, separateLines, spatialModels, outModels);
                }
            }
            else
            {
                tick = 0;
                //假如出现了一条线还当前多边形内部,则说明当前多边形不合法,需要重新查询
                bool reSearch = false;
                //循环所有线段
                foreach (Line2D x in remainingLines)
                {
                    //假如成立
                    if (x.IsInRegion(Lines))
                    {
                        //说明内部有线,则需要重新查找
                        reSearch = true;
                        break;
                    }
                }

                if (reSearch)
                {
                    FindSpatialFromLinesModel(interiorLines, separateLines, spatialModels, outModels);

                    return;
                }

                //需要移除的线
                List <LineModel> removeInteriorLines = new List <LineModel>();

                //查找所有细分的墙体
                foreach (Line2D line in Lines)
                {
                    LineModel iw = interiorLines.Find(x => x.Line.IsAlmostEqualTo(line));
                    if (iw != null)
                    {
                        iw.UseAge -= 1;

                        spatialLines.Add(iw);

                        if (iw.UseAge == 0)
                        {
                            removeInteriorLines.Add(iw);
                        }
                    }
                }


                //移除已经使用完成的墙体
                removeInteriorLines.ForEach(x => {
                    if (x.LineType == LineType.outer)
                    {
                        outModels.Remove(outModels.Find(u => u.Line.IsAlmostEqualTo(x.Line)));
                    }
                    interiorLines.Remove(x);
                });


                List <Line2D> boundary = null;

                //合并相关的内墙线
                List <LineModel> mergeInteriorLines = this.MergeSpatialLines(spatialLines, separateLines, out boundary);


                //声明封闭区域
                SpatialModel spatial = new SpatialModel();

                //合并完成后,查找轮廓线
                if (boundary.Count != Lines.Count)
                {
                    Lines = GraphicAlgorithm.FindClosedLines(boundary, false, false, startLine);
                }

                List <Line2D> mergeLines = GraphicAlgorithm.MergeLines(new List <Line2D>(Lines));


                spatial.LineModels = mergeInteriorLines;

                //当前底部的区域信息

                //添加一个封闭区域
                spatialModels.Add(spatial);


                if (interiorLines.Count > 0)
                {
                    FindSpatialFromLinesModel(interiorLines, separateLines, spatialModels, outModels);
                }
            }
        }
Пример #19
0
        /// <summary>
        /// 线和多边形的关系
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PInsideTestBtn_Click(object sender, RoutedEventArgs e)
        {
            List <Geometry2D> gss   = this.drawingKernel.GeometryShapes;
            List <Line2D>     lines = new List <Line2D>();

            List <Line2D> vts = new List <Line2D>();

            foreach (var g in gss)
            {
                if (g is PolygonGeometry)
                {
                    PolygonGeometry poly = g as DrawingKernel.Geometries.Primitives.PolygonGeometry;
                    g.FillColor = Colors.Azure;
                    g.Opacity   = 0.3;
                    poly.Update();
                    lines.AddRange(poly.Lines);
                }
                if (g is DrawingKernel.Geometries.Primitives.LineGeometry)
                {
                    DrawingKernel.Geometries.Primitives.LineGeometry l = g as DrawingKernel.Geometries.Primitives.LineGeometry;
                    vts.Add(Line2D.Create(l.Start, l.End));
                }
                if (g.GeometryId == "tp")
                {
                    this.drawingKernel.RemoveGeometryShape(g);
                }
            }

            if (vts != null)
            {
                for (int i = 0; i < vts.Count; i++)
                {
                    var rs = GraphicAlgorithm.LineInsideOfRegion(vts[i], lines, null);
                    if (rs == 1)
                    {
                        DrawingKernel.Geometries.Primitives.LineGeometry lg = new DrawingKernel.Geometries.Primitives.LineGeometry();
                        lg.Start      = vts[i].Start;
                        lg.End        = vts[i].End;
                        lg.PenColor   = Colors.Blue;
                        lg.GeometryId = "tp";
                        this.drawingKernel.AddShape(lg);
                    }
                    else if (rs == 0)
                    {
                        DrawingKernel.Geometries.Primitives.LineGeometry lg = new DrawingKernel.Geometries.Primitives.LineGeometry();
                        lg.PenColor   = Colors.Red;
                        lg.Start      = vts[i].Start;
                        lg.End        = vts[i].End;
                        lg.GeometryId = "tp";
                        this.drawingKernel.AddShape(lg);
                    }
                    else
                    {
                        DrawingKernel.Geometries.Primitives.LineGeometry lg = new DrawingKernel.Geometries.Primitives.LineGeometry();
                        lg.PenColor   = Colors.Black;
                        lg.Start      = vts[i].Start;
                        lg.End        = vts[i].End;
                        lg.GeometryId = "tp";
                        this.drawingKernel.AddShape(lg);
                    }
                }
            }
        }
        /// <summary>
        /// 检测当前多边形和另外一个多边形的关系,
        /// 0图形相交
        /// 1 表示包容,返回较小的多边形区域,为共有区域
        /// -1 表示相离
        /// </summary>
        /// <param name="clines">需要检测的多边形</param>
        /// <param name="outLines">目标多边形</param>
        /// <param name="innerLines">相交的区域</param>
        /// <returns></returns>
        public int Check(List <Line2D> clines, List <Line2D> outLines, out List <List <Line2D> > innerLines)
        {
            int ins = 0, ous = 0, gon = 0;

            //相交的区域
            innerLines = new List <List <Line2D> >();

            //循环当前所有的线段
            for (int i = 0; i < clines.Count; i++)
            {
                //当前线段是否在指定多边形内部
                var result = GraphicAlgorithm.LineInsideOfRegion(clines[i], outLines, null);

                //假如是内部,则内部数量+1
                if (result == 1)
                {
                    ins++;
                }
                //假如在外部,则外部数量+1
                else if (result == -1)
                {
                    ous++;
                }
                else if (result == 2)
                {
                    gon++;
                }
                //否则有相交区域,则不记录
                else
                {
                    break;
                }
            }
            //都在内部,说明当前图形被包含在指定图形内部
            if ((ins + gon) == clines.Count)
            {
                innerLines.Add(clines);
                return(1);
            }

            //全部在外部,有两种情况,一种是两个图形分离,一种是当前图形包含了指定图形
            else if ((ous + gon) == clines.Count)
            {
                //开始检测两个之间的关系,找到目标图形的一个线,判断在当前图形的关系
                var r = GraphicAlgorithm.LineInsideOfRegion(outLines[0], clines, null);
                //说明当前outLines就是在clines的内部
                if (r == 1)
                {
                    innerLines.Add(outLines);
                    return(1);
                }
                //两个图形属于相离的状态
                else
                {
                    innerLines = null;
                    return(-1);
                }
            }
            //计算没有记录
            else
            {
                //没有找到一个相交的线,说明两个图形相连
                if (ins + ous + gon == clines.Count)
                {
                    innerLines = null;
                    return(-1);
                }
                //说明图形确实相交,需要获取相交区域
                else
                {
                    innerLines = GetSuperposition(clines, outLines);
                    return(0);
                }
            }
        }
Пример #21
0
        /// <summary>
        /// 对指定的进行每个线段进行缩放,并且指定缩放的长度,传入的线,不能共线或者重叠,否则会出现错误
        /// </summary>
        /// <param name="nlist"></param>
        /// <returns></returns>
        public List <Line2D> Elastic2(List <Tuple <Line2D, Double> > nlist)
        {
            List <Line2D> lines = new List <Line2D>();

            //不处理变形的情况
            foreach (var tp in nlist)
            {
                if (tp.Item1.Length < tp.Item2)
                {
                    return(null);
                }
                else
                {
                    lines.Add(tp.Item1);
                }
            }

            //获取当前线段的顺时针排序
            List <Line2D> sortLines = GraphicAlgorithm.Sort(lines, null, 1);

            List <Line2D> moveLines = new List <Line2D>();

            ///开始线段偏移
            for (int i = 0; i < sortLines.Count; i++)
            {
                var v1      = Vector3D.Create(sortLines[i].Start.X, sortLines[i].Start.Y, 0);
                var v2      = Vector3D.Create(sortLines[i].End.X, sortLines[i].End.Y, 0);
                var l1      = Line3D.Create(v1, v2);
                var moveDir = l1.Direction.Cross(Vector3D.BasisZ);
                var tp      = nlist.Find(x => x.Item1.IsAlmostEqualTo(sortLines[i]));
                var nl      = l1.Offset(tp.Item2, -moveDir);
                moveLines.Add(TransformUtil.Projection(nl));
            }
            List <Vector2D> NPList = new List <Vector2D>();

            //开始循环所有的线段
            for (int i = 0; i < moveLines.Count; i++)
            {
                Vector2D v = null;
                if (i == 0)
                {
                    v = moveLines[0].IntersectStraightLine(moveLines[moveLines.Count - 1]);
                }
                else
                {
                    v = moveLines[i].IntersectStraightLine(moveLines[i - 1]);
                }

                if (v == null)
                {
                    return(null);
                }
                else
                {
                    NPList.Add(v);
                }
            }

            List <Line2D> nliset = new List <Line2D>();

            //生成新的多边形
            for (int i = 0; i < NPList.Count; i++)
            {
                if (i == 0)
                {
                    nliset.Add(Line2D.Create(NPList[NPList.Count - 1], NPList[i]));
                }
                else
                {
                    nliset.Add(Line2D.Create(NPList[i - 1], NPList[i]));
                }
            }

            return(nliset);
        }
Пример #22
0
        /// <summary>
        /// 对多边形进行扩张和缩放,range为负数为内缩小,为正数为外扩
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public List <Line2D> Elastic(List <Line2D> lines, double range, List <Line2D> neverOffset, bool allowDistortion = false)
        {
            if (range < 0)
            {
                //说明会引起多边形形状的变化
                Line2D line = lines.Find(x => x.Length < Math.Abs(range));

                //说明图形已经边型了,需要变形处理
                if (line != null && allowDistortion)
                {
                    //允许变形的缩放
                    this.ElasticDistortion(lines, range);
                }
            }


            List <Line2D> NLList = new List <Line2D>();
            //首先需要对线段进行一次合并,由于多边形可能存在共线的情况,那么偏移会出问题
            var mergelines = GraphicAlgorithm.Merge(lines);
            //获取当前线段的顺时针排序
            List <Line2D> sortLines = GraphicAlgorithm.Sort(mergelines, null, 1);

            //获取当前连续的顶点
            List <Vector2D> PList = new List <Vector2D>();

            //当前直线的方向
            List <Vector2D> DList = new List <Vector2D>();

            //记录所有的点
            sortLines.ForEach(x => {
                PList.Add(x.Start);
                DList.Add(x.Direction);
            });

            //所有点的列表
            List <Vector2D> NPList = new List <Vector2D>();

            int startIndex, endindex;

            //获取所有的点
            for (int i = 0; i < DList.Count; i++)
            {
                startIndex = i == 0 ? DList.Count - 1 : i - 1;
                endindex   = i;
                //两个线之间的夹角
                double sina = DList[startIndex].Cross(DList[endindex]);
                //用于判断当前是阴阳角
                var Corndir = 0;

                if (sina > 0)
                {
                    Corndir = 1;
                }
                else
                {
                    Corndir = -1;
                }
                //由于偏移出是平行四边形,则要移动的长度为
                var moveLen = -range / sina;

                Vector2D movedir = null;
                if (neverOffset != null)
                {
                    var nf = neverOffset.FindAll(x => x.Start.IsAlmostEqualTo(PList[i]) || x.End.IsAlmostEqualTo(PList[i]));

                    if (nf != null && nf.Count == 1)
                    {
                        if (nf[0].Direction.IsAlmostEqualTo(DList[startIndex]) || nf[0].Direction.IsAlmostEqualTo(-DList[startIndex]))
                        {
                            movedir = DList[startIndex];
                            Vector2D npt = PList[i] + movedir * range * Corndir;
                            NPList.Add(npt);
                        }
                        else
                        {
                            movedir = -DList[endindex];
                            Vector2D npt = PList[i] + movedir * range * Corndir;
                            NPList.Add(npt);
                        }

                        continue;
                    }
                    if (nf != null && nf.Count == 2)
                    {
                        NPList.Add(PList[i]);
                        continue;
                    }
                }
                //移动的方向为
                movedir = DList[endindex] - DList[startIndex];
                Vector2D np = PList[i] + movedir * moveLen;
                //添加新点
                NPList.Add(np);
            }

            ///形成新的线
            for (int i = 0; i < NPList.Count; i++)
            {
                var index = i == (NPList.Count - 1) ? 0 : i + 1;
                NLList.Add(Line2D.Create(NPList[i], NPList[index]));
            }

            return(NLList);
        }
Пример #23
0
        /// <summary>
        /// 检测一个点是否在一个多边形内部
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void InsideTestBtn_Click(object sender, RoutedEventArgs e)
        {
            List <Geometry2D> gss   = this.drawingKernel.GeometryShapes;
            List <Line2D>     lines = new List <Line2D>();

            List <Vector2D> vts = new List <Vector2D>();

            foreach (var g in gss)
            {
                if (g is PolygonGeometry)
                {
                    PolygonGeometry poly = g as DrawingKernel.Geometries.Primitives.PolygonGeometry;
                    g.FillColor = Colors.Azure;
                    g.Opacity   = 0.3;
                    poly.Update();
                    lines.AddRange(poly.Lines);
                }
                if (g is DrawingKernel.Geometries.Primitives.LineGeometry)
                {
                    DrawingKernel.Geometries.Primitives.LineGeometry l = g as DrawingKernel.Geometries.Primitives.LineGeometry;
                    vts.Add(l.Start);
                    vts.Add(l.End);
                }
                if (g.GeometryId == "tp")
                {
                    this.drawingKernel.RemoveGeometryShape(g);
                }
            }

            if (vts != null)
            {
                int resultP = 0;
                for (int i = 0; i < vts.Count; i++)
                {
                    resultP = GraphicAlgorithm.InsideOfRegion(vts[i], lines);
                    if (resultP == 0)
                    {
                        CircleGeometry c = new DrawingKernel.Geometries.Primitives.CircleGeometry();
                        c.FillColor  = Colors.Red;
                        c.Start      = vts[i];
                        c.End        = Vector2D.Create(vts[i].X + 5, vts[i].Y);
                        c.GeometryId = "tp";
                        this.drawingKernel.AddShape(c);
                    }
                    else if (resultP == 1)
                    {
                        CircleGeometry c = new DrawingKernel.Geometries.Primitives.CircleGeometry();
                        c.FillColor  = Colors.Green;
                        c.Start      = vts[i];
                        c.End        = Vector2D.Create(vts[i].X + 5, vts[i].Y);
                        c.GeometryId = "tp";
                        this.drawingKernel.AddShape(c);
                    }
                    else
                    {
                        CircleGeometry c = new DrawingKernel.Geometries.Primitives.CircleGeometry();
                        c.FillColor  = Colors.Yellow;
                        c.Start      = vts[i];
                        c.End        = Vector2D.Create(vts[i].X + 5, vts[i].Y);
                        c.GeometryId = "tp";
                        this.drawingKernel.AddShape(c);
                    }
                }
            }
        }
Пример #24
0
        private void FindLineArrarys(List <Line3D> resultDecomposedLines, List <Line3D> sortOutLines, List <Line3D> usedLines, List <List <Line3D> > curveArrarys)
        {
            //首先要剔除那些线的两端和其他线不是相连的线段

            //查找一个任意起点
            Line3D startLine = null;

            if (sortOutLines.Count > 0)
            {
                startLine = sortOutLines[0];
            }

            //需要移除的墙体
            List <Line3D> remainingLines = new List <Line3D>();

            remainingLines.AddRange(resultDecomposedLines);



            //查找最小封闭区域
            List <Line3D> Lines = GraphicAlgorithm.FindClosedLines(resultDecomposedLines, false, false, startLine);

            curveArrarys.Add(Lines);

            foreach (var line in Lines)
            {
                //包含在外框线中
                bool isContained = IsLineContained(line, sortOutLines);
                //包含在内框线中,并且已经被使用过
                bool isUsed = IsLineContained(line, usedLines);

                if (isContained || isUsed)
                {
                    Line3D targetLine = FindtargetLine(line, remainingLines);
                    if (targetLine != null)
                    {
                        remainingLines.Remove(targetLine);
                    }
                }
                else
                {
                    usedLines.Add(line);
                }

                #region MyRegion
                //if (isContained)
                //{
                //    Line3D targetLine = FindtargetLine(line, remainingLines);
                //    if (targetLine != null)
                //        remainingLines.Remove(targetLine);
                //}
                ////添加到使用的线中
                //else
                //{

                //    if (isUsed)
                //    {
                //        Line3D targetLine = FindtargetLine(line, remainingLines);
                //        if (targetLine != null)
                //            remainingLines.Remove(targetLine);
                //    }
                //}
                #endregion
            }

            if (remainingLines.Count > 0)
            {
                FindLineArrarys(remainingLines, sortOutLines, usedLines, curveArrarys);
            }
            else
            {
                return;
            }
        }