public bool IsConvex() { Vector2[] pts = GetPoints(); for (int i = 0; i < pts.Length; i++) { int prevInd = i; int thisInd = (i + 1) % pts.Length; int nextInd = (i + 2) % pts.Length; float ccwAngle = HelperFunctions.AngleBetween(pts[nextInd] - pts[thisInd], pts[prevInd] - pts[thisInd]); if (ccwAngle > Mathf.PI + 0.05f)//small tolerance to avoid issues with edges that are subdivided { return(false); } } return(true); }
public void AddConnection(LinkedGraphEdge connection) { int insertIndex = 0; LinkedGraphVertex otherVert = connection.GetOppositeVertex(this); float newAngle = HelperFunctions.AngleBetween(otherVert.pt - pt, Vector2.right) % (Mathf.PI * 2); for (int i = 0; i < connections.Count; i++) { LinkedGraphVertex thisOppositeVert = connections[i].GetOppositeVertex(this); float existingAngle = HelperFunctions.AngleBetween(thisOppositeVert.pt - pt, Vector2.right) % (Mathf.PI * 2); if (newAngle < existingAngle) { insertIndex++; } else { break; } } connections.Insert(insertIndex, connection); }
public Vector2[] GetSimplifiedPoints(float simplificationAngle) { List <Vector2> pts = new List <Vector2>(GetPoints()); int i = 0; while (i < pts.Count) { int prevInd = i; int thisInd = (i + 1) % pts.Count; int nextInd = (i + 2) % pts.Count; float ccwAngle = HelperFunctions.AngleBetween(pts[nextInd] - pts[thisInd], pts[prevInd] - pts[thisInd]); if (Mathf.Abs(ccwAngle - Mathf.PI) < simplificationAngle) { i = 0; pts.RemoveAt(thisInd); } else { i++; } } return(pts.ToArray()); }
public List <EdgeType> GetLocalLoop(EdgeType startingEdge, bool ccw) { List <EdgeType> foundEdges = new List <EdgeType>(); foundEdges.Add(startingEdge); LinkedGraphVertex firstVertex = startingEdge.a; LinkedGraphVertex lastVertex = startingEdge.b; bool foundLoop = false; int edgesSeen = 0; while (!foundLoop) { EdgeLoopEdge lastEdge = foundEdges[foundEdges.Count - 1]; Vector2 lastEdgeDirection = lastEdge.GetOppositeVertex(lastVertex).pt - lastVertex.pt; float minAngle = float.MaxValue; EdgeType minAngleEdge = null; if (lastVertex.NumConnections() <= 1) { Debug.LogWarning("Reached end of loop while collecting loop."); return(null); } foreach (LinkedGraphEdge connection in lastVertex.GetConnections()) { if (connection == lastEdge) { continue;//ignore the connection if it is this instance. } //all connections must share lastVertex with lastEdge Vector2 thisEdgeDirection = connection.GetOppositeVertex(lastVertex).pt - lastVertex.pt; float angle = HelperFunctions.AngleBetween(thisEdgeDirection, lastEdgeDirection); if (!ccw) { //we want to invert the smallest angle when its cw since angleBetween gets the ccw angle angle = Mathf.PI * 2 - angle; } if (angle < minAngle) { if (connection is EdgeType) { minAngle = angle; minAngleEdge = (EdgeType)connection; } else { Debug.LogWarning("Could not isolate loop because connected edges were not EdgeLoopEdges"); } } edgesSeen++; if (edgesSeen > MAXLOOPSIZE) { Debug.LogWarning("Couldn't close loop. Failing"); DebugLines debug = GameObject.FindObjectOfType <DebugLines>(); foreach (EdgeType edge in foundEdges) { debug.AddEdge(edge, Color.red); } return(null); } } foundEdges.Add(minAngleEdge); lastVertex = minAngleEdge.GetOppositeVertex(lastVertex); if (lastVertex == firstVertex) { foundLoop = true; } } //maintain the loops go ccw paradigm if (!ccw) { foundEdges.Reverse(); } return(foundEdges); }