public static Vertex Create(Vertex v1, Vertex v2, double alpha) { var v = v2.ToPoint() - v1.ToPoint(); v = v / v.Length * alpha; var p = v1.ToPoint() + v; var vertex = new Vertex() { X = p.X, Y = p.Y, IsIntersect = true,Alpha = alpha}; return vertex; }
public static bool Intersects(Vertex p1, Vertex p2, Vertex q1, Vertex q2, ref double alphaP, ref double alphaQ) { double wecP1 = (p1.X - q1.X) * (q2.Y - q1.Y) - (p1.Y - q1.Y) * (q2.X - q1.X); double wecP2 = (p2.X - q1.X) * (q2.Y - q1.Y) - (p2.Y - q1.Y) * (q2.X - q1.X); if (wecP1 * wecP2 <= 0) { double wecQ1 = (q1.X - p1.X) * (p2.Y - p1.Y) - (q1.Y - p1.Y) * (p2.X - p1.X); double wecQ2 = (q2.X - p1.X) * (p2.Y - p1.Y) - (q2.Y - p1.Y) * (p2.X - p1.X); if (wecQ1 * wecQ2 <= 0) { alphaP = wecP1 / (wecP1 - wecP2); alphaQ = wecQ1 / (wecQ1 - wecQ2); return true; } } return false; }
//public static void public static List<List<Vertex>> Clip(Vertex subject, Vertex clip, ClipType clipType) { bool isIntersect = false; //phase 1 for (var si = subject; si != null; si = si.Next == subject ? null : si.Next) { if (si.IsIntersect) continue; for (var cj = clip; cj != null; cj = cj.Next == clip ? null : cj.Next) { if (cj.IsIntersect) continue; var cross = Segment.Intersect (si.ToPoint(), si.NonIntersectionNext.ToPoint(), cj.ToPoint(), cj.NonIntersectionNext.ToPoint()); if (cross.HasValue) { double a = cross.Value.DistanceBetween (si.ToPoint ()) / si.ToPoint ().DistanceBetween (si.NonIntersectionNext.ToPoint ()); double b = cross.Value.DistanceBetween (cj.ToPoint ()) / cj.ToPoint ().DistanceBetween (cj.NonIntersectionNext.ToPoint ()); Vertex i1 = new Vertex () { X = cross.Value.X, Y = cross.Value.Y, IsIntersect = true, Alpha = a, }; Vertex i2 = new Vertex () { X = cross.Value.X, Y = cross.Value.Y, IsIntersect = true, Alpha = b, }; i1.Neibour = i2; i2.Neibour = i1; i1.InsertTo (si, si.NonIntersectionNext); i2.InsertTo (cj, cj.NonIntersectionNext); isIntersect = true; } } } if(!isIntersect) { List<List<Vertex>> result = new List<List<Vertex>>(); if (subject.Contains(clip)) { result.Add(clip.ToVertexList()); } else if (clip.Contains(subject)) { result.Add(subject.ToVertexList()); } return result; } //phase 2 bool status = clip.Contains(subject); if (clipType == ClipType.Union || clipType == ClipType.Difference) status = !status; for (var si = subject; si != null; si = si.Next == subject ? null : si.Next) { if (si.IsIntersect) { si.IsExit = status; status = !status; } } status = subject.Contains(clip); if (clipType == ClipType.Union) status = !status; for (var cj = clip; cj != null; cj = cj.Next == clip ? null : cj.Next) { if (cj.IsIntersect) { cj.IsExit = status; status = !status; } } //phase 3 Vertex current; List<List<Vertex>> polygonList = new List<List<Vertex>>(); for (var si = subject; si != null; si = si.Next == subject ? null : si.Next) { if (si.IsIntersect && !si.IsVisit) { current = si; var polygon = new List<Vertex>(); polygonList.Add(polygon); polygon.Add(current); do { current.IsVisit = true; if (current.IsExit) { do { current = current.Previous; if(current.Neibour!= polygon[0]) polygon.Add(current); current.IsVisit = true; } while (!current.IsIntersect); } else { do { current = current.Next; if(current.Neibour != polygon[0]) polygon.Add(current); current.IsVisit = true; } while (!current.IsIntersect); } current = current.Neibour; } while (!current.IsVisit); } } return polygonList; }
public static List<List<Vertex>> Union(Vertex subject, Vertex clip) { return Clip(subject, clip, ClipType.Union); }
public static List<List<Vertex>> Split(Vertex subject,Vertex polyline) { return null; }
public static List<List<Vertex>> Intersect(Vertex subject,Vertex clip) { return Clip(subject, clip, ClipType.Inersection); }
public static List<List<Vertex>> Diff(Vertex subject, Vertex clip) { return Clip(subject, clip, ClipType.Difference); }
public bool Contains(Vertex point) { int windNumber = 0; Vertex si = this; do { if (si.Y <= point.Y) { if (si.Next.Y > point.Y) { if (Triangle.GetSignedArea(si.ToPoint(), si.Next.ToPoint(), point.ToPoint()) > 0) windNumber++; } } else { if (si.Next.Y <= point.Y) if (Triangle.GetSignedArea(si.ToPoint(), si.Next.ToPoint(), point.ToPoint()) < 0) windNumber--; } si = si.Next; } while (si != this); return (windNumber & 1) != 0; }
public void InsertTo(Vertex start,Vertex end) { Vertex prev, next = start; while (next != end && next.Alpha < Alpha) next = next.Next; prev = next.Previous; Next = next; Previous = prev; prev.Next = this; next.Previous = this; }