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); }
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); }
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; } } }
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); }
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); }