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); }
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)); }
public override float GetMinDistance(Vec3 from) { return(HintPos.IsZero() ? 0 : from.Distance(HintPos)); }
public override float GetMinDistance(Vec3 from) { return(from.Distance(Dest)); }
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); }