///<summary>Finds the next adjacent edge to [edge], ie the adjacent edge that creates the smallest angle</summary> private static LinedefSide NextEdge(LinedefSide edge, Dictionary <Linedef, int> visited_lines) { // Get relevant vertices Vertex vertex; // Vertex to be tested Vertex vertex_prev; // 'Previous' vertex if (edge.Front) { vertex = edge.Line.End; vertex_prev = edge.Line.Start; } else { vertex = edge.Line.Start; vertex_prev = edge.Line.End; } // Find next connected line with the lowest angle float min_angle = Angle2D.PI2; LinedefSide next = null; foreach (Linedef line in vertex.Linedefs) { // Ignore original line if (line == edge.Line) { continue; } // Ignore if zero-length if (line.Start.Position == line.End.Position) { continue; } // Get next vertex Vertex vertex_next; bool front = true; if (line.Start == vertex) { vertex_next = line.End; } else { vertex_next = line.Start; front = false; } // Ignore already-traversed lines int side = (front ? 1 : 2); if (visited_lines.ContainsKey(line) && (visited_lines[line] & side) == side) { continue; } // Determine angle between lines float angle = Angle2D.GetAngle(new Vector2D(vertex_prev.Position.x, vertex_prev.Position.y), new Vector2D(vertex.Position.x, vertex.Position.y), new Vector2D(vertex_next.Position.x, vertex_next.Position.y)); // Check if minimum angle if (angle < min_angle) { min_angle = angle; if (next == null) { next = new LinedefSide(line, front); } else { next.Line = line; next.Front = front; } } } // Return the next edge found if (next == null) { return(null); } if (!visited_lines.ContainsKey(next.Line)) { visited_lines.Add(next.Line, 0); } visited_lines[next.Line] |= (next.Front ? 1 : 2); return(next); }
/// <summary>Find the closest edge within the current outline (that isn't part of the current outline)</summary> private LinedefSide FindInnerEdge() { //DebugConsole.WriteLine("FindInnerEdge: processing " + vertex_valid.Count + " verts"); // Find rightmost non-discarded vertex vertex_right = null; foreach (Vertex v in vertex_valid) { // Set rightmost if no current rightmost vertex if (vertex_right == null) { vertex_right = v; continue; } // Check if the vertex is rightmost if (v.Position.x > vertex_right.Position.x) { vertex_right = v; } } // If no vertex was found, we're done if (vertex_right == null) { //DebugConsole.WriteLine("FindInnerEdge: no vertex_right"); return(null); } // Go through vertex's connected lines, to find // the line with the smallest angle parallel with // the right side of the bbox Linedef eline = null; float min_angle = float.MaxValue; foreach (Linedef line in vertex_right.Linedefs) { // Ignore if zero-length if (line.Start == line.End) { continue; } // Get opposite vertex Vertex opposite = (line.Start == vertex_right ? line.End : line.Start); // Determine angle float angle = Angle2D.GetAngle(new Vector2D(vertex_right.Position.x + 32, vertex_right.Position.y), new Vector2D(vertex_right.Position.x, vertex_right.Position.y), new Vector2D(opposite.Position.x, opposite.Position.y)); // Check if minimum if (angle < min_angle) { min_angle = angle; eline = line; } } // If no line was found, something is wrong (the vertex may have no attached lines) if (eline == null) { // Discard vertex and try again vertex_valid.Remove(vertex_right); //DebugConsole.WriteLine("vertex_valid: " + vertex_valid.Count + " verts after Remove (in FindInnerEdge)"); return(FindInnerEdge()); } // Determine appropriate side return(new LinedefSide(eline, (vertex_right == eline.Start))); }