private bool IsPossibleMergeTriangles(Vector2 aA, Vector2 aB, ref int[] aCrossedEdges)
        {
            Vector2 c, d;
            int     count = 0;

            for (int i = 0, n = _self.edges.Count; i < n; i++)
            {
                c = _self.vertices[_self.edges[i].a];
                d = _self.vertices[_self.edges[i].b];
                if (AntGeo.LinesCross(aA, aB, c, d))
                {
                    // Write crossed edge to the result array.
                    if (count < aCrossedEdges.Length)
                    {
                        aCrossedEdges[count] = i;
                    }
                    count++;

                    if (_self.edges[i].HasNeigbors)
                    {
                        // Crossed line with neighbors, can't to connect.
                        return(false);
                    }
                }
            }
            return(count == 2);
        }
 private bool DrawEdgesIfNotCrossing(Vector2 aA, Vector2 aB, Vector2 aC, Vector2 aD)
 {
     if (!AntGeo.LinesCross(aA, aB, aC, aD))
     {
         Handles.DrawDottedLine(aA, aB, 1.0f);
         Handles.DrawDottedLine(aC, aD, 1.0f);
         return(true);
     }
     return(false);
 }
Ejemplo n.º 3
0
        public int FindNodeByPoint(Vector2 aPoint)
        {
            var v = new Vector2[3];

            for (int i = 0, n = nodes.Count; i < n; i++)
            {
                v[0] = vertices[edges[nodes[i].edges[0]].a];
                v[1] = vertices[edges[nodes[i].edges[0]].b];
                v[2] = vertices[edges[nodes[i].edges[2]].a];
                if (AntGeo.IsPointInConvexPolygon(ref v, aPoint))
                {
                    return(i);
                }
            }
            return(-1);
        }
Ejemplo n.º 4
0
        private bool IsCrossAnyWall(Vector2 aA, Vector2 aB)
        {
            int count = 0;

            for (int i = 0, n = edges.Count; i < n; i++)
            {
                if (!edges[i].HasNeigbors)
                {
                    if (AntGeo.LinesCross(aA, aB, vertices[edges[i].a], vertices[edges[i].b], true))
                    {
                        return(true);
                    }
                }
                else if (AntGeo.LinesCross(aA, aB, vertices[edges[i].a], vertices[edges[i].b], true))
                {
                    count++;
                }
            }
            return(!(count > 0));
        }
        private void LinkNodes(int aFrom, int aTo)
        {
            Vector2 c, d;
            var     a = _self.GetNodeCenter(aFrom);
            var     b = _self.GetNodeCenter(aTo);

            for (int i = 0, n = _self.edges.Count; i < n; i++)
            {
                c = _self.vertices[_self.edges[i].a];
                d = _self.vertices[_self.edges[i].b];
                if (AntGeo.LinesCross(a, b, c, d))
                {
                    var e = _self.edges[i];
                    e.AddNeighbor(aFrom);
                    e.AddNeighbor(aTo);
                    _self.edges[i] = e;
                    return;
                }
            }
        }
Ejemplo n.º 6
0
        public Vector2 GetNodeCenter(int aNodeIndex)
        {
            var a   = vertices[edges[nodes[aNodeIndex].edges[0]].a];
            var b   = vertices[edges[nodes[aNodeIndex].edges[0]].b];
            var toA = new Vector2((a.x + b.x) * 0.5f, (a.y + b.y) * 0.5f);

            a = vertices[edges[nodes[aNodeIndex].edges[2]].a];
            b = vertices[edges[nodes[aNodeIndex].edges[2]].b];
            var toB = new Vector2((a.x + b.x) * 0.5f, (a.y + b.y) * 0.5f);

            a = vertices[edges[nodes[aNodeIndex].edges[1]].a];
            b = vertices[edges[nodes[aNodeIndex].edges[1]].b];

            var result = Vector2.zero;

            if (!AntGeo.LinesCross(b, toA, a, toB, out result))
            {
                AntGeo.LinesCross(a, toA, b, toB, out result);
            }
            return(result);
        }
