void ConnectEndPoints(List <Node> _nodes, List <Edge> _edges) { // Find endpoints List <Node> endNodes = new List <Node>(); for (int i = 1; i < _nodes.Count; i++) { if (_nodes[i].adjacents.Count == 1) { endNodes.Add(_nodes[i]); } } // Connect endpoints to edges or other nodes for (int i = 0; i < endNodes.Count; i++) { // End node direction Node adjacent = Node.GetNode(_nodes, endNodes[i].adjacents[0]); Vector3 nodeDir = (endNodes[i].Position - adjacent.Position).normalized; //Check if there is any nodes in the rough direction of the end node float roughAngle = 30f; List <Node> nodesInDir = new List <Node>(); for (int j = 0; j < _nodes.Count; j++) { if (_nodes[j] == endNodes[i]) { continue; } Vector3 dirToNode = (_nodes[j].Position - endNodes[i].Position).normalized; if (Vector3.Angle(nodeDir, dirToNode) < roughAngle && Vector3.Angle(nodeDir, dirToNode) > 30f) { nodesInDir.Add(_nodes[j]); } } // The node with which this endpoint is connected to Node connectTo = null; // If there are some nodes in the rough direction, pick the one that is closest if (nodesInDir.Count > 0) { float toClosest = Mathf.Infinity; Node closest = null; for (int j = 0; j < nodesInDir.Count; j++) { float toCurrent = Vector3.Distance(endNodes[i].Position, nodesInDir[j].Position); if (toCurrent < toClosest) { toClosest = toCurrent; closest = nodesInDir[j]; } } if (toClosest < subEdgeEndConnectionRange) { connectTo = closest; } } // Else get intersection with closest edge in the direction of this endpoint if (connectTo == null) { // Ending point for tested segment in the direction of this endpoint Vector3 segmentEnd = endNodes[i].Position + nodeDir * 1000f; // Get the intersection Vector3 intersectPoint = Vector3.zero; // Convert all used points to XZ space Vector3 intersectPointXZ = Vector2.zero; Vector2 endPointXZ = new Vector2(endNodes[i].Position.x, endNodes[i].Position.z); Vector2 segmentEndXZ = new Vector2(segmentEnd.x, segmentEnd.z); List <Edge> intersectedEdges = new List <Edge>(); List <Vector3> intersectPoints = new List <Vector3>(); // Ignore the edge that starts on this endpoint Edge endEdge = _edges.Find(e => (e.Node1 == endNodes[i].ID || e.Node2 == endNodes[i].ID)); for (int j = 0; j < _edges.Count; j++) { if (_edges[j] == endEdge) { continue; } Node n1 = Node.GetNode(_nodes, _edges[j].Node1); Node n2 = Node.GetNode(_nodes, _edges[j].Node2); Vector2 node1XZ = new Vector2(n1.Position.x, n1.Position.z); Vector2 node2XZ = new Vector2(n2.Position.x, n2.Position.z); if (UtilityTools.MathHelper.AreIntersecting(out intersectPointXZ, endPointXZ, segmentEndXZ, node1XZ, node2XZ) == 1) { intersectPoints.Add(new Vector3(intersectPointXZ.x, n1.Position.y, intersectPointXZ.y)); intersectedEdges.Add(_edges[j]); } } // Get closest intersect point float toClosest = Mathf.Infinity; Edge closestIntersectedEdge = null; for (int j = 0; j < intersectPoints.Count; j++) { float toPoint = Vector3.Distance(endNodes[i].Position, intersectPoints[j]); if (toPoint < toClosest) { toClosest = toPoint; intersectPoint = intersectPoints[j]; closestIntersectedEdge = intersectedEdges[j]; } } // Split the intersected edge on the intersection if (closestIntersectedEdge == null || intersectPoint == Vector3.zero) { Debug.Log("Primitive::ConnectEndPoints() - Intersect point not found."); continue; } else { connectTo = Edge.SplitEdge(closestIntersectedEdge, intersectPoint, _nodes, _edges); } } _edges.Add(new Edge(endNodes[i].ID, connectTo.ID, subEdgeWidth)); } // Refresh adjacent nodes after all the endpoint connections EdgeGraphUtility.CheckAdjacentNodes(ref _nodes, ref _edges); }
/// Goes through all the edges and finds intersections /// If intersections are found, splits both edges in the intersection point /// </summary> /// <returns>True if an edge was fixed</returns> public static bool FixIntersectingEdges(ref List <Node> nodes, ref List <Edge> edges) { bool retval = false; CleanUpEdges(ref nodes, ref edges); int limit = edges.Count; for (int i = 0; i < edges.Count; i++) { if (i > limit) { break; } Vector3 intersectPoint = Vector3.zero; Node n1 = Node.GetNode(nodes, edges[i].Node1); Node n2 = Node.GetNode(nodes, edges[i].Node2); if (n1 == null || n2 == null) { continue; } Vector2 node1XZ = new Vector2(n1.Position.x, n1.Position.z); Vector2 node2XZ = new Vector2(n2.Position.x, n2.Position.z); for (int j = 0; j < edges.Count; j++) { if (i == j) { continue; } Node otherN1 = Node.GetNode(nodes, edges[j].Node1); Node otherN2 = Node.GetNode(nodes, edges[j].Node2); if (otherN1 == null || otherN2 == null || otherN1.adjacents.Contains(n1.ID) || otherN2.adjacents.Contains(n1.ID) || otherN1.adjacents.Contains(n2.ID) || otherN2.adjacents.Contains(n2.ID)) { continue; } Vector2 otherN1XZ = new Vector2(otherN1.Position.x, otherN1.Position.z); Vector2 otherN2XZ = new Vector2(otherN2.Position.x, otherN2.Position.z); Vector3 intersectPointXZ; if (UtilityTools.MathHelper.AreIntersecting(out intersectPointXZ, node1XZ, node2XZ, otherN1XZ, otherN2XZ) == 1) { intersectPoint = new Vector3(intersectPointXZ.x, otherN1.Position.y, intersectPointXZ.y); Node intersectNode = Edge.SplitEdge(edges[i], intersectPoint, nodes, edges); Edge.SplitEdge(edges[j], intersectPoint, nodes, edges, intersectNode); retval = true; break; } } } return(retval); }