SplitEdge() public static method

Splits given edge into two edges at given point If a node is given, it will be used to split the edges Otherwise make a new node
public static SplitEdge ( Edge edge, Vector3 point, List nodes, List edges, Node node = null ) : Node
edge Edge
point Vector3
nodes List
edges List
node Node
return Node
Example #1
0
        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);
        }
Example #2
0
        /// 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);
        }