/// <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); }
/// <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); }); } }
/// <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); }
/// <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); } }
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); }); } }
/// <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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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); }
/// <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); }
/// <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); } } }
/// <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); } } }
/// <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); }
/// <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); }
/// <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); } } } }
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; } }