Beispiel #1
0
        /// <summary>
        /// A function for adding an edge to the graph. A node will be created when it does not exist.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        /// <param name="cost"></param>
        public void AddEdge(Vector2D source, Vector2D destination, double cost = 1)
        {
            var v = GetNode(source, create: true);
            var w = GetNode(destination, create: true);

            v.Adjacent.Add(new Edge(w, cost));
        }
Beispiel #2
0
        public void Draw(Graphics g)
        {
            Pen p = new Pen(Color.Gray, .5f);
            var grid = new List<Vector2D>();

            var cellSize = height / (height / this.cellSize);

            for (int i = 0; i < width / this.cellSize; i++)
            {
                var vHorizontal = new Vector2D(0, height);
                var vVertical = new Vector2D(width, 0);

                vHorizontal *= Matrix.Translate(0, this.cellSize * i);
                vVertical *= Matrix.Translate(this.cellSize * i, 0);

                grid.Add(vHorizontal);
                grid.Add(vVertical);
            }

            var rowY = 0;
            var rowX = 0;
            foreach (Vector2D v in grid)
            {
                if (grid.IndexOf(v) % 2 == 0)
                {
                    g.DrawLine(p, v.x, rowY, v.x + width, rowY);
                    rowY += cellSize;
                }
                else
                {
                    g.DrawLine(p, rowX, v.y, rowX, v.y + height);
                    rowX += cellSize;
                }
            }
        }
        public Vector2D Calculate()
        {
            //Used to record the average heading of the neighbours
            Vector2D AverageHeading = new Vector2D();

            var neighbours = this.MovingEntity.GetNeighbours(true);

            int neighbourCount = 0;

            foreach(IMovingEntity neighbour in neighbours)
            {
                //Make sure *this* agent isn't included in the calculations and that
                //the agent being examind is close enough
                if(neighbour != this.MovingEntity)
                {
                    AverageHeading += neighbour.GetHeading();
                    ++neighbourCount;
                }
            }

            //If the neighbourhood contained one or more vehicles, average their
            //heading vectors.
            if(neighbourCount > 0)
            {
                AverageHeading /= (float)neighbourCount;
                AverageHeading -= this.MovingEntity.GetHeading();
            }

            return AverageHeading;
        }
        public Vector2D Calculate()
        {
            //First find the centre of mass of all the agents
            Vector2D centerOfMass = new Vector2D();
            Vector2D steeringForce = new Vector2D();

            int NeighbourCount = 0;

            //iterate through the neighbours and sum up all the position vectors
            foreach (IMovingEntity neighbour in this.MovingEntity.GetNeighbours(true))
            {
                //Make sure *this* agent isn't included in the calculations and that
                //the agent begint examined is a neigbour
                if (neighbour != this.MovingEntity)
                {
                    centerOfMass += neighbour.GetPosition();
                    ++NeighbourCount;
                }
            }

            if (NeighbourCount > 0)
            {
                //The center of mass is the average of the sum of positions
                centerOfMass /= (float)NeighbourCount;

                //now Seek toward that position
                steeringForce = new Seek(this.MovingEntity, centerOfMass).Calculate();
            }

            return steeringForce;
        }
        public Vector2D Calculate()
        {
            var neighbours = MovingEntity.GetNeighbours(true);
            Vector2D SteeringForce = new Vector2D();

            foreach (IMovingEntity neighbour in neighbours)
            {
                //Make sure this agent ins't included in the calculations
                //and that the agent being examind is close enough
                if (neighbour != this.MovingEntity)
                {
                    Vector2D ToAgent = this.MovingEntity.GetPosition() - neighbour.GetPosition();

                    //Scale the force inversely proportional to the agent's distance
                    //from its neighbour
                    var temp = ToAgent.Normalize() / ToAgent.GetLength();

                    //temp x and y are NaN if two entities are on the exact same location.
                    if (!(float.IsNaN(temp.x) || float.IsNaN(temp.y)))
                        SteeringForce += temp;
                }
            }

            return SteeringForce;
        }
