/// <summary> /// Not used, and not tested. /// Filters out colinear vertices. Which is a useful step in mesh simplification. /// The other steps aren't implemented yet. Mesh simplification would be neat, /// but the rendering performance gain in most situations would be tiny. /// </summary> static IEnumerable <Vertex> RemoveColinearVertices(IEnumerable <Vertex> originalVertices) { List <Vertex> cache = originalVertices.ToList(); if (cache.Count == 0) { yield break; } // to save headaches about removal during enumeration, build a set of vertices to remove HashSet <Vertex> verticesToRemove = new HashSet <Vertex>(); foreach (Vertex start in cache) { if (verticesToRemove.Contains(start)) { continue; } // build collection of unique directions from other vertices to start, // while building it also find any colinear vertices we can remove HashSet <DirectionToVertex> directionsFromStart = new HashSet <DirectionToVertex>(); foreach (Vertex a in cache) { if (verticesToRemove.Contains(a)) { continue; } if (a.Equals(start)) { continue; } DirectionToVertex startToA = new DirectionToVertex(start, a); bool shouldAddDirection = true; foreach (var startToB in directionsFromStart.Where(direction => direction.RoughlyEqualDirection(startToA))) { // the following vertices are colinear: start, A, startToB.target, // because direction to start is (roughly) the same for A and startToB.target, we know // the middle of the 3 cannot be start. The middle is whichever of A and B is closest to start. if (startToA.distancetoTarget <= startToB.distancetoTarget) { // A is the middle vertex verticesToRemove.Add(a); // no need to add this direction to the collection, as other colinears will be // detected thanks to the startToB direction which detected this one shouldAddDirection = false; // no need to check any other parallel directions // wouldn't expect there to be other parallels anyway (might want to check that!) break; } else { // B is the middle vertex verticesToRemove.Add(startToB.target); // remove record of B's direction, replacing it with A's direction directionsFromStart.Remove(startToB); shouldAddDirection = true; } } if (shouldAddDirection) { directionsFromStart.Add(startToA); } } } foreach (Vertex item in cache) { if (!verticesToRemove.Contains(item)) { yield return(item); } } }
public bool RoughlyEqualDirection(DirectionToVertex other, float fuzziness = 0.001f) { return(VectorRoughlyEqual(this.direction, other.direction, fuzziness)); }