private static List<Intersection> CutByLineVertical(Vertex s1, Vertex s2, LinkedList<VertexBase> linkC) { var crossXs = new List<Intersection>(); var x = s1.X; List<VertexBase> shearedPolyC = linkC.ToList(); var minY = s1.Y > s2.Y ? s2.Y : s1.Y; var maxY = s1.Y > s2.Y ? s1.Y : s2.Y; int i = -1; bool backToHead = false; for (var vertex = linkC.First; //这样回到头部的线也可以正常被切到 vertex != null && ((vertex.Value is Vertex && vertex.Next != null) || ((vertex.Value is Intersection) && ((Intersection)vertex.Value).NextC != null) || (vertex.Value is Vertex && vertex.Next == null && !backToHead) || (vertex.Value is Intersection && ((Intersection)vertex.Value).NextC == null && !backToHead)); vertex = vertex.Next) { i++; var c1 = shearedPolyC[i % shearedPolyC.Count]; var c2 = shearedPolyC[(i + 1)%shearedPolyC.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); var inters = new Intersection(x, y); VertexBase next = null; if ((y > minY && y < maxY) || (c2.X == x && y == minY) || (c2.X == x && y == maxY) || (y == minY && c1.X != x && c2.X != x) || (y == maxY && c1.X != x && c2.X != x)) { inters.Name = "I" + Counter.Default.Val++; if (vertex.Next == null) { backToHead = true; next = linkC.First.Value; } else { next = vertex.Next.Value; } WindowLog.Default.Log("切割C的边{0}{1}得到交点{2}", vertex.Value.Name, next.Name, inters.Name); inters.NextC = next; if (vertex.Value is Vertex) (vertex.Value as Vertex).Next = inters; else if (vertex.Value is Intersection) (vertex.Value as Intersection).NextC = inters; linkC.AddAfter(vertex, inters); vertex = vertex.Next; crossXs.Add(inters); } if (backToHead) break; #region log var cLinkSb = new StringBuilder(); var v = linkC.First.Value; while (v != null) { cLinkSb.Append(v.Name); if (v is Intersection) { var curr = v as Intersection; next = curr.NextC; } else if (v is Vertex) { var curr = v as Vertex; next = curr.Next; } if (next.Equals(linkC.First.Value)) { break; } v = next; cLinkSb.Append("->"); } WindowLog.Default.Log("C链表:" + cLinkSb); #endregion } return crossXs; }
private static List <Intersection> CutByLineVertical(Vertex s1, Vertex s2, LinkedList <VertexBase> linkC) { var crossXs = new List <Intersection>(); var x = s1.X; List <VertexBase> shearedPolyC = linkC.ToList(); var minY = s1.Y > s2.Y ? s2.Y : s1.Y; var maxY = s1.Y > s2.Y ? s1.Y : s2.Y; int i = -1; bool backToHead = false; for (var vertex = linkC.First; //这样回到头部的线也可以正常被切到 vertex != null && ((vertex.Value is Vertex && vertex.Next != null) || ((vertex.Value is Intersection) && ((Intersection)vertex.Value).NextC != null) || (vertex.Value is Vertex && vertex.Next == null && !backToHead) || (vertex.Value is Intersection && ((Intersection)vertex.Value).NextC == null && !backToHead)); vertex = vertex.Next) { i++; var c1 = shearedPolyC[i % shearedPolyC.Count]; var c2 = shearedPolyC[(i + 1) % shearedPolyC.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); var inters = new Intersection(x, y); VertexBase next = null; if ((y > minY && y < maxY) || (c2.X == x && y == minY) || (c2.X == x && y == maxY) || (y == minY && c1.X != x && c2.X != x) || (y == maxY && c1.X != x && c2.X != x)) { inters.Name = "I" + Counter.Default.Val++; if (vertex.Next == null) { backToHead = true; next = linkC.First.Value; } else { next = vertex.Next.Value; } WindowLog.Default.Log("切割C的边{0}{1}得到交点{2}", vertex.Value.Name, next.Name, inters.Name); inters.NextC = next; if (vertex.Value is Vertex) { (vertex.Value as Vertex).Next = inters; } else if (vertex.Value is Intersection) { (vertex.Value as Intersection).NextC = inters; } linkC.AddAfter(vertex, inters); vertex = vertex.Next; crossXs.Add(inters); } if (backToHead) { break; } #region log var cLinkSb = new StringBuilder(); var v = linkC.First.Value; while (v != null) { cLinkSb.Append(v.Name); if (v is Intersection) { var curr = v as Intersection; next = curr.NextC; } else if (v is Vertex) { var curr = v as Vertex; next = curr.Next; } if (next.Equals(linkC.First.Value)) { break; } v = next; cLinkSb.Append("->"); } WindowLog.Default.Log("C链表:" + cLinkSb); #endregion } return(crossXs); }
/// <summary> /// 用实体多边形S的边切割切割多边形C,并插入交点到C中 /// </summary> /// <param name="s1"></param> /// <param name="s2"></param> /// <param name="linkC"></param> /// <returns></returns> private static List<Intersection> CutByLine(Vertex s1, Vertex s2, LinkedList<VertexBase> linkC) { if (s1.X == s2.X) return CutByLineVertical(s1, s2, linkC); var crossXs = new List<Intersection>(); double slope = 0, y = s1.Y; slope = (s2.Y - s1.Y) / (s1.X - s2.X);//s2.Y == s1.Y不单独判断,反正这里可以正常处理s2.Y == s1.Y即slope==0 var shearedPolyC = linkC.Select(r => new Vertex(r.X, r.X * slope + r.Y) as VertexBase).ToList();//为了保存错切计算的坐标 y = s1.X * slope + s1.Y; var minX = s1.X > s2.X ? s2.X : s1.X; var maxX = s1.X > s2.X ? s1.X : s2.X; //LinkedListNode<VertexBase> vertex; int i = -1; var backToHead = false; for (var vertex = linkC.First; //这样回到头部的线也可以正常被切到 vertex != null && ((vertex.Value is Vertex && vertex.Next != null) || ((vertex.Value is Intersection) && ((Intersection)vertex.Value).NextC != null) || (vertex.Value is Vertex && vertex.Next == null && !backToHead) || (vertex.Value is Intersection && ((Intersection)vertex.Value).NextC == null && !backToHead)); vertex = vertex.Next) { ++i; var c1 = shearedPolyC[i % shearedPolyC.Count]; var c2 = shearedPolyC[(i + 1) % shearedPolyC.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; var inters = new Intersection(x, npy); VertexBase next = null; if ((x > minX && x < maxX) || (c2.Y == y && x == s2.X) || (x == minX && c1.Y != y && c2.Y != y) || (x == maxX && c1.Y != y && c2.Y != y)) { inters.Name = "I" + Counter.Default.Val++; if (vertex.Next == null) { backToHead = true; next = linkC.First.Value; } else { next = vertex.Next.Value; } WindowLog.Default.Log("切割C的边{0}{1}得到交点{2}", vertex.Value.Name, next.Name, inters.Name); inters.NextC = next; if (vertex.Value is Vertex) ((Vertex)vertex.Value).Next = inters; else if (vertex.Value is Intersection) ((Intersection)vertex.Value).NextC = inters; linkC.AddAfter(vertex, inters); vertex = vertex.Next; crossXs.Add(inters); } if (backToHead) break; #region log var cLinkSb = new StringBuilder(); var v = linkC.First.Value; while (v != null) { cLinkSb.Append(v.Name); if (v is Intersection) { var curr = v as Intersection; next = curr.NextC; } else if (v is Vertex) { var curr = v as Vertex; next = curr.Next; } if (next.Equals(linkC.First.Value)) { break; } v = next; cLinkSb.Append("->"); } WindowLog.Default.Log("C链表:" + cLinkSb); #endregion } return crossXs; }
/// <summary> /// 用实体多边形S的边切割切割多边形C,并插入交点到C中 /// </summary> /// <param name="s1"></param> /// <param name="s2"></param> /// <param name="linkC"></param> /// <returns></returns> private static List <Intersection> CutByLine(Vertex s1, Vertex s2, LinkedList <VertexBase> linkC) { if (s1.X == s2.X) { return(CutByLineVertical(s1, s2, linkC)); } var crossXs = new List <Intersection>(); double slope = 0, y = s1.Y; slope = (s2.Y - s1.Y) / (s1.X - s2.X); //s2.Y == s1.Y不单独判断,反正这里可以正常处理s2.Y == s1.Y即slope==0 var shearedPolyC = linkC.Select(r => new Vertex(r.X, r.X * slope + r.Y) as VertexBase).ToList(); //为了保存错切计算的坐标 y = s1.X * slope + s1.Y; var minX = s1.X > s2.X ? s2.X : s1.X; var maxX = s1.X > s2.X ? s1.X : s2.X; //LinkedListNode<VertexBase> vertex; int i = -1; var backToHead = false; for (var vertex = linkC.First; //这样回到头部的线也可以正常被切到 vertex != null && ((vertex.Value is Vertex && vertex.Next != null) || ((vertex.Value is Intersection) && ((Intersection)vertex.Value).NextC != null) || (vertex.Value is Vertex && vertex.Next == null && !backToHead) || (vertex.Value is Intersection && ((Intersection)vertex.Value).NextC == null && !backToHead)); vertex = vertex.Next) { ++i; var c1 = shearedPolyC[i % shearedPolyC.Count]; var c2 = shearedPolyC[(i + 1) % shearedPolyC.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; var inters = new Intersection(x, npy); VertexBase next = null; if ((x > minX && x < maxX) || (c2.Y == y && x == s2.X) || (x == minX && c1.Y != y && c2.Y != y) || (x == maxX && c1.Y != y && c2.Y != y)) { inters.Name = "I" + Counter.Default.Val++; if (vertex.Next == null) { backToHead = true; next = linkC.First.Value; } else { next = vertex.Next.Value; } WindowLog.Default.Log("切割C的边{0}{1}得到交点{2}", vertex.Value.Name, next.Name, inters.Name); inters.NextC = next; if (vertex.Value is Vertex) { ((Vertex)vertex.Value).Next = inters; } else if (vertex.Value is Intersection) { ((Intersection)vertex.Value).NextC = inters; } linkC.AddAfter(vertex, inters); vertex = vertex.Next; crossXs.Add(inters); } if (backToHead) { break; } #region log var cLinkSb = new StringBuilder(); var v = linkC.First.Value; while (v != null) { cLinkSb.Append(v.Name); if (v is Intersection) { var curr = v as Intersection; next = curr.NextC; } else if (v is Vertex) { var curr = v as Vertex; next = curr.Next; } if (next.Equals(linkC.First.Value)) { break; } v = next; cLinkSb.Append("->"); } WindowLog.Default.Log("C链表:" + cLinkSb); #endregion } return(crossXs); }