public double DiagonalDistanceTo(BuildingBlock point) { double xDistance = Math.Abs(X - point.X); double yDistance = Math.Abs(Y - point.Y); if (xDistance > yDistance) { return(Math.Sqrt(2) * yDistance + 1 * (xDistance - yDistance)); } return(Math.Sqrt(2) * xDistance + 1 * (yDistance - xDistance)); }
private void InitializeRoomPriority(BuildingBlock door) { _globalRoomCounter++; int targetPriority = door.Priority + 1; bool done = false; List <BuildingBlock> tileList = BuildingBlocks.Values.Where(t => t.Type == Tile.Types.Free || t.Type == Tile.Types.Person || t.Type == Tile.Types.Stair).ToList(); List <BuildingBlock> doorNeighbours = door.BuildingBlockNeighbours.Where( n => (n.Type == Tile.Types.Free || n.Type == Tile.Types.Person) && n.Priority > targetPriority).ToList(); if (doorNeighbours.Count == 0) { done = true; } foreach (BuildingBlock block in doorNeighbours) { block.Priority = targetPriority; if (block.Room == 0) { block.Room = _globalRoomCounter; } } do { if (tileList.Any(b => b.BuildingBlockNeighbours.Any(n => n.Priority == targetPriority) && b.Priority > targetPriority && (b.Type == Tile.Types.Free || b.Type == Tile.Types.Person))) { foreach ( BuildingBlock block in tileList.Where(b => b.BuildingBlockNeighbours.Any(n => n.Priority == targetPriority && n.Z == b.Z) && b.Priority > targetPriority)) { block.Priority = targetPriority; if (block.Room == 0) { block.Room = _globalRoomCounter; } } } else { done = true; } } while (!done); }
private void CreateVisualRepresentation() { int width = LocalFloorPlan.Width; int height = LocalFloorPlan.Height; int floorAmount = LocalFloorPlan.FloorAmount; _floorContainer = new Grid[floorAmount]; for (int z = 0; z < floorAmount; z++) { Grid container = new Grid() { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top }; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Rectangle figure = new Rectangle { Height = TileSize, Width = TileSize, Fill = new SolidColorBrush(Colors.White), Tag = Coordinate(x, y, z), /* Makes binding rectangles to buildingblocks easier */ Margin = new Thickness(0, 0, x * TileSize * 2 + x, y * TileSize * 2 + y) }; if (LocalFloorPlan.Tiles[Coordinate(x, y, z)].Type != Tile.Types.Free) { ColorizeBuildingBlock(figure, LocalFloorPlan.Tiles[Coordinate(x, y, z)].Type); } BuildingBlock current = (LocalFloorPlan.Tiles[Coordinate(x, y, z)] as BuildingBlock); current.Figure = figure; figure.ToolTip = current.ToString(); figure.MouseLeftButtonDown += OnBuildingBlockClick; AllRectangles.Add(Coordinate(x, y, z), figure); container.Children.Add(figure); } } _floorContainer[z] = container; } VisualContainer.Children.Add(_floorContainer[0]); }
private void OnBuildingBlockClick(object sender, MouseButtonEventArgs e) { Tile.Types type = (Tile.Types)OnBuildingBlockTypeFetch?.Invoke(); //Get the type of the currently radio'ed FloorPlanControl-type Rectangle senderRectangle = sender as Rectangle; //Get a reference to the sender rectangle if (senderRectangle == null) { throw new GeneralInternalException(); } BuildingBlock senderBlock = (BuildingBlock)LocalFloorPlan.Tiles[senderRectangle.Tag.ToString()]; SetBlockType(senderBlock, type); if (Keyboard.IsKeyDown(Settings.LineToolKey)) { if (previousBlock != null) { DrawLine(senderBlock, type); } previousBlock = senderBlock; } }
private void SetExitAndStairPriority(BuildingBlock exitOrStair, IEnumerable <BuildingBlock> doorlist) { InitializeRoomPriority(exitOrStair); do { foreach (BuildingBlock door in doorlist.Where(d => d.Z == exitOrStair.Z)) { //Checks for each door, if the doors priority is larger than the surrounding buildingblocks if (door.Priority > (BuildingBlocks.Values.Where( b => b.BuildingBlockNeighbours.Contains(door) && b.Type == Tile.Types.Free || b.Type == Tile.Types.Person) .Min(n => n.Priority))) { door.Priority = (BuildingBlocks.Values.Where(b => (b.Type == Tile.Types.Free || b.Type == Tile.Types.Person) && b.BuildingBlockNeighbours.Contains(door)).Min(n => n.Priority)); door.Priority++; InitializeRoomPriority(door); } } } while (doorlist.Any(d => d.Priority - d.BuildingBlockNeighbours.Min(n => n.Priority) > 2)); }
//Method using to person, when person is blocked more than 5 rounds. private IEnumerable <BuildingBlock> FindNewPath(Person person) { //Gets the personblocking's pathlist BuildingBlock target = person.PathList[person.StepsTaken + 1]; BuildingBlock pos = person.PathList[person.StepsTaken]; if (AllPeople.Values.Count(p => p.PathList.Count > p.StepsTaken + 1 && p.PathList[p.StepsTaken] == target && p.PathList[p.StepsTaken + 1] == pos) == 1) { Person personBlocking = AllPeople.Values.First(p => p.PathList[p.StepsTaken] == target); if (personBlocking.PathList.Count > 0 && (person.Position as BuildingBlock).BuildingBlockNeighbours.Any(n => n.Type != Tile.Types.Person)) { if (personBlocking.PathList.Count(b => b.Type != Tile.Types.Person) < person.PathList.Count(b => b.Type != Tile.Types.Person)) { person.PathList.Clear(); person.PathList.AddRange(personBlocking.PathList); person.StepsTaken = personBlocking.StepsTaken + 1; } } } return(null); }
private void CheckForStairConnection(BuildingBlock buildingBlock) { if (buildingBlock.Type == Tile.Types.Stair && FloorAmount > 1) { string coordinatesOfFloorAbove = Coordinate(buildingBlock.X, buildingBlock.Y, buildingBlock.Z + 1); string coordinatesOfFloorBelow = Coordinate(buildingBlock.X, buildingBlock.Y, buildingBlock.Z - 1); if (Tiles.ContainsKey(coordinatesOfFloorAbove)) { BuildingBlock neighbourAbove = Tiles[coordinatesOfFloorAbove] as BuildingBlock; if (neighbourAbove?.Type == Tile.Types.Stair) { buildingBlock.BuildingBlockNeighbours.Add(neighbourAbove); } } if (Tiles.ContainsKey(coordinatesOfFloorBelow)) { BuildingBlock neighbourBelow = Tiles[coordinatesOfFloorBelow] as BuildingBlock; if (neighbourBelow?.Type == Tile.Types.Stair) { buildingBlock.BuildingBlockNeighbours.Add(neighbourBelow); } } } }
private IEnumerable <Tile> GetPathUsingAStar(IEvacuateable person, BuildingBlock destination) { bool firstRun = true; SortedSet <BuildingBlock> priorityQueue = new SortedSet <BuildingBlock>(Comparer <BuildingBlock> .Default); Dictionary <string, BuildingBlock> closedSet = new Dictionary <string, BuildingBlock>(); List <BuildingBlock> unvisitedVertices = TheFloorPlan.Tiles.Values.Cast <BuildingBlock>().ToList(); foreach (BuildingBlock point in unvisitedVertices) { point.LengthToDestination = point.DiagonalDistanceTo(destination); point.Parent = null; if (firstRun) { firstRun = false; } else { point.LengthFromSource = 100000; } point.IsChecked = false; } unvisitedVertices.Remove(person.Position as BuildingBlock); BuildingBlock currentPosition = person.Position as BuildingBlock; if (currentPosition == null) { return(null); } currentPosition.LengthFromSource = 0; unvisitedVertices.Insert(0, currentPosition); while (!Equals(currentPosition, destination)) { foreach (BuildingBlock buildingBlock in currentPosition.BuildingBlockNeighbours) { if (buildingBlock.IsChecked == false) { if (!closedSet.ContainsKey(Settings.Coordinate(buildingBlock.X, buildingBlock.Y, buildingBlock.Z))) { priorityQueue.Add(buildingBlock); } } } CheckNeighbors(currentPosition, priorityQueue); if (priorityQueue.Count == 0) { if (closedSet.ContainsKey(Settings.Coordinate(currentPosition.X, currentPosition.Y, currentPosition.Z)) == false) { closedSet.Add(Settings.Coordinate(currentPosition.X, currentPosition.Y, currentPosition.Z), currentPosition); } foreach (BuildingBlock buildingBlock in unvisitedVertices) { buildingBlock.IsChecked = false; } continue; } currentPosition.IsChecked = true; currentPosition = priorityQueue.First(); priorityQueue.Clear(); } List <BuildingBlock> path = new List <BuildingBlock>(); BuildingBlock parent = destination; do { path.Add(parent); parent = parent.Parent; } while (parent != null); path.Reverse(); return(path); }
public Person(BuildingBlock position) : this(0, 0, position) { }
private Color CalculateHeatMapColor(BuildingBlock block) { // Modified from: http://www.andrewnoske.com/wiki/Code_-_heatmaps_and_color_gradients double value = Math.Min( (double)block.HeatmapCounter / ((double)_mainWindow.TheUserInterface.LocalPeopleDictionary.Count * 2), 1.0); int colorAmount = 4; double[,] color = { { 0, 0, 255 } , { 0, 255, 0 } , { 255, 255, 0 } , { 255, 0, 0 } }; // A static array of 4 colors: (blue, green, yellow, red) using {r,g,b} for each. int idx1; // |-- Our desired color will be between these two indexes in "color". int idx2; // | double fractBetween = 0; // Fraction between "idx1" and "idx2" where our value is. if (value <= 0) { idx1 = idx2 = 0; } // accounts for an input <=0 else if (value >= 255) { idx1 = idx2 = colorAmount - 1; } // accounts for an input >=0 else { value = value * (colorAmount - 1); // Will multiply value by 3. idx1 = (int)Math.Floor(value); // Our desired color will be after this index. idx2 = Math.Min(idx1 + 1, colorAmount - 1); // ... and before this index (inclusive). fractBetween = value - idx1; // Distance between the two indexes (0-1). } int red = (int)Math.Round((color[idx2, 0] - color[idx1, 0]) * fractBetween + color[idx1, 0]); int green = (int)Math.Round((color[idx2, 1] - color[idx1, 1]) * fractBetween + color[idx1, 1]); int blue = (int)Math.Round((color[idx2, 2] - color[idx1, 2]) * fractBetween + color[idx1, 2]); return(new Color { A = 255, R = Convert.ToByte(red), G = Convert.ToByte(green), B = Convert.ToByte(blue) }); }
public void LineToolReleased() { previousBlock = null; }