private static bool RecordEars(EarPolygon poly) { LinkedListNode <EarPoint> active = poly.Get(); int NumPoints = poly.NumPoints() - 2; while (poly.NumPoints() >= 3) { int num = poly.NumPoints(); int idx = active.Value.mIndex; do { if (IsConvex(active, poly)) { if (IsEar(active, poly)) { break; } } active = poly.Next(active); } while (idx != active.Value.mIndex); poly.AddResult(poly.Previous(active).Value[0], poly.Previous(active).Value[1], active.Value[0], active.Value[1], poly.Next(active).Value[0], poly.Next(active).Value[1]); active = poly.Next(active); poly.Remove(poly.Previous(active)); continue; } return(true); }
private static List <Vector4> MergePolygon(EarPolygon poly) { List <Vector4> connects = new List <Vector4>(); if (poly.NumChildren() > 0) { List <EarPolygon> children = poly.GetChildren(); List <KeyValuePair <int, float> > order = ChildOrder(children); KeyValuePair <LinkedListNode <EarPoint>, LinkedListNode <EarPoint> > connection; LinkedListNode <EarPoint> temp; for (int i = 0; i < order.Count; i++) { connection = GetSplit(poly, children[order[i].Key], order[i].Value); connects.Add(new Vector4(connection.Key.Value[0], connection.Key.Value[1], connection.Value.Value[0], connection.Value.Value[1])); LinkedListNode <EarPoint> newP = poly.InsertPoint(connection.Key.Value[0], connection.Key.Value[1], connection.Value); temp = connection.Key; do { temp = children[order[i].Key].Next(temp); newP = poly.InsertPoint(temp.Value[0], temp.Value[1], newP); } while (temp.Value != connection.Key.Value); newP = poly.InsertPoint(connection.Value.Value[0], connection.Value.Value[1], newP); } } return(connects); }
private static bool IsInSegment(LinkedListNode <EarPoint> ele, EarPolygon poly) { LinkedListNode <EarPoint> a = poly.Previous(ele); LinkedListNode <EarPoint> b = ele; LinkedListNode <EarPoint> c = poly.Next(ele); return(GeoSegmentUtils.IsPointInSegment2(a.Value.mPoint, c.Value.mPoint, ref b.Value.mPoint)); }
private static bool IsConvex(LinkedListNode <EarPoint> ele, EarPolygon poly) { LinkedListNode <EarPoint> a = poly.Previous(ele); LinkedListNode <EarPoint> b = ele; LinkedListNode <EarPoint> c = poly.Next(ele); return(GeoPolygonUtils.IsConvex(a.Value.mPoint, b.Value.mPoint, c.Value.mPoint)); }
private float mArea; // 带符号 public EarPolygon() { mChildren = new List <EarPolygon>(); mResults = new List <List <Vector2> >(); mHead = new LinkedList <EarPoint>(); mParent = null; mNumberOfPoints = 0; }
public static List <List <Vector2> > Waypoint(EarPolygon poly, out List <List <Vector2> > lines) // 简单多边形 点组 { List <Vector2> vert = new List <Vector2>(); List <List <int> > convexes = ConvexPolygonDecompose.Decompose(poly, ref vert); List <List <Vector2> > convexBorder; lines = Calculate(vert, convexes, out convexBorder); return(convexBorder); }
public EarPolygon(EarPolygon parent) { mChildren = new List <EarPolygon>(); mResults = new List <List <Vector2> >(); mHead = new LinkedList <EarPoint>(); mParent = parent; parent.AddChild(this); mNumberOfPoints = 0; }
public static List <List <int> > Decompose(EarPolygon poly, ref List <Vector2> vert) { EarClipping.Clip(poly); List <Vector2> triangles = new List <Vector2>(); GeoUtils.FlatList(poly.mResults, ref triangles); List <int> indices = new List <int>(); GeoUtils.MeshVertexPrimitiveType(triangles, ref vert, ref indices); return(HMDecompose(vert, indices)); }
private static bool RecordEars(EarPolygon poly) { LinkedListNode <EarPoint> active = poly.Get(); int NumPoints = poly.NumPoints() - 2; while (poly.NumPoints() >= 3) { int num = poly.NumPoints(); int idx = active.Value.mIndex; //do //{ // if (IsConvex(active, poly)) // { // if (IsEar(active, poly)) // { // break; // } // } // active = poly.Next(active); //} while (idx != active.Value.mIndex); List <LinkedListNode <EarPoint> > candidate = new List <LinkedListNode <EarPoint> >(); do { if (IsConvex(active, poly)) { if (IsEar(active, poly)) { candidate.Add(active); } } active = poly.Next(active); } while (idx != active.Value.mIndex); List <KeyValuePair <int, float> > temp = new List <KeyValuePair <int, float> >(); for (int i = 0; i < candidate.Count; ++i) { LinkedListNode <EarPoint> ear = candidate[i]; float angle = AngleWithUp(ear, poly); temp.Add(new KeyValuePair <int, float>(i, angle)); } temp.Sort((x, y) => { return(-x.Value.CompareTo(y.Value)); }); active = candidate[temp[0].Key]; temp.Clear(); candidate.Clear(); poly.AddResult(poly.Previous(active).Value.mPoint, active.Value.mPoint, poly.Next(active).Value.mPoint); poly.AddResult(poly.Previous(active).Value.mVertex, active.Value.mVertex, poly.Next(active).Value.mVertex); active = poly.Next(active); poly.Remove(poly.Previous(active)); continue; } return(true); }
private static List <LinkedListNode <EarPoint> > OrderPoints(EarPolygon poly, LinkedListNode <EarPoint> point) { LinkedListNode <EarPoint> head = poly.Get(); List <LinkedListNode <EarPoint> > pointContainer = new List <LinkedListNode <EarPoint> >(); LinkedListNode <EarPoint> activePoint = point; while (head != null) { pointContainer.Add(head); head = head.Next; } pointContainer.Sort(new EarNodeValueCompare(activePoint)); return(pointContainer); }
private static bool IsEar(LinkedListNode <EarPoint> ele, EarPolygon poly) { LinkedListNode <EarPoint> checkerN1 = poly.Next(ele); LinkedListNode <EarPoint> checker = poly.Next(checkerN1); while (checker.Value.mIndex != poly.Previous(ele).Value.mIndex) { if (InTriangle(checker.Value, ele.Value, poly.Next(ele).Value, poly.Previous(ele).Value)) { return(false); } checker = poly.Next(checker); } return(true); }
private static float AngleWithUp(LinkedListNode <EarPoint> ele, EarPolygon poly) { LinkedListNode <EarPoint> a = poly.Previous(ele); LinkedListNode <EarPoint> b = ele; LinkedListNode <EarPoint> c = poly.Next(ele); Vector3 ab = a.Value.mVertex - b.Value.mVertex; Vector3 cb = c.Value.mVertex - b.Value.mVertex; float angle = Vector3.Angle(ab, cb); if (angle > 90) { angle = 180 - angle; } return(angle); }
private static void OrientatePolygon(EarPolygon poly) { poly.CalculateArea(); if (!poly.IsCCW()) { poly.Reverse(-1); } for (int i = 0; i < poly.NumChildren(); i++) { poly[i].CalculateArea(); if (poly[i].IsCCW()) { poly[i].Reverse(-1); } } }
private static List <LinkedListNode <EarPoint> > OrderPoints(EarPolygon poly, LinkedListNode <EarPoint> point) { LinkedListNode <EarPoint> head = poly.Get(); List <LinkedListNode <EarPoint> > pointContainer = new List <LinkedListNode <EarPoint> >(); activePoint = point; while (head != null) { pointContainer.Add(head); head = head.Next; } pointContainer.Sort((i, j) => { Vector2 t1 = i.Value.mPoint - activePoint.Value.mPoint; Vector2 t2 = j.Value.mPoint - activePoint.Value.mPoint; return(t1.sqrMagnitude.CompareTo(t2.sqrMagnitude)); }); return(pointContainer); }
/// <summary> /// 简单多边形或者三角面点数组 /// </summary> /// <param name="tries"></param> /// <param name="isPolygon">是否为简单多边形</param> /// <param name="vert"></param> /// <returns></returns> public static List <List <int> > Decompose(List <Vector2> tries, bool isPolygon, ref List <Vector2> vert) { if (isPolygon) { EarPolygon poly = new EarPolygon(); foreach (Vector2 v in tries) { poly.AddPoint(v.x, v.y); } EarClipping.Clip(poly); List <Vector2> triangles = new List <Vector2>(); GeoUtils.FlatList(poly.mResults, ref triangles); List <int> indices = new List <int>(); GeoUtils.MeshVertexPrimitiveType(triangles, ref vert, ref indices); return(HMDecompose(vert, indices)); } else { List <int> indices = new List <int>(); GeoUtils.MeshVertexPrimitiveType(tries, ref vert, ref indices); return(HMDecompose(vert, indices)); } }
public static List <Vector4> Merge(EarPolygon poly) { OrientatePolygon(poly); return(MergePolygon(poly)); }
private static LinkedListNode <EarPoint> GetClosest(List <LinkedListNode <EarPoint> > pointsOrdered, int index, EarPolygon poly, LinkedListNode <EarPoint> innerPoint, EarPolygon polychild) { LinkedListNode <EarPoint> a = innerPoint; LinkedListNode <EarPoint> b = pointsOrdered[index]; LinkedListNode <EarPoint> c = poly.Get(); bool intersection = false; do { intersection = DoIntersect(a.Value, b.Value, c.Value, poly.Next(c).Value); c = c.Next; } while ((!intersection) && (c != null)); if (!intersection) { c = a; do { intersection = DoIntersect(a.Value, b.Value, c.Value, polychild.Next(c).Value); c = polychild.Next(c); } while ((!intersection) && (c.Value != a.Value)); if (!intersection) { return(b); } } return(GetClosest(pointsOrdered, index + 1, poly, innerPoint, polychild)); }
private static KeyValuePair <LinkedListNode <EarPoint>, LinkedListNode <EarPoint> > GetSplit(EarPolygon outer, EarPolygon inner, float smallestX) { LinkedListNode <EarPoint> smallest = inner.Get(); do { if (smallest.Value[0] == smallestX) { break; } smallest = smallest.Next; } while (smallest != null); LinkedListNode <EarPoint> closest = GetClosest(OrderPoints(outer, smallest), 0, outer, smallest, inner); KeyValuePair <LinkedListNode <EarPoint>, LinkedListNode <EarPoint> > split = new KeyValuePair <LinkedListNode <EarPoint>, LinkedListNode <EarPoint> >(smallest, closest); return(split); }
public static void Clip(EarPolygon poly) { Merge(poly); RecordEars(poly); }
public void AddChild(EarPolygon child) { mChildren.Add(child); }