private void recreateRoomsButton_Click(object sender, EventArgs e)
        {
            if (mazeGraph != null && MessageBox.Show("This operation will remove the rooms and the graph. It cannot be undone.\n Are you sure?", "", MessageBoxButtons.OKCancel) != DialogResult.OK)
                return;
            mazeGraph = new MazeGraph();
            mazeRooms = new ArrayList();

            roomsTreeView.Nodes.Clear();

            RoomsGraphBuilder roomsGraphBuilder = new RoomsGraphBuilder();
            if (!ConvexOnlyCheckBox.Checked)
            {
                roomsGraphBuilder.GenerateConvexRoomsOnly = false;
                roomsGraphBuilder.SplitRoomsIntoConvex = false;
            }
            foreach (MazeWall wall in mazeWalls)
            {
                if (wall.MazeWallType == MazeWallType.wall)
                    roomsGraphBuilder.AddWall(new Point2D(wall.points[0].X, wall.points[0].Y), new Point2D(wall.points[1].X, wall.points[1].Y));
                else
                    roomsGraphBuilder.AddDoor(new Point2D(wall.points[0].X, wall.points[0].Y), new Point2D(wall.points[1].X, wall.points[1].Y));
            }
            roomsGraphBuilder.BuildRegion();

            Hashtable mazeNodeByRoomasGraphNodes = new Hashtable();
            Hashtable mazeWallsByRoomasGraphWalls = new Hashtable();

            ArrayList oldMazeWalls = mazeWalls;
            mazeWalls = new ArrayList();
            foreach (Room graphBuilderRoom in roomsGraphBuilder.Rooms)
            {
                ArrayList roomWalls = new ArrayList();
                foreach (Wall graphBuilderWall in graphBuilderRoom.Walls)
                {
                    bool oldWallFound = false;
                    foreach (MazeWall mazeWall in oldMazeWalls)     //find old
                    {
                        if (mazeWall.Segment.ContainsSegment(graphBuilderWall.WallSegment))
                        {
                            oldWallFound = true;
                            MazeWall roomWall = new MazeWall(graphBuilderWall.From, graphBuilderWall.To, mazeWall.Width, mazeWall.Height, mazeWall.Color);
                            roomWall.MazeWallType = (graphBuilderWall.Type == Wall.WallType.Solid ? MazeWallType.wall : MazeWallType.gate);
                            int indexOf = mazeWalls.IndexOf(roomWall);
                            if (indexOf >= 0)
                            {
                                roomWall = (MazeWall)mazeWalls[indexOf];
                            }
                            else
                            {
                                mazeWalls.Add(roomWall);
                                mazeWallsByRoomasGraphWalls[graphBuilderWall] = roomWall;
                            }
                            roomWalls.Add(roomWall);
                            break;
                        }
                    }
                    if (!oldWallFound)
                    {
                        MazeWall roomWall = new MazeWall(graphBuilderWall.From, graphBuilderWall.To, 0, 0, Color.Black);
                        int indexOf = mazeWalls.IndexOf(roomWall);
                        if (indexOf >= 0)
                        {
                            roomWall = (MazeWall)mazeWalls[indexOf];
                        }
                        else
                        {
                            roomWall.MazeWallType = MazeWallType.gate;
                            mazeWalls.Add(roomWall);
                            mazeWallsByRoomasGraphWalls[graphBuilderWall] = roomWall;
                        }
                        roomWalls.Add(roomWall);
                    }
                }

                /*              ///reorder walls
                              ArrayList orderedRoomWalls = new ArrayList();
                              orderedRoomWalls.Add(roomWalls[0]);
                              roomWalls.RemoveAt(0);
                              Point2D nextPoint = (roomWalls[0] as Wall).To;
                              while (roomWalls.Count > 0)
                              {
                                  foreach (Wall wall in roomWalls)
                                      if (wall.From.GetDistance(nextPoint) < 0.01)
                                      {
                                          nextPoint = wall.From;
                                          roomWalls.Remove(wall);
                                          orderedRoomWalls.Add(wall);
                                          break;
                                      }
                                      else if (wall.To.GetDistance(nextPoint) < 0.01)
                                      {
                                          nextPoint = wall.To;
                                          roomWalls.Remove(wall);
                                          orderedRoomWalls.Add(wall);
                                          break;
                                      }
                              }
              */
                MazeSpace room = new MazeSpace(roomWalls);
                mazeRooms.Add(room);
                foreach (MazeWall roomWall in roomWalls)
                {
                    if (roomWall.RoomFrom == null)
                        roomWall.RoomFrom = room;
                    else
                        roomWall.RoomTo = room;
                }

                //////////////////////////////////////   nodes

                foreach (RoomsGraph.Node borderNode in graphBuilderRoom.BorderNodes)        //push door-nodes into rooms
                {
                    Vector2D v = new Vector2D(borderNode.DoorWall.From, borderNode.DoorWall.To);
                    v.MakePerpendicular();
                    v.Length = (double)wallWidthNumericUpDown.Value * 100;
                    if (Math.Abs(v.AngleBetween(new Vector2D(borderNode.DoorWall.Center, borderNode.Location))) > Math.PI / 2)
                        v.Inverse();
                    borderNode.Position.X += v.x;
                    borderNode.Position.Y += v.y;
                }

                room.CetralNode = new MazeNode(graphBuilderRoom.CentralNode.Location, room, null);
                mazeNodeByRoomasGraphNodes[graphBuilderRoom.CentralNode] = room.CetralNode;
                mazeGraph.AddNode(room.CetralNode);
                foreach (RoomsGraph.Node n in graphBuilderRoom.BorderNodes)
                {
                    MazeNode mazeGraphNode = new MazeNode(n.Location, room, (MazeWall)mazeWallsByRoomasGraphWalls[n.DoorWall]);
                    mazeNodeByRoomasGraphNodes[n] = mazeGraphNode;
                    room.BorderNodes.Add(mazeGraphNode);
                    mazeGraph.AddNode(mazeGraphNode);
                }
            }

            foreach (RoomsGraph.Arc arc in roomsGraphBuilder.Graph.Arcs)
            {
                if (mazeNodeByRoomasGraphNodes[arc.StartNode] != null && mazeNodeByRoomasGraphNodes[arc.EndNode] != null)
                    mazeGraph.AddArc((MazeNode)mazeNodeByRoomasGraphNodes[arc.StartNode], (MazeNode)mazeNodeByRoomasGraphNodes[arc.EndNode]);
            }

            recreateRoomsTreeView();
            recreateGraphTreeView();
            RefreshMazeWallsTreeView();

            mazePanel_Paint(this, null);
        }
Beispiel #2
0
 /// <summary>
 /// ベクトルのクロス積
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 public static Vector3D CrossProduct(Vector2D a, Vector2D b)
 {
     return new Vector3D(0, 0, a.X * b.Y - a.Y * b.X);
 }
        private void mazePanel_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            mazeBitmapStaticGraphics.Clear(mazeBackColor);
            foreach (MazeWall wall in mazeWalls)
            {
                Pen wallPen = new Pen(wall.Color, wall.Width);
                mazeBitmapGraphics.DrawLine(wallPen, wall.points[0], wall.points[1]);
                wallPen.Dispose();
            }
            if (selectedWall != null)
            {
                mazeBitmapGraphics.DrawLine(selectedWallPen, selectedWall.points[0], selectedWall.points[1]);
            }

            int size = sizeTrackBar.Value;
            int sizeOffset = sizeTrackBar.Value / 2;

            foreach (MazeRobot robot in mazeRobots)
            {
                if (robot.Selected)
                {
                    mazeBitmapGraphics.FillEllipse(robotBrushSelected, robot.position.X - sizeOffset, robot.position.Y - sizeOffset, size, size);
                    mazeBitmapGraphics.DrawString(robot.name, fontSelected, robotBrushSelected, robot.position.X - sizeOffset, robot.position.Y - sizeOffset);
                    mazeBitmapGraphics.DrawLine(robotPenArrow, robot.position.X, robot.position.Y, robot.arrow.X, robot.arrow.Y);
                }
                else
                {
                    robotPenSelected.Color = getRobotColor(robot.Probability);
                    mazeBitmapGraphics.FillEllipse(robotPenSelected.Brush, robot.position.X - sizeOffset, robot.position.Y - sizeOffset, size, size);
                    mazeBitmapGraphics.DrawLine(robotPenArrow, robot.position.X, robot.position.Y, robot.arrow.X, robot.arrow.Y);
                }
            }

            RobotTask taskCurrent;
            RobotTask taskPrivious = null;

            for (int i = 0; i < robotsTaskList.Count(); i++)
            {
                taskCurrent = robotsTaskList[i];

                if (taskCurrent.IsEnd)
                    mazeBitmapGraphics.FillRectangle(taskPenDone, taskCurrent.GetTaskX - sizeOffset, taskCurrent.GetTaskY - sizeOffset, size, size);
                else
                    mazeBitmapGraphics.FillRectangle(taskPenInProgress, taskCurrent.GetTaskX - sizeOffset, taskCurrent.GetTaskY - sizeOffset, size, size);

                if (i == 0)
                    taskPrivious = taskCurrent;
                else
                {
                    if (taskPrivious.RobotID != taskCurrent.RobotID)
                        taskPrivious = taskCurrent;
                    else
                    {
                        Pen temp = taskPanDirection[taskPrivious.RobotID - 1];
                        temp.CustomEndCap = new AdjustableArrowCap(size / 2, size / 2);
                        Vector2D arcDir = new Vector2D(new Point2D(taskPrivious.GetTaskX, taskPrivious.GetTaskY), new Point2D(taskCurrent.GetTaskX, taskCurrent.GetTaskY));
                        arcDir.Normalize();

                        mazeBitmapGraphics.DrawLine(temp, taskPrivious.GetTaskX, taskPrivious.GetTaskY, taskCurrent.GetTaskX, taskCurrent.GetTaskY);

                        taskPrivious = taskCurrent;
                    }
                }
            }

            /*for(int i = 0; i < mazeTargets.Count; i++)
            {
                target = (Target) mazeTargets[i];

                if (target.TaskDone)
                    mazeBitmapGraphics.FillRectangle(taskPenDone, target.X - sizeOffset, target.Y - sizeOffset, size, size);
                else
                    mazeBitmapGraphics.FillRectangle(taskPenInProgress, target.X - sizeOffset, target.Y - sizeOffset, size, size);

                if ((i > 0) && (i != mazeTargets.Count))
                {
                    targetPrevious = (Target)mazeTargets[i - 1];
                    Pen temp = taskPanDirection[targetPrevious.ID - 1];
                    temp.CustomEndCap = new AdjustableArrowCap(size / 2, size / 2);
                    Vector2D arcDir = new Vector2D(new Point2D(targetPrevious.X, targetPrevious.Y), new Point2D(target.X, target.Y));
                    arcDir.Normalize();

                    mazeBitmapGraphics.DrawLine(temp, targetPrevious.X, targetPrevious.Y, target.X, target.Y);
                }
            }*/

            foreach (MazeVictim victim in mazeVictims)
            {
                mazeBitmapGraphics.FillEllipse(victimBrush, victim.position.X - sizeOffset / 2, victim.position.Y - sizeOffset, size / 2, size);
            }
            if (objectSelectorTabControl.SelectedTab == graphTabPage && mazeRooms != null)
            {
                foreach (MazeSpace room in mazeRooms)
                    DrawRoom(room, false);
                foreach (MazeNode node in mazeGraph.MazeGraphNodes)
                {
                    if (node.Door != null)
                        mazeBitmapGraphics.FillEllipse(graphBrush, (float)node.position.x - sizeOffset, (float)node.position.y - sizeOffset, size, size);
                    else
                        mazeBitmapGraphics.FillEllipse(graphBrush, (float)node.position.x - sizeOffset * 2, (float)node.position.y - sizeOffset * 2, size * 2, size * 2);
                }
                if (graphTreeView.SelectedNode != null && graphTreeView.SelectedNode.Tag as MazeArc != null)
                {
                    MazeArc arc = graphTreeView.SelectedNode.Tag as MazeArc;
                    mazeBitmapGraphics.DrawLine(selectedGraphPen, (float)arc.from.position.x, (float)arc.from.position.y, (float)arc.to.position.x, (float)arc.to.position.y);
                    MazeNode node = graphTreeView.SelectedNode.Parent.Tag as MazeNode;
                    mazeBitmapGraphics.DrawEllipse(selectedGraphPen, (float)node.position.x - sizeOffset, (float)node.position.y - sizeOffset, size, size);
                }
                if (graphTreeView.SelectedNode != null && graphTreeView.SelectedNode.Tag as MazeNode != null)
                {
                    MazeNode node = graphTreeView.SelectedNode.Tag as MazeNode;
                    mazeBitmapGraphics.DrawEllipse(selectedGraphPen, (float)node.position.x - sizeOffset, (float)node.position.y - sizeOffset, size, size);
                }

                foreach (MazeArc arc in mazeGraph.MazeGraphArcs)
                {
                    graphPen.CustomEndCap = new AdjustableArrowCap(size / 2, size / 2);
                    graphPen.CustomStartCap = new AdjustableArrowCap(1, size / 2);
                    Vector2D arcDir = new Vector2D(arc.from.position, arc.to.position);
                    arcDir.Normalize();
                    Point2D from = arc.from.position.GetTranslatedPoint(arcDir * (arc.from.Door == null ? size : size / 2));
                    arcDir.Inverse();
                    Point2D to = arc.to.position.GetTranslatedPoint(arcDir * (arc.to.Door == null ? size : size / 2));

                    if (true)
                        mazeBitmapGraphics.DrawString(arc.Weight.ToString(), fontGraph, robotBrushSelected, (float)((arc.from.position.x + arc.to.position.x) / 2), (float)((arc.from.position.y + arc.to.position.y) / 2));

                    mazeBitmapGraphics.DrawLine(graphPen, from, to);
                }
            }
            if (objectSelectorTabControl.SelectedTab == roomsTabPage && mazeRooms != null)
            {
                foreach (MazeSpace room in mazeRooms)
                {
                    DrawRoom(room, false);
                }
                if (roomsTreeView.SelectedNode != null)
                {
                    if (roomsTreeView.SelectedNode.Tag as MazeSpace != null)
                    {
                        DrawRoom(roomsTreeView.SelectedNode.Tag as MazeSpace, true);
                    }
                    else if (roomsTreeView.SelectedNode.Tag as MazeWall != null)
                    {
                        DrawRoom(roomsTreeView.SelectedNode.Parent.Tag as MazeSpace, true);
                        MazeWall door = roomsTreeView.SelectedNode.Tag as MazeWall;
                        mazeBitmapGraphics.DrawLine(selectedDoorPen, door.points[0], door.points[1]);
                    }

                    foreach (MazeWall door in mazeWalls)
                    {
                        if (door.MazeWallType != MazeWallType.gate)
                            continue;

                        Vector2D v = new Vector2D(door.points[0], door.points[1]);
                        v.MakePerpendicular();
                        v.Length = 20;
                        if (door.MazeDoorType == MazeGateType.door)
                        {
                            mazeBitmapGraphics.DrawLine(doorPenWithArrow, door.Center, door.Center.GetTranslatedPoint(v));
                            v.Inverse();
                            mazeBitmapGraphics.DrawLine(doorPenWithArrow, door.Center, door.Center.GetTranslatedPoint(v));
                        }
                        else if (door.MazeDoorType == MazeGateType.passage)
                        {
                            mazeBitmapGraphics.DrawLine(passagePenWithArrow, door.Center, door.Center.GetTranslatedPoint(v));
                            v.Inverse();
                            mazeBitmapGraphics.DrawLine(passagePenWithArrow, door.Center, door.Center.GetTranslatedPoint(v));
                        }
                        else if (door.MazeDoorType == MazeGateType.doorOneWayFromTo || door.MazeDoorType == MazeGateType.doorOneWayToFrom)      //draw direction
                        {
                            bool pointsIn = Math.Abs(v.AngleBetween(new Vector2D(door.Center, door.RoomFrom.CenterPoint))) < Math.PI / 2;
                            if ((!pointsIn && door.MazeDoorType == MazeGateType.doorOneWayToFrom) ||
                                (pointsIn && door.MazeDoorType == MazeGateType.doorOneWayFromTo))
                                v.Inverse();
                            mazeBitmapGraphics.DrawLine(doorPenWithArrow, door.Center, door.Center.GetTranslatedPoint(v));
                        }
                    }
                }

            }

            DrawStatic();

            mazeGraphics.DrawImage(mazePanelBitmap, 0, 0);
        }
Beispiel #4
0
 public static double Angle(Vector2D a, Vector2D b)
 {
     return Math.Acos(a * b / a.Length / b.Length);
 }