Beispiel #6
0
        public Vector2D Calculate()
        {
            Vector2D ToTarget = TargetPosition - this.MovingEntity.GetPosition();

            //Calculate the distance to the target position.
            double distance = ToTarget.GetLength();

            if (distance > 0)
            {
                //Because the decleration is enumerated as an int, this value is
                //required to provide fin tweaking of the decleration.
                const double DeclerationTweaker = 220;

                //Calculate the speed required to reach the target given the
                //desired decleration.
                double speed = distance / ((double)Decleration.normal * DeclerationTweaker);

                //Make sure the velocity does not exceed the max
                if (speed > this.MovingEntity.GetMaxSpeed())
                    speed = this.MovingEntity.GetMaxSpeed();

                //From here proceed just like Seek except we don't need to normalize the TargetPosition Vector,
                //because we have already gone to the trouble of calculating its lenght: distance;
                DesiredVelocity = ToTarget * (float)speed / (float)distance;

                return (DesiredVelocity - this.MovingEntity.GetVelocity());
            }

            return new Vector2D();
        }
        public void GetLengthTest()
        {
            Vector2D v1 = new Vector2D(100, 200);

            var length = v1.GetLength();

            Assert.AreEqual(223.6068, Math.Round(length * 10000) / 10000);
        }
        public void NormalizeTest()
        {
            Vector2D v1 = new Vector2D(100, 200);

            var normalizedVector = v1.Normalize();
            Assert.AreEqual(0.447, Math.Round(normalizedVector.x * 1000) / 1000);
            Assert.AreEqual(0.894, Math.Round(normalizedVector.y * 1000) / 1000);
        }
        public void PerpendicularTest()
        {
            Vector2D v1 = new Vector2D(100, 200);
            Vector2D perp = v1.Perpendicular();

            Assert.AreEqual(200, perp.x);
            Assert.AreEqual(-100, perp.y);
        }
        public void TruncateTest()
        {
            Vector2D v1 = new Vector2D(100, 200);

            v1.Truncate(99);
            Assert.AreEqual(44.27, Math.Round(v1.x * 100) / 100);
            Assert.AreEqual(88.55, Math.Round(v1.y * 100) / 100);
        }
        public void VectorMultiplyTest()
        {
            Vector2D v1 = new Vector2D(100, 200);
            Vector2D result = v1 * 20;

            Assert.AreEqual(2000, result.x);
            Assert.AreEqual(4000, result.y);
        }
        public WallEntity(Vector2D point1, Vector2D point2)
            : base(point1 - point2)
        {
            this.Point1 = point1;
            this.Point2 = point2;

            this.Normal = CalculateNormal();
        }
        public Vector2D Calculate()
        {
            Vector2D vector = new Vector2D();

            foreach (ISteeringBehaviour behaviour in this.Behaviours)
                vector += behaviour.Calculate();

            return vector;
        }
        public HumanWhoLostItsContacts(Vector2D position)
            : base(position)
        {
            this.MaxSpeed = 0.1f;
            this.Scale = 50f;
            this.ViewDistance = 200f;

            this.SteeringBehaviour.AddSteeringBehaviour(new WallAvoidance(this, World.Instance.Walls));
        }
        public JeepEntity(Vector2D position)
            : base(position)
        {
            this.MaxSpeed = 0.3f;
            this.Scale = 50f;
            this.ViewDistance = 200f;
            this.CurrentGoal = new FollowPath(this, PathFactory.GetJeepPath());

            this.SteeringBehaviour.AddSteeringBehaviour(new Separation(this));
        }
Beispiel #16
0
        public Vector2D Calculate()
        {
            Vector2D steeringForce = new Vector2D();

            steeringForce += (seperation.Calculate() * seperationMultiplier);
            steeringForce += (cohesion.Calculate() * cohesionMultiplier);
            steeringForce += (alignment.Calculate() * alignmentMultiplier);

            return steeringForce;
        }
Beispiel #17
0
 public Vector2D Normalize()
 {
     Vector2D v1 = new Vector2D();
     float length = this.GetLength();
     if (length != 0)
     {
         v1.x = this.x / length;
         v1.y = this.y / length;
     }
     return v1;
 }
        public LionEntity(Vector2D position)
            : base(position, 1, 1)
        {
            this.Mass = 300f;
            this.MaxSpeed = .1f;
            this.ViewDistance = 100;
            this.Carnivore = true;
            this.Scale = 50;

            this.SteeringBehaviour.AddSteeringBehaviour(new WallAvoidance(this, World.Instance.Walls));
            this.SteeringBehaviour.AddSteeringBehaviour(new Flee(this, 50));
        }
