private static Tuple<CrossInOut, int, bool> CutByLineVerticalForCrossDi(VertexBase v1, VertexBase v2, List<VertexBase> list, bool withIdx, int line2Idx = 0) { bool hasIntersection = false; bool smallToBig = true; var crossXsmaller = new List<IntersWithIndex>(); var crossXbigger = new List<IntersWithIndex>(); var minY = v1.Y; var maxY = v2.Y; if (v1.Y > v2.Y) { minY = v2.Y; maxY = v1.Y; smallToBig = false; } var x = v1.X; for (var toCutLineStart = 0; toCutLineStart < list.Count; toCutLineStart++) { var c1 = list[toCutLineStart % list.Count]; var c2 = list[(toCutLineStart + 1) % list.Count]; // 重合 if (c1.X == c2.X && c1.X == x) continue; //不相交 if (c1.X > x && c2.X > x) continue; if (c1.X < x && c2.X < x) continue; var y = LineCrossV(x, c1, c2); if (!hasIntersection) if ((y > minY && y < maxY) || (c2.X == x && y == v2.Y) || (y == minY && c1.X != x && c2.X != x) || (y == maxY && c1.X != x && c2.X != x) ) hasIntersection = true; var inters = new IntersWithIndex(x, y, toCutLineStart); if (smallToBig) { if (y < minY) crossXsmaller.Add(inters); if ((y > minY && y < maxY) || (y == minY && c2.X == x) || (y == minY && c1.X != x && c2.X != x) || (y == maxY && c2.X == x) || (y == maxY && c1.X != x && c2.X != x) || (y > maxY) ) crossXbigger.Add(inters); } else { if (y > maxY) crossXsmaller.Add(inters); if ((y > minY && y < maxY) || (y == maxY && c2.X == x) || (y == maxY && c1.X != x && c2.X != x) || (y == minY && c2.X == x) || (y == minY && c1.X != x && c2.X != x) || (y < minY) ) crossXbigger.Add(inters); } } if (!hasIntersection) return Tuple.Create(CrossInOut.In, 0, false); if (smallToBig) crossXbigger.Sort((p1, p2) => p1.X.CompareTo(p2.X)); else crossXbigger.Sort((p1, p2) => -(p1.X.CompareTo(p2.X))); var count = crossXbigger.Count; CrossInOut crossRet; int cuttedLineIdx; if (withIdx)//切割多边形的一条边去切实体多边形的一条边 { int countSkip = 0; for (; ; countSkip++) { if (crossXbigger[countSkip].Idx == line2Idx)//line2Idx确定了实体多边形的这条边 break; } count += countSkip; crossRet = count % 2 == 0 ? CrossInOut.In : CrossInOut.Out; cuttedLineIdx = crossXbigger[countSkip].Idx; } else//实体多边形的一条边去切切割多边形 { crossRet = count % 2 == 0 ? CrossInOut.In : CrossInOut.Out; cuttedLineIdx = crossXbigger[0].Idx; } return Tuple.Create(crossRet, cuttedLineIdx, true); }
private static Tuple <CrossInOut, int, bool> CutByLineVerticalForCrossDi(VertexBase v1, VertexBase v2, List <VertexBase> list, bool withIdx, int line2Idx = 0) { bool hasIntersection = false; bool smallToBig = true; var crossXsmaller = new List <IntersWithIndex>(); var crossXbigger = new List <IntersWithIndex>(); var minY = v1.Y; var maxY = v2.Y; if (v1.Y > v2.Y) { minY = v2.Y; maxY = v1.Y; smallToBig = false; } var x = v1.X; for (var toCutLineStart = 0; toCutLineStart < list.Count; toCutLineStart++) { var c1 = list[toCutLineStart % list.Count]; var c2 = list[(toCutLineStart + 1) % list.Count]; // 重合 if (c1.X == c2.X && c1.X == x) { continue; } //不相交 if (c1.X > x && c2.X > x) { continue; } if (c1.X < x && c2.X < x) { continue; } var y = LineCrossV(x, c1, c2); if (!hasIntersection) { if ((y > minY && y < maxY) || (c2.X == x && y == v2.Y) || (y == minY && c1.X != x && c2.X != x) || (y == maxY && c1.X != x && c2.X != x) ) { hasIntersection = true; } } var inters = new IntersWithIndex(x, y, toCutLineStart); if (smallToBig) { if (y < minY) { crossXsmaller.Add(inters); } if ((y > minY && y < maxY) || (y == minY && c2.X == x) || (y == minY && c1.X != x && c2.X != x) || (y == maxY && c2.X == x) || (y == maxY && c1.X != x && c2.X != x) || (y > maxY) ) { crossXbigger.Add(inters); } } else { if (y > maxY) { crossXsmaller.Add(inters); } if ((y > minY && y < maxY) || (y == maxY && c2.X == x) || (y == maxY && c1.X != x && c2.X != x) || (y == minY && c2.X == x) || (y == minY && c1.X != x && c2.X != x) || (y < minY) ) { crossXbigger.Add(inters); } } } if (!hasIntersection) { return(Tuple.Create(CrossInOut.In, 0, false)); } if (smallToBig) { crossXbigger.Sort((p1, p2) => p1.X.CompareTo(p2.X)); } else { crossXbigger.Sort((p1, p2) => - (p1.X.CompareTo(p2.X))); } var count = crossXbigger.Count; CrossInOut crossRet; int cuttedLineIdx; if (withIdx)//切割多边形的一条边去切实体多边形的一条边 { int countSkip = 0; for (; ; countSkip++) { if (crossXbigger[countSkip].Idx == line2Idx)//line2Idx确定了实体多边形的这条边 { break; } } count += countSkip; crossRet = count % 2 == 0 ? CrossInOut.In : CrossInOut.Out; cuttedLineIdx = crossXbigger[countSkip].Idx; } else//实体多边形的一条边去切切割多边形 { crossRet = count % 2 == 0 ? CrossInOut.In : CrossInOut.Out; cuttedLineIdx = crossXbigger[0].Idx; } return(Tuple.Create(crossRet, cuttedLineIdx, true)); }
/// <summary> /// 用于获得交点进出性的切割函数 /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="list"></param> /// <param name="line2Idx"> </param> /// <returns></returns> private static Tuple<CrossInOut, int, bool> CutByLineForCrossDi(VertexBase v1, VertexBase v2, List<VertexBase> list, bool withIdx, int line2Idx = 0) { bool hasIntersection = false; bool smallToBig = true; var crossXsmaller = new List<IntersWithIndex>(); var crossXbigger = new List<IntersWithIndex>(); var slope = (v2.Y - v1.Y) / (v1.X - v2.X); var minX = v1.X; var maxX = v2.X; if (v1.X > v2.X) { minX = v2.X; maxX = v1.X; smallToBig = false; } //错切后的切割多边形 var shearedPolyC = list.Select(r => new Vertex(r.X, r.X * slope + r.Y) { Name = r.Name }).ToList(); //把实体多边形的第一条边(即切线)错切后得到一条水平直线 var y = v1.X * slope + v1.Y; for (var toCutLineStart = 0; toCutLineStart < list.Count; toCutLineStart++) { var c1 = shearedPolyC[toCutLineStart % list.Count];//注意,不要漏了文档中C4->C1这种结尾的线段 var c2 = shearedPolyC[(toCutLineStart + 1) % list.Count]; // 重合 if (c1.Y == c2.Y && c1.Y == y) continue; //不相交 if (c1.Y > y && c2.Y > y) continue; if (c1.Y < y && c2.Y < y) continue; var x = LineCrossH(y, c1, c2); var npy = y - x * slope; if (!hasIntersection) if ((x > minX && x < maxX) || (c2.Y == y && x == v2.X) || (x == minX && c1.Y != y && c2.Y != y) || (x == maxX && c1.Y != y && c2.Y != y) ) hasIntersection = true; var inters = new IntersWithIndex(x, npy, toCutLineStart); if (smallToBig) { if (x < minX) crossXsmaller.Add(inters); if ((x > minX && x < maxX) || (x == minX && c2.Y == y) || (x == minX && c1.Y != y && c2.Y != y) || (x == maxX && c2.Y == y) || (x == maxX && c1.Y != y && c2.Y != y) || (x > maxX) //这个必不可少,不然影响进出性判断 ) crossXbigger.Add(inters); } else { if (x > maxX) crossXsmaller.Add(inters); if ((x > minX && x < maxX) || (x == maxX && c2.Y == y) || (x == maxX && c1.Y != y && c2.Y != y) || (c2.Y == y && x == minX) || (x == minX && c1.Y != y && c2.Y != y) || (x < minX) //这个必不可少,不然影响进出性判断 ) crossXbigger.Add(inters); } } if (!hasIntersection) return Tuple.Create(CrossInOut.In, 0, false); if (smallToBig) crossXbigger.Sort((p1, p2) => p1.X.CompareTo(p2.X)); else crossXbigger.Sort((p1, p2) => -(p1.X.CompareTo(p2.X))); var count = crossXbigger.Count; CrossInOut crossRet; int cuttedLineIdx; if (withIdx)//切割多边形的一条边去切实体多边形的一条边 { int countSkip = 0; for (; ; countSkip++) { if (crossXbigger[countSkip].Idx == line2Idx)//line2Idx确定了实体多边形的这条边 break; } count += countSkip; crossRet = count % 2 == 0 ? CrossInOut.In : CrossInOut.Out; cuttedLineIdx = crossXbigger[countSkip].Idx; } else//实体多边形的一条边去切切割多边形 { crossRet = count % 2 == 0 ? CrossInOut.In : CrossInOut.Out; cuttedLineIdx = crossXbigger[0].Idx; } return Tuple.Create(crossRet, cuttedLineIdx, true); }
/// <summary> /// 用于获得交点进出性的切割函数 /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="list"></param> /// <param name="line2Idx"> </param> /// <returns></returns> private static Tuple <CrossInOut, int, bool> CutByLineForCrossDi(VertexBase v1, VertexBase v2, List <VertexBase> list, bool withIdx, int line2Idx = 0) { bool hasIntersection = false; bool smallToBig = true; var crossXsmaller = new List <IntersWithIndex>(); var crossXbigger = new List <IntersWithIndex>(); var slope = (v2.Y - v1.Y) / (v1.X - v2.X); var minX = v1.X; var maxX = v2.X; if (v1.X > v2.X) { minX = v2.X; maxX = v1.X; smallToBig = false; } //错切后的切割多边形 var shearedPolyC = list.Select(r => new Vertex(r.X, r.X * slope + r.Y) { Name = r.Name }).ToList(); //把实体多边形的第一条边(即切线)错切后得到一条水平直线 var y = v1.X * slope + v1.Y; for (var toCutLineStart = 0; toCutLineStart < list.Count; toCutLineStart++) { var c1 = shearedPolyC[toCutLineStart % list.Count];//注意,不要漏了文档中C4->C1这种结尾的线段 var c2 = shearedPolyC[(toCutLineStart + 1) % list.Count]; // 重合 if (c1.Y == c2.Y && c1.Y == y) { continue; } //不相交 if (c1.Y > y && c2.Y > y) { continue; } if (c1.Y < y && c2.Y < y) { continue; } var x = LineCrossH(y, c1, c2); var npy = y - x * slope; if (!hasIntersection) { if ((x > minX && x < maxX) || (c2.Y == y && x == v2.X) || (x == minX && c1.Y != y && c2.Y != y) || (x == maxX && c1.Y != y && c2.Y != y) ) { hasIntersection = true; } } var inters = new IntersWithIndex(x, npy, toCutLineStart); if (smallToBig) { if (x < minX) { crossXsmaller.Add(inters); } if ((x > minX && x < maxX) || (x == minX && c2.Y == y) || (x == minX && c1.Y != y && c2.Y != y) || (x == maxX && c2.Y == y) || (x == maxX && c1.Y != y && c2.Y != y) || (x > maxX) //这个必不可少,不然影响进出性判断 ) { crossXbigger.Add(inters); } } else { if (x > maxX) { crossXsmaller.Add(inters); } if ((x > minX && x < maxX) || (x == maxX && c2.Y == y) || (x == maxX && c1.Y != y && c2.Y != y) || (c2.Y == y && x == minX) || (x == minX && c1.Y != y && c2.Y != y) || (x < minX) //这个必不可少,不然影响进出性判断 ) { crossXbigger.Add(inters); } } } if (!hasIntersection) { return(Tuple.Create(CrossInOut.In, 0, false)); } if (smallToBig) { crossXbigger.Sort((p1, p2) => p1.X.CompareTo(p2.X)); } else { crossXbigger.Sort((p1, p2) => - (p1.X.CompareTo(p2.X))); } var count = crossXbigger.Count; CrossInOut crossRet; int cuttedLineIdx; if (withIdx)//切割多边形的一条边去切实体多边形的一条边 { int countSkip = 0; for (; ; countSkip++) { if (crossXbigger[countSkip].Idx == line2Idx)//line2Idx确定了实体多边形的这条边 { break; } } count += countSkip; crossRet = count % 2 == 0 ? CrossInOut.In : CrossInOut.Out; cuttedLineIdx = crossXbigger[countSkip].Idx; } else//实体多边形的一条边去切切割多边形 { crossRet = count % 2 == 0 ? CrossInOut.In : CrossInOut.Out; cuttedLineIdx = crossXbigger[0].Idx; } return(Tuple.Create(crossRet, cuttedLineIdx, true)); }