Exemplo n.º 1
0
        public bool Overlaps(Vec3 circle_center, float radius, bool tangential_ok = false)
        {
            Vec3  center_aligned = Align(circle_center);
            float dist           = circle_center.Distance(center_aligned);

            return(tangential_ok ? dist < radius : dist <= radius);
        }
Exemplo n.º 2
0
        public Vec3 GetRandomPosInRing(Vec3 ring_center, float min_radius, float max_radius)
        {
            var potential_grid_cells = GetCellsOverlappedByCircle(m_GridCells, ring_center, max_radius);

            List <Cell> cells = new List <Cell>();

            foreach (GridCell grid_cell in potential_grid_cells)
            {
                cells.AddRange(grid_cell.Cells.FindAll(x => x.Overlaps(ring_center, max_radius) && !x.AABB.Inside(ring_center, min_radius)));
            }

            Cell random_cell = cells[Rng.Next(cells.Count)];
            Vec3 random_pos  = random_cell.AABB.GetRandomPos();

            float dist = random_pos.Distance(ring_center);

            if (dist > min_radius && dist <= max_radius)
            {
                return(random_pos);
            }

            //align position to ring
            Vec3 dir_to_random_pos = random_pos - ring_center;

            dir_to_random_pos.Normalize();

            random_pos = ring_center + dir_to_random_pos * (min_radius + (float)Rng.NextDouble() * (max_radius - min_radius));
            return(random_cell.AABB.Align(random_pos));
        }
Exemplo n.º 3
0
 public override float GetMinDistance(Vec3 from)
 {
     return(HintPos.IsZero() ? 0 : from.Distance(HintPos));
 }
Exemplo n.º 4
0
 public override float GetMinDistance(Vec3 from)
 {
     return(from.Distance(Dest));
 }
Exemplo n.º 5
0
        public static bool FindPath <T>(T start, ref T end, Vec3 from, Vec3 to, MovementFlag flags, ref List <path_pos> path, float random_coeff = 0, bool allow_disconnected = false) where T : Cell
        {
            if (path != null)
            {
                path.Clear();
            }

            //based on http://en.wikipedia.org/wiki/A*_search_algorithm

            List <NodeInfo> open   = new List <NodeInfo>();
            List <NodeInfo> closed = new List <NodeInfo>();

            Random rng = new Random();

            if (start == null || end == null)
            {
                return(false);
            }

            NodeInfo s = new NodeInfo(start, from, null, 0, from.Distance(to));

            open.Add(s);

            while (open.Count > 0)
            {
                //sort by cost
                float    min_total_cost = open.Min(x => x.TotalCost);
                NodeInfo best           = open.Find(x => x.TotalCost.Equals(min_total_cost));

                open.Remove(best);

                //take node with lower cost from open list
                NodeInfo info = best;

                if (info.cell == end)
                {
                    BuildPath(start, end, from, to, info, ref path);
                    return(true);
                }

                closed.Insert(0, info);

                foreach (Cell.Neighbour neighbour in info.cell.Neighbours)
                {
                    Cell cell_neighbour = neighbour.cell;

                    if (cell_neighbour.Disabled || (neighbour.connection_flags & flags) != flags)
                    {
                        continue;
                    }

                    Vec3 leading_point = neighbour.border_point != null ? neighbour.border_point : cell_neighbour.Center;

                    NodeInfo info_neighbour = GetNodeInfoFromList(cell_neighbour, leading_point, closed);

                    // if already processed then skip this neighbour
                    if (info_neighbour != null)
                    {
                        continue;
                    }

                    float random_dist_mod = -random_coeff + (2 * random_coeff) * (float)rng.NextDouble();

                    float new_g     = info.g + (info.leading_point.IsEmpty ? info.cell.Distance(leading_point) : info.leading_point.Distance(leading_point)) * (1 + random_dist_mod) * info.cell.MovementCostMult;
                    bool  is_better = false;

                    info_neighbour = GetNodeInfoFromList(cell_neighbour, leading_point, open);

                    // if not in open list
                    if (info_neighbour == null)
                    {
                        info_neighbour = new NodeInfo(cell_neighbour, leading_point, null, 0, leading_point.Distance(to) * (1 + random_dist_mod) * info.cell.MovementCostMult);
                        is_better      = true;

                        open.Insert(0, info_neighbour);
                    }
                    else if (new_g < info_neighbour.g)
                    {
                        is_better = true;
                    }

                    if (is_better)
                    {
                        info_neighbour.parent = info;
                        info_neighbour.g      = new_g;
                    }
                }
            }

            if (allow_disconnected && closed.Count > 0)
            {
                float    min_total_cost = closed.Min(x => x.h);
                NodeInfo best           = closed.Find(x => x.h.Equals(min_total_cost));
                end = (T)best.cell;

                BuildPath(start, end, from, to, best, ref path);
                return(true);
            }

            return(false);
        }