Ejemplo n.º 7
0
        private void BuildRoute(Vector2 aFrom, Vector2 aTo, List <int> aWay, ref List <Vector2> aRoute)
        {
            aRoute.Clear();
            aRoute.Add(aFrom);

            var     currentPoint = aFrom;
            var     nextPoint = Vector2.zero;
            Vector2 a, b, c, d, to;
            Node    node;

            for (int i = 0, n = aWay.Count; i < n; i++)
            {
                node = nodes[aWay[i]];
                for (int j = 0; j < 3; j++)
                {
                    // If edge has links to neighbors.
                    if (edges[node.edges[j]].HasNeigbors)
                    {
                        // Extract edge points.
                        a = vertices[edges[node.edges[j]].a];
                        b = vertices[edges[node.edges[j]].b];

                        // Expand the ray to the target.
                        to = AntGeo.ExpandSegment(currentPoint, aTo, 100.0f);

                        // Check crossing ray from current point to the target.
                        if (AntGeo.LinesCross(currentPoint, to, a, b, out nextPoint))
                        {
                            AddPointToList(ref aRoute, nextPoint);
                            currentPoint = nextPoint;
                            break;
                        }
                        else
                        {
                            // If not found crossing, then expand edge to two sides.
                            AntGeo.ExpandSegment(a, b, out c, out d, 50.0f);

                            // Check ray to the target with expanded edge.
                            if (AntGeo.LinesCross(currentPoint, to, c, d, out nextPoint))
                            {
                                // If found crossing point with expanded edge, find the near point of the edge to cross point.
                                AntGeo.ExpandSegment(a, b, out c, out d, -0.1f);
                                nextPoint = AntGeo.GetNearestPointFromSegment(nextPoint, c, d);

                                AddPointToList(ref aRoute, nextPoint);
                                currentPoint = nextPoint;
                                break;
                            }
                            else
                            {
                                // If no found crossing, then try to cast ray from the center of current node.
                                currentPoint = node.position;
                                if (AntGeo.LinesCross(currentPoint, to, c, d, out nextPoint))
                                {
                                    AntGeo.ExpandSegment(a, b, out c, out d, -0.1f);
                                    nextPoint = AntGeo.GetNearestPointFromSegment(nextPoint, c, d);

                                    AddPointToList(ref aRoute, nextPoint);
                                    currentPoint = nextPoint;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            // Add last point.
            aRoute.Add(aTo);

            // Debug route.
            _routeA.Clear();
            for (int i = 0, n = aRoute.Count; i < n; i++)
            {
                _routeA.Add(aRoute[i]);
            }

            // Optimize path to remove some points.
            int co = 3;

            while (co != 0)
            {
                co--;
                var delList      = new List <int>();
                int currentIndex = 0;
                int nextIndex    = 2;

                while (true)
                {
                    if (nextIndex >= aRoute.Count)
                    {
                        break;
                    }

                    if (IsCrossAnyWall(aRoute[currentIndex], aRoute[nextIndex]))
                    {
                        currentIndex++;
                        nextIndex++;
                    }
                    else
                    {
                        aRoute.RemoveAt(nextIndex - 1);
                    }
                }
            }
        }
        private bool MergeEdgesIfNotCrossing(Vector2 aA, Vector2 aB, Vector2 aC, Vector2 aD, int aFrom, int aTo)
        {
            // Link two nodes only. (?)
            // if ((AntMath.Equal(aA, aC) && AntMath.Equal(aB, aD)) ||
            //  (AntMath.Equal(aA, aD) && AntMath.Equal(aB, aC)))
            // {
            //  AntLog.Trace("Merge two edges!");
            //  return true;
            // }

            // Create one new node.
            // --------------------
            var v = new Vector2[] { aA, aB, aC, aD };

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (i != j && AntMath.Equal(v[i], v[j]))
                    {
                        // Remove shared vertex.
                        AntArray.RemoveAt <Vector2>(ref v, i);

                        var edges = new int[3];
                        edges[0] = GetEdge(v[0], v[1]);
                        edges[1] = GetEdge(v[1], v[2]);
                        edges[2] = GetEdge(v[2], v[0]);

                        var node = AddNode(edges[0], edges[1], edges[2]);
                        LinkNodes(aFrom, node);
                        LinkNodes(node, aTo);

                        var center   = _self.GetNodeCenter(node);
                        var testNode = _self.FindNodeByPoint(center);
                        if (testNode != node)
                        {
                            // The triangle turned inside out, recreate.
                            RemoveNode(node);

                            edges[0] = GetEdge(v[0], v[2]);
                            edges[1] = GetEdge(v[2], v[1]);
                            edges[2] = GetEdge(v[1], v[0]);

                            node = AddNode(edges[0], edges[1], edges[2]);
                            LinkNodes(aFrom, node);
                            LinkNodes(node, aTo);

                            center   = _self.GetNodeCenter(node);
                            testNode = _self.FindNodeByPoint(center);
                            if (testNode != node)
                            {
                                // The triangle turned inside out, recreate.
                                RemoveNode(node);

                                edges[0] = GetEdge(v[1], v[2]);
                                edges[1] = GetEdge(v[2], v[0]);
                                edges[2] = GetEdge(v[0], v[1]);

                                node = AddNode(edges[0], edges[1], edges[2]);
                                LinkNodes(aFrom, node);
                                LinkNodes(node, aTo);

                                center   = _self.GetNodeCenter(node);
                                testNode = _self.FindNodeByPoint(center);
                                if (testNode != node)
                                {
                                    A.Warning("Wrong triangle! ({0})", node);
                                }
                            }
                        }

                        return(true);
                    }
                }
            }

            // Create two new nodes.
            // ---------------------
            if (!AntGeo.LinesCross(aA, aB, aC, aD))
            {
                var edges = new int[5];
                edges[0] = GetEdge(aA, aB);
                edges[1] = GetEdge(aB, aD);
                edges[2] = GetEdge(aD, aA);
                edges[3] = GetEdge(aA, aC);
                edges[4] = GetEdge(aC, aD);

                var nodeA = AddNode(edges[0], edges[1], edges[2]);
                var nodeB = AddNode(edges[3], edges[4], edges[2]);
                LinkNodes(aFrom, nodeA);
                LinkNodes(nodeA, nodeB);
                LinkNodes(nodeB, aTo);
                return(true);
            }

            return(false);
        }