public static IPoly RemoveDuplicateVerticies(IPoly poly) { List <Vector3> output = new List <Vector3>(); for (int i = 0; i < poly.Resolution; i++) { if (output.Count == 0) { output.Add(poly.GetPoint(i)); } else { Vector3 point = poly.GetPoint(i); Vector3 last = output[output.Count - 1]; if (!Math3d.Compare(point, last)) { output.Add(point); } } } if (Math3d.Compare(output[0], output[output.Count - 1])) { output.RemoveAt(0); } return(poly.Clone(output.ToArray())); }
/// <summary> /// Create a polygon from a set of edges /// For this algorithm to work as expected, the edges must wrap to form a polygon /// Optimize output will merge consecutive edges with have the same line /// </summary> /// <param name="edges"></param> /// <param name="constructor"></param> /// <param name="optimizeOutput"></param> /// <returns></returns> public static IPoly GetPolygonFromEdges(IEnumerable <IEdge> edges, Func <IEnumerable <IEdge>, IPoly> constructor = null, bool optimizeOutput = true) { if (constructor == null) { constructor = (x) => new EdgePoly(x); } //create a hash set of all edges HashSet <IEdge> hashSet = new HashSet <IEdge>(edges); IEdge current = hashSet.First(); DoubleLinkNode <IEdge> currentNode = new DoubleLinkNode <IEdge>(current); DoubleLinkNode <IEdge> firstNode = currentNode; hashSet.Remove(current); while (hashSet.Count > 0) { //find next node IEdge next = hashSet.FirstOrDefault(x => Math3d.Compare(current.B, x.A)); //error check if (next == null) { return(null); } //remove the node from the hash set hashSet.Remove(next); //create the next link node currentNode.next = new DoubleLinkNode <IEdge>(next); currentNode.next.previous = currentNode; //advance the search space current = next; currentNode = currentNode.next; } //link ends currentNode.next = firstNode; firstNode.previous = currentNode; if (optimizeOutput) { //rotate list to find good canidate for first node for (currentNode = firstNode.next; currentNode != firstNode; currentNode = currentNode.next) { if (!IsParallel(currentNode.previous.value, currentNode.value)) { break; } } firstNode = currentNode; //break link to prevent infinate loops over bad geometry firstNode.previous.next = null; firstNode.previous = null; var last = firstNode; //eliminate extra edges for (var node = firstNode; node != null; node = node.next) { if (node != null) { last = node; } while (node.next != null && IsParallel(node.value, node.next.value)) { node.value = new Edge(node.value.A, node.next.value.B); node.next = node.next.next; } } //relink ends last.next = firstNode; firstNode.previous = last; } //construct output to ngon List <IEdge> outputList = new List <IEdge>(); outputList.Add(firstNode.value); for (var node = firstNode.next; node != firstNode; node = node.next) { outputList.Add(node.value); } return(constructor(outputList)); }