Beispiel #19
0
        public override void Activate()
        {
            Status = Goal_Status.ACTIVE;
            RemoveAllSubGoals();
            if (!destinationIsSet)
            {
                currentDestination = new Vector2D(50, 50);
                destinationIsSet = true;
            }

            AddSubGoal(new MoveToPosition(Owner, currentDestination));
        }
        public Vector2D Calculate()
        {
            //A list of feelers. The feelers are like the whiskers of a cat.
            var feelers = CreateFeelers(movingEntity);

            double distanceToThisIP = 0.0;
            double distanceToClosestIP = Double.MaxValue;

            //This will hold an index into the vector of walls
            int closestWall = -1;

            Vector2D steeringForce = new Vector2D();
            Vector2D point = new Vector2D();
            Vector2D closestPoint = new Vector2D();

            //Examine each feeler in turn
            for (int flr = 0; flr < feelers.Count(); flr++)
            {
                //Run through each wall checking for any intersection points
                for (int w = 0; w < walls.Count; w++)
                {
                    //If the vehicle intersects with the line
                    if (LineIntersection(this.movingEntity.GetPosition(), feelers[flr], walls[w].From(), walls[w].To(), out distanceToThisIP, out point))
                    {
                        //Is this the closest found so far? If so keep a reord
                        if (distanceToThisIP < distanceToClosestIP)
                        {
                            distanceToClosestIP = distanceToThisIP;
                            closestPoint = point;
                            closestWall = w;
                        }
                    }

                } // next wall

                //If an intersection point has been detected, calculate a force
                //that will direct the agent away
                if (closestWall >= 0)
                {
                    //Calculate by what distance the projected position of the agent
                    //will overshoot the wall
                    Vector2D overShoot = feelers[flr] - closestPoint;

                    //Create a force in the direction of the wall normal, with a
                    //magnitude of the overshoot
                    steeringForce += walls[closestWall].Normal() * overShoot.GetLength();
                }

            } // next feeler

            return steeringForce;
        }
Beispiel #21
0
        public static bool LineIntersectsWithCirlce(Vector2D circlePosition, float circleRadius, Vector2D point1, Vector2D point2)
        {
            //Distance from point1 to the middle of the circle
            float distanceToPoint1 = Distance(circlePosition, point1);

            //Distance from point2 to the middle of the circle
            float distanceToPoint2 = Distance(circlePosition, point2);

            if (distanceToPoint1 < circleRadius || distanceToPoint2 < circleRadius)
                return true;

            return false;
        }
Beispiel #22
0
        /// <summary>
        /// Het Dijkstra-algoritme kan alleen gebruikt worden wanneer er geen negatieve paden aanwezig zijn.
        /// Zodra deze wel aanwezig zijn zal deze functie in een oneindige lus blijven hangen.
        /// </summary>
        /// <param name="startName">Het punt waar vanuit de korste routes berekent moeten worden.</param>
        /// <returns>Returns all the considered positions</returns>
        public List<Vector2D> DijkstraWithManhattan(Vector2D startPosition, Vector2D endPosition)
        {
            MinHeap<Path> minHeap = new MinHeap<Path>();
            Node startNode = FindClosestNode(startPosition);
            Node endNode = FindClosestNode(endPosition);

            List<Vector2D> considerdPositions = new List<Vector2D>();

            clearAll();
            startNode.Distance = 0 + GetManhattanValue(startNode.Position, endNode.Position);
            minHeap.Insert(new Path(startNode, startNode.Distance));
            int nodeSeen = 0;
            while (minHeap.Count != 0 && nodeSeen < nodeMap.Count)
            {
                Path vrec = minHeap.ExtractMin();
                Node v = vrec.Destination;

                if (v.Scratch != 0)
                    continue;
                v.Scratch = 1;
                nodeSeen++;

                foreach (Edge e in v.Adjacent)
                {
                    Node w = e.destination;
                    double cvw = e.cost;
                    if (cvw < 0)
                        throw new Exception("Graph has negative edges.");

                    float heuristic1 = GetManhattanValue(w.Position, endNode.Position);
                    float heuristic2 = GetManhattanValue(v.Position, endNode.Position);

                    if (w.Distance + heuristic1 > v.Distance + heuristic2 + cvw)
                    {
                        w.Distance = v.Distance + heuristic2 + cvw;
                        w.Previous = v;

                        considerdPositions.Add(w.Position);

                        if (w.Position == endNode.Position)
                            return considerdPositions;

                        minHeap.Insert(new Path(w, w.Distance));
                    }
                }
            }

            return considerdPositions;
        }
Beispiel #23
0
        public Vector2D Calculate()
        {
            float rand = (Convert.ToSingle(new Random().Next(-10, 10)) / 10f);
            Vector2D velocity = movingEntity.GetVelocity();

            circleCenter = new Vector2D(velocity.x, velocity.y);
            circleCenter.Normalize();
            circleCenter *= circleDistance;

            displacement = new Vector2D(0, -1);
            displacement *= circleRadius;

            displacement = SetAngle(displacement, displacementAngle);

            displacementAngle += rand * circleAngleChange - circleAngleChange * .5f;
            wanderForce = circleCenter + displacement;
            return wanderForce;
        }
Beispiel #24
0
        public void Draw(Graphics g)
        {
            Pen p = new Pen(Color.Red, 5f);

            var pentagon = new List<Vector2D>();

            float c1 = Convert.ToSingle(Math.Cos((2 * Math.PI) / 5));
            float c2 = Convert.ToSingle(Math.Cos(Math.PI / 5));
            float s1 = Convert.ToSingle(Math.Sin((2 * Math.PI / 5)));
            float s2 = Convert.ToSingle(Math.Sin((4 * Math.PI) / 5));

            var vA = new Vector2D(1, 0);
            var vB = new Vector2D(c1, s1);
            var vC = new Vector2D(-c2, s2);
            var vD = new Vector2D(-c2, -s2);
            var vE = new Vector2D(c1, -s1);

            Matrix rotationMatrix = Matrix.Rotate(Rotation);
            pentagon.Add((vA * Scale) * rotationMatrix);
            pentagon.Add((vB * Scale) * rotationMatrix);
            pentagon.Add((vC * Scale) * rotationMatrix);
            pentagon.Add((vD * Scale) * rotationMatrix);
            pentagon.Add((vE * Scale) * rotationMatrix);

            pentagon = Screen.Viewporttranformation(width, height, pentagon);

            for (int i = 0; i < pentagon.Count; i++)
            {
                Vector2D previous;
                Vector2D current = pentagon[i];
                if (i == 0)
                    previous = pentagon[pentagon.Count - 1];
                else
                    previous = pentagon[i - 1];
                g.DrawLine(p, previous.x, previous.y, current.GetWidth(), current.GetHeight());
            }
        }
 public WaterEntity(Vector2D position, float scale = 25, float bradius = 1)
     : base(position, scale, bradius)
 {
     this.Bradius = 150;
 }
 public void DefaultVectorTest()
 {
     Vector2D v1 = new Vector2D(100, 200);
     Assert.AreEqual(100, v1.x);
     Assert.AreEqual(200, v1.y);
 }
 public RockEntity(Vector2D position)
     : base(position, 1, 1)
 {
     Bradius = 50;
 }
        public static Graph GenerateWorldGraph(World world)
        {
            Graph graph = new Graph();

            float maxWidth = World.Width;
            float maxHeight = World.Height;

            int edgeSize = 30;

            //Add a little padding on the edge of the world. We don't want our entities to fall off the world.
            int OffsetX = (World.Width % edgeSize) / 2;
            int OffsetY = (World.Height % edgeSize) / 2;

            for (int y = OffsetY; y < maxHeight; y += edgeSize)
            {
                for (int x = OffsetX; x < maxWidth; x += edgeSize)
                {
                    Vector2D currentPosition = new Vector2D(x, y);

                    var staticObjects = world.GetAllStaticObjects();

                    //Check if new node fits on the world
                    if (currentPosition.x + edgeSize < maxWidth)
                    {
                        Vector2D promissingPoint = new Vector2D(x + edgeSize, y);

                        bool doesIntersect = false;
                        foreach (BaseEntity entity in staticObjects)
                            if (Util.LineIntersectsWithCirlce(entity.Position, entity.Bradius / 2, currentPosition, promissingPoint))
                                doesIntersect = true;

                        if (!doesIntersect)
                        {
                            //Add edges in two directions
                            //  A --> B
                            //  A <-- B
                            graph.AddEdge(currentPosition, promissingPoint);
                            graph.AddEdge(promissingPoint, currentPosition);
                        }
                    }

                    if (currentPosition.y + edgeSize < maxHeight)
                    {
                        Vector2D promissingPoint = new Vector2D(x, y + edgeSize);
                        bool doesIntersect = false;

                        foreach (BaseEntity entity in staticObjects)
                            if (Util.LineIntersectsWithCirlce(entity.Position, entity.Bradius / 2, currentPosition, promissingPoint))
                                doesIntersect = true;

                        if (!doesIntersect)
                        {
                            //Add edges in two directions
                            //  A --> B
                            //  A <-- B
                            graph.AddEdge(currentPosition, promissingPoint);
                            graph.AddEdge(promissingPoint, currentPosition);
                        }
                    }
                }
            }
            return graph;
        }
Beispiel #29
0
 public Vector2D SetAngle(Vector2D v, float number)
 {
     var lenght = v.GetLength();
     return new Vector2D(Convert.ToSingle(Math.Cos(number) * lenght),
                         Convert.ToSingle(Math.Sin(number) * lenght));
 }
Beispiel #30
0
 public Seek(IMovingEntity entity, Vector2D targetPosition)
 {
     this.movingEntity = entity;
     this.TargetPosition = targetPosition;
 }