// helper method for the above private List <PolygonWaypoint> findExitPath(PolygonWaypoint waypoint, List <PolygonWaypoint> visitedWaypoints) { foreach (PolygonWaypoint neighbor in waypoint.neighbors) { if (!visitedWaypoints.Contains(neighbor)) { visitedWaypoints.Add(neighbor); // found an opening - pack away the recursion and return the path if (neighbor.waypointType == PolygonWaypoint.WaypointType.OPENING) { List <PolygonWaypoint> exitPath = new List <PolygonWaypoint>(); exitPath.Add(neighbor); return(exitPath); } else { List <PolygonWaypoint> exitPath = findExitPath(neighbor, visitedWaypoints); if (exitPath != null) { exitPath.Add(neighbor); return(exitPath); } } } } return(null); }
// simple use of dijkstra's algorithm to find shortest path to an exit (incomplete, if necessary at all) public List <PolygonWaypoint> findShortestPathToWaypoint(PolygonWaypoint srcWaypoint, PolygonWaypoint destWaypoint) { Dictionary <PolygonWaypoint, Double> waypointDistances = new Dictionary <PolygonWaypoint, double>(); Dictionary <PolygonWaypoint, PolygonWaypoint> prevs = new Dictionary <PolygonWaypoint, PolygonWaypoint>(); List <PolygonWaypoint> unvisited = new List <PolygonWaypoint>(); List <PolygonWaypoint> visited = new List <PolygonWaypoint>(); // start with all nodes unvisited foreach (PolygonWaypoint point in waypoints) { waypointDistances.Add(point, Double.PositiveInfinity); } // set starting waypoint with tentative distance 0 and evaluate neighboring waypoints unvisited.Remove(srcWaypoint); waypointDistances[srcWaypoint] = 0; visited.Add(srcWaypoint); // keep evaluating waypoints until exit waypoint is evaluated while (true) { double minTentativeDistance = Double.PositiveInfinity; PolygonWaypoint minNeighbor = null; // find the minimal tentative distance from the visited set to the neighbor foreach (PolygonWaypoint visitedWaypoint in visited) { foreach (PolygonWaypoint neighbor in visitedWaypoint.neighbors) { if (visited.Contains(neighbor)) { continue; } double distance = TerrainService.MathEngine.CalcDistance(visitedWaypoint.x, visitedWaypoint.y, neighbor.x, neighbor.y); if (distance + waypointDistances[visitedWaypoint] < waypointDistances[neighbor]) { waypointDistances[neighbor] = distance + waypointDistances[visitedWaypoint]; } if (waypointDistances[neighbor] < minTentativeDistance) { minTentativeDistance = waypointDistances[neighbor]; minNeighbor = neighbor; } } } visited.Add(minNeighbor); unvisited.Remove(minNeighbor); } return(null); }
// simple use of dijkstra's algorithm to find shortest path to an exit (incomplete, if necessary at all) public List<PolygonWaypoint> findShortestPathToWaypoint(PolygonWaypoint srcWaypoint, PolygonWaypoint destWaypoint) { Dictionary<PolygonWaypoint, Double> waypointDistances = new Dictionary<PolygonWaypoint, double>(); Dictionary<PolygonWaypoint, PolygonWaypoint> prevs = new Dictionary<PolygonWaypoint, PolygonWaypoint>(); List<PolygonWaypoint> unvisited = new List<PolygonWaypoint>(); List<PolygonWaypoint> visited = new List<PolygonWaypoint>(); // start with all nodes unvisited foreach (PolygonWaypoint point in waypoints) { waypointDistances.Add(point, Double.PositiveInfinity); } // set starting waypoint with tentative distance 0 and evaluate neighboring waypoints unvisited.Remove(srcWaypoint); waypointDistances[srcWaypoint] = 0; visited.Add(srcWaypoint); // keep evaluating waypoints until exit waypoint is evaluated while (true) { double minTentativeDistance = Double.PositiveInfinity; PolygonWaypoint minNeighbor = null; // find the minimal tentative distance from the visited set to the neighbor foreach (PolygonWaypoint visitedWaypoint in visited) { foreach (PolygonWaypoint neighbor in visitedWaypoint.neighbors) { if (visited.Contains(neighbor)) continue; double distance = TerrainService.MathEngine.CalcDistance(visitedWaypoint.x, visitedWaypoint.y, neighbor.x, neighbor.y); if (distance + waypointDistances[visitedWaypoint] < waypointDistances[neighbor]) { waypointDistances[neighbor] = distance + waypointDistances[visitedWaypoint]; } if (waypointDistances[neighbor] < minTentativeDistance) { minTentativeDistance = waypointDistances[neighbor]; minNeighbor = neighbor; } } } visited.Add(minNeighbor); unvisited.Remove(minNeighbor); } return null; }
// find closest waypoint in the polygon to the given coordinates public PolygonWaypoint findClosestWaypoint(double x, double y) { PolygonWaypoint closest = waypoints.ElementAt(0); foreach (PolygonWaypoint w in waypoints) { double distToClosest = TerrainService.MathEngine.CalcDistance(x, y, closest.x, closest.y); double distToCurrentWaypoint = TerrainService.MathEngine.CalcDistance(x, y, w.x, w.y); if (distToCurrentWaypoint < distToClosest) { closest = w; } } return(closest); }
public void addWaypoint(PolygonWaypoint waypoint, params PolygonWaypoint[] neighbors) { // do not allow duplicate waypoints! if (waypoints.Contains(waypoint)) return; waypoints.Add(waypoint); if (waypoint.waypointType == PolygonWaypoint.WaypointType.CORRIDOR) corridors.Add(waypoint); if (waypoint.waypointType == PolygonWaypoint.WaypointType.ROOM) rooms.Add(waypoint); if (waypoint.waypointType == PolygonWaypoint.WaypointType.OPENING) openings.Add(waypoint); if (neighbors != null) { foreach (PolygonWaypoint neighbor in neighbors) { // this is a directed graph so we must add neighborhoods mutually, yet avoid duplicates if (!waypoint.neighbors.Contains(neighbor)) waypoint.neighbors.Add(neighbor); if (!neighbor.neighbors.Contains(waypoint)) neighbor.neighbors.Add(waypoint); } } }
// arbitrarily find an exit path from a specific waypoint public List <PolygonWaypoint> findExitPath(PolygonWaypoint waypoint) { List <PolygonWaypoint> visitedWaypoints = new List <PolygonWaypoint>(); List <PolygonWaypoint> exitPath = new List <PolygonWaypoint>(); visitedWaypoints.Add(waypoint); // if destination waypoint is already an opening let it be our path out if (waypoint.waypointType == PolygonWaypoint.WaypointType.OPENING) { exitPath.Add(waypoint); return(exitPath); } // if not, go ahead and find a path exitPath.AddRange(findExitPath(waypoint, visitedWaypoints)); exitPath.Add(waypoint); exitPath.Reverse(); return(exitPath); }
public void addWaypoint(PolygonWaypoint waypoint, params PolygonWaypoint[] neighbors) { // do not allow duplicate waypoints! if (waypoints.Contains(waypoint)) { return; } waypoints.Add(waypoint); if (waypoint.waypointType == PolygonWaypoint.WaypointType.CORRIDOR) { corridors.Add(waypoint); } if (waypoint.waypointType == PolygonWaypoint.WaypointType.ROOM) { rooms.Add(waypoint); } if (waypoint.waypointType == PolygonWaypoint.WaypointType.OPENING) { openings.Add(waypoint); } if (neighbors != null) { foreach (PolygonWaypoint neighbor in neighbors) { // this is a directed graph so we must add neighborhoods mutually, yet avoid duplicates if (!waypoint.neighbors.Contains(neighbor)) { waypoint.neighbors.Add(neighbor); } if (!neighbor.neighbors.Contains(waypoint)) { neighbor.neighbors.Add(waypoint); } } } }
//VH internal void PolygonsInit() { try { List<clsPolygon> structures = new List<clsPolygon>(); Structure1 = TDS.DAL.PolygonsDB.GetPolygonByName("Polygon1"); Structure2 = TDS.DAL.PolygonsDB.GetPolygonByName("Malam"); // initialize waypoint graphs. TODO - move to non volatile afterwards Structure1.waypointGraph = new PolygonWaypointGraph(); PolygonWaypoint waypoint1 = new PolygonWaypoint(1, 34.849099516868591, 32.098940297448664, PolygonWaypoint.WaypointType.CORRIDOR); PolygonWaypoint waypoint2 = new PolygonWaypoint(2, 34.849078059196472, 32.098663090529335, PolygonWaypoint.WaypointType.CORRIDOR); PolygonWaypoint waypoint3 = new PolygonWaypoint(3, 34.849582314491272, 32.098685812439619, PolygonWaypoint.WaypointType.CORRIDOR); PolygonWaypoint waypoint7 = new PolygonWaypoint(7, 34.85012412071228, 32.098722167484318, PolygonWaypoint.WaypointType.CORRIDOR); PolygonWaypoint waypoint8 = new PolygonWaypoint(8, 34.850113391876221, 32.098940297448664, PolygonWaypoint.WaypointType.ROOM); PolygonWaypoint waypoint9 = new PolygonWaypoint(9, 34.85012412071228, 32.098444959902984, PolygonWaypoint.WaypointType.ROOM); PolygonWaypoint waypoint10 = new PolygonWaypoint(10, 34.849571585655212, 32.0989584749222, PolygonWaypoint.WaypointType.ROOM); PolygonWaypoint opening0 = new PolygonWaypoint(4, 34.8490619659424, 32.0996174058948, PolygonWaypoint.WaypointType.OPENING); PolygonWaypoint opening4 = new PolygonWaypoint(5, 34.8496359586716, 32.0980768632898, PolygonWaypoint.WaypointType.OPENING); PolygonWaypoint opening5 = new PolygonWaypoint(6, 34.848627448082, 32.0989584749222, PolygonWaypoint.WaypointType.OPENING); opening0.edgeNum = 0; opening4.edgeNum = 4; opening5.edgeNum = 5; Structure1.waypointGraph.addWaypoint(waypoint1, waypoint2, opening0, opening5, waypoint10); Structure1.waypointGraph.addWaypoint(waypoint2, waypoint1, waypoint3); Structure1.waypointGraph.addWaypoint(waypoint3, waypoint2, opening4); Structure1.waypointGraph.addWaypoint(waypoint7, waypoint3); Structure1.waypointGraph.addWaypoint(waypoint8, waypoint7); Structure1.waypointGraph.addWaypoint(waypoint9, waypoint7); Structure1.waypointGraph.addWaypoint(waypoint10, waypoint3, waypoint1); Structure1.waypointGraph.addWaypoint(opening0, waypoint1); Structure1.waypointGraph.addWaypoint(opening4, waypoint3); Structure1.waypointGraph.addWaypoint(opening5, waypoint1); Structure2.waypointGraph = new PolygonWaypointGraph(); PolygonWaypoint malamOpening1 = new PolygonWaypoint(1, 34.8513351380825, 32.098514261381, PolygonWaypoint.WaypointType.OPENING); malamOpening1.edgeNum = 1; PolygonWaypoint malamWaypoint2 = new PolygonWaypoint(2, 34.851239919662476, 32.098531303338191, PolygonWaypoint.WaypointType.CORRIDOR); PolygonWaypoint malamWaypoint3 = new PolygonWaypoint(3, 34.851202368736267, 32.098304083596624, PolygonWaypoint.WaypointType.CORRIDOR); PolygonWaypoint malamWaypoint4 = new PolygonWaypoint(4, 34.850950241088867, 32.098322261196749, PolygonWaypoint.WaypointType.CORRIDOR); PolygonWaypoint malamWaypoint5 = new PolygonWaypoint(5, 34.851266741752625, 32.098753978136557, PolygonWaypoint.WaypointType.CORRIDOR); PolygonWaypoint malamWaypoint6 = new PolygonWaypoint(6, 34.850998520851135, 32.098772155647154, PolygonWaypoint.WaypointType.CORRIDOR); Structure2.waypointGraph.addWaypoint(malamOpening1, malamWaypoint2); Structure2.waypointGraph.addWaypoint(malamWaypoint2, malamOpening1, malamWaypoint3, malamWaypoint5); Structure2.waypointGraph.addWaypoint(malamWaypoint3, malamWaypoint2, malamWaypoint4); Structure2.waypointGraph.addWaypoint(malamWaypoint4, malamWaypoint3); Structure2.waypointGraph.addWaypoint(malamWaypoint5, malamWaypoint2, malamWaypoint6); Structure2.waypointGraph.addWaypoint(malamWaypoint6, malamWaypoint5); structures.Add(Structure1); structures.Add(Structure2); foreach (clsPolygon structure in structures) { foreach (var pnt in structure.Points) { if (pnt.x > structure.maxX) structure.maxX = pnt.x; if (pnt.x < structure.minX) structure.minX = pnt.x; if (pnt.y > structure.maxY) structure.maxY = pnt.y; if (pnt.y < structure.minY) structure.minY = pnt.y; } } } catch (Exception ex) { } }
// helper method for the above private List<PolygonWaypoint> findExitPath(PolygonWaypoint waypoint, List<PolygonWaypoint> visitedWaypoints) { foreach (PolygonWaypoint neighbor in waypoint.neighbors) { if (!visitedWaypoints.Contains(neighbor)) { visitedWaypoints.Add(neighbor); // found an opening - pack away the recursion and return the path if (neighbor.waypointType == PolygonWaypoint.WaypointType.OPENING) { List<PolygonWaypoint> exitPath = new List<PolygonWaypoint>(); exitPath.Add(neighbor); return exitPath; } else { List<PolygonWaypoint> exitPath = findExitPath(neighbor, visitedWaypoints); if (exitPath != null) { exitPath.Add(neighbor); return exitPath; } } } } return null; }
// arbitrarily find an exit path from a specific waypoint public List<PolygonWaypoint> findExitPath(PolygonWaypoint waypoint) { List<PolygonWaypoint> visitedWaypoints = new List<PolygonWaypoint>(); List<PolygonWaypoint> exitPath = new List<PolygonWaypoint>(); visitedWaypoints.Add(waypoint); // if destination waypoint is already an opening let it be our path out if (waypoint.waypointType == PolygonWaypoint.WaypointType.OPENING) { exitPath.Add(waypoint); return exitPath; } // if not, go ahead and find a path exitPath.AddRange(findExitPath(waypoint, visitedWaypoints)); exitPath.Add(waypoint); exitPath.Reverse(); return exitPath; }