Ejemplo n.º 1
0
inline void ExpandNodeFromNode(struct Map * themap,struct Path * route,unsigned int from_node,unsigned int to_node,unsigned char current_heading,unsigned int turning_penalty)
{
  unsigned int x=from_node % themap->world_size_x; // Ypologizoume tin syntetagmeni x , y
  unsigned int y=from_node / themap->world_size_x; // Ypologizoume tin syntetagmeni x , y

  unsigned int new_heuristic=ManhattanDistance(x,y,route->target_x,route->target_y);
  unsigned int new_movement_cost=ManhattanDistance(x,y,route->target_x,route->target_y);
  unsigned int new_score=themap->world[to_node].movement_cost+themap->world[to_node].heuristic;//=themap->world[from_node].score;

  unsigned int turning_movement_overhead=GetHeadingChangeOverhead(current_heading,themap->world[from_node].arrived_direction);

  new_movement_cost=themap->world[from_node].movement_cost + turning_movement_overhead + GetHeadingMovementOverhead(current_heading);
  new_score = new_movement_cost + new_heuristic;

  if ((new_score<themap->world[to_node].score) ||  (themap->world[to_node].score==0) )
    {
      //Antikathistoume ton parent tou komvou to_node me ton from_node afou yparxei kalytero monopati!..!
      themap->world[to_node].parent_node = from_node;
      themap->world[to_node].score = new_score;
      themap->world[to_node].movement_cost=new_movement_cost;
      themap->world[to_node].heuristic=new_heuristic;
      themap->world[to_node].arrived_direction = current_heading;
    }

}
Ejemplo n.º 2
0
	/** Search a sub-tree for the element nearest to a given point */
	node_distance FindNearestRecursive(CoordT xy[2], size_t node_idx, int level) const
	{
		/* Dimension index of current level */
		int dim = level % 2;
		/* Node reference */
		const node &n = this->nodes[node_idx];

		/* Coordinate of element splitting at this node */
		CoordT c = this->xyfunc(n.element, dim);
		/* This node's distance to target */
		DistT thisdist = ManhattanDistance(n.element, xy[0], xy[1]);
		/* Assume this node is the best choice for now */
		node_distance best = std::make_pair(n.element, thisdist);

		/* Next node to visit */
		size_t next = (xy[dim] < c) ? n.left : n.right;
		if (next != INVALID_NODE) {
			/* Check if there is a better node down the tree */
			best = SelectNearestNodeDistance(best, this->FindNearestRecursive(xy, next, level + 1));
		}

		/* Check if the distance from current best is worse than distance from target to splitting line,
		 * if it is we also need to check the other side of the split. */
		size_t opposite = (xy[dim] >= c) ? n.left : n.right; // reverse of above
		if (opposite != INVALID_NODE && best.second >= abs((int)xy[dim] - (int)c)) {
			node_distance other_candidate = this->FindNearestRecursive(xy, opposite, level + 1);
			best = SelectNearestNodeDistance(best, other_candidate);
		}

		return best;
	}
Ejemplo n.º 3
0
void COORD::UnitTest()
{
    assert(COORD(3, 3) + COORD(2, 2) == COORD(5, 5));
    COORD coord(5, 2);
    coord += COORD(2, 5);
    assert(coord == COORD(7, 7));
    assert(COORD(2, 2) + North == COORD(2, 3));
    assert(COORD(2, 2) + East == COORD(3, 2));
    assert(COORD(2, 2) + South == COORD(2, 1));
    assert(COORD(2, 2) + West == COORD(1, 2));
    assert(Compass[E_NORTH] == North);
    assert(Compass[E_EAST] == East);
    assert(Compass[E_WEST] == West);
    assert(Compass[E_SOUTH] == South);
    assert(Clockwise(E_NORTH) == E_EAST);
    assert(Clockwise(E_EAST) == E_SOUTH);
    assert(Clockwise(E_SOUTH) == E_WEST);
    assert(Clockwise(E_WEST) == E_NORTH);
    assert(Opposite(E_NORTH) == E_SOUTH);
    assert(Opposite(E_EAST) == E_WEST);
    assert(Opposite(E_SOUTH) == E_NORTH);
    assert(Opposite(E_WEST) == E_EAST);
    assert(Anticlockwise(E_NORTH) == E_WEST);
    assert(Anticlockwise(E_EAST) == E_NORTH);
    assert(Anticlockwise(E_SOUTH) == E_EAST);
    assert(Anticlockwise(E_WEST) == E_SOUTH);
    assert(ManhattanDistance(COORD(3, 2), COORD(-4, -7)) == 16);
    assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_NORTH) == -9);
    assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_EAST) == -7);
    assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_SOUTH) == 9);
    assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_WEST) == 7);
}
Ejemplo n.º 4
0
Archivo: 8a.cpp Proyecto: gittan/8a
 int DistanceTo(const State& goal) const {
     int total_distance = 0;
     for (int goal_cell = 0; goal_cell < N; ++goal_cell) {
         const int v = goal.a_[goal_cell];
         int our_cell = 0;
         for (; our_cell < N && a_[our_cell] != v; ++our_cell) {
         }
         total_distance += ManhattanDistance(goal_cell, our_cell);
     }
     return total_distance;
 }
Ejemplo n.º 5
0
AStarNode::AStarNode(sf::Vector2f position, sf::Vector2f goal, int moveCost, AStarNode *parent)
	:m_position(position), m_goal(goal), m_parent(parent), m_moveCost(moveCost)
{
	// Set G value
	if(m_parent)
	{
		m_G = m_parent->GetG()+moveCost;
	}
	else
	{
		m_G = moveCost;
	}

	// Set H value
	m_H = ManhattanDistance(m_position, m_goal);
}
Ejemplo n.º 6
0
float AStar::HeuristicDistance(Vector StartPos, Vector EndPos)
{
	// Seems like HEURISTIC_EUCLIDEAN == HEURISTIC_DISTANCE
	if(Heuristic == HEURISTIC_EUCLIDEAN)
	{
		return EuclideanDistance(StartPos, EndPos);
	}
	else if(Heuristic == HEURISTIC_DISTANCE)
	{
		return (StartPos - EndPos).Length();
	}
	else if(Heuristic == HEURISTIC_CUSTOM)
	{
		//gLua->PushReference(HeuristicRef);
			//GMOD_PushVector(StartPos);
			//GMOD_PushVector(EndPos);
		//gLua->Call(2, 1);
		//return gLua->GetNumber(1);
	}
	return ManhattanDistance(StartPos, EndPos);
}
Ejemplo n.º 7
0
bool
RasterMap::FirstIntersection(const GeoPoint &origin, const int h_origin,
                             const GeoPoint &destination, const int h_destination,
                             const int h_virt, const int h_ceiling,
                             const int h_safety,
                             GeoPoint &intx, int &h) const
{
  const auto c_origin = projection.ProjectCoarse(origin);
  const auto c_destination = projection.ProjectCoarse(destination);
  const int c_diff = c_origin.ManhattanDistance(c_destination);
  const bool can_climb = (h_destination< h_virt);

  intx = destination; h = h_destination; // fallback, pass
  if (c_diff==0) {
    return false; // no distance
  }

  const int slope_fact = (((int)h_virt) << RASTER_SLOPE_FACT) / c_diff;
  const int vh_origin = std::max(h_origin,
                                 h_destination
                                 - ((c_diff * slope_fact) >> RASTER_SLOPE_FACT));

  RasterLocation c_int;
  if (raster_tile_cache.FirstIntersection(c_origin.x, c_origin.y,
                                          c_destination.x, c_destination.y,
                                          vh_origin, h_destination,
                                          slope_fact, h_ceiling, h_safety,
                                          c_int, h,
                                          can_climb)) {
    bool changed = c_int != c_destination ||
      (h > h_destination && c_int == c_destination);
    if (changed) {
      intx = projection.UnprojectCoarse(c_int);
      assert(h>= h_origin);
    }
    return changed;
  } else {
    return false;
  }
}
Ejemplo n.º 8
0
GeoPoint
RasterMap::Intersection(const GeoPoint& origin,
                        const int h_origin, const int h_glide,
                        const GeoPoint& destination,
                        const int height_floor) const
{
  const auto c_origin = projection.ProjectCoarseRound(origin);
  const auto c_destination = projection.ProjectCoarseRound(destination);
  const int c_diff = ManhattanDistance(c_origin, c_destination);
  if (c_diff == 0)
    return GeoPoint::Invalid();

  const int slope_fact = (((int)h_glide) << RASTER_SLOPE_FACT) / c_diff;

  auto c_int =
    raster_tile_cache.Intersection(c_origin, c_destination,
                                   h_origin, slope_fact, height_floor);
  if (c_int.x < 0)
    return GeoPoint::Invalid();

  return projection.UnprojectCoarse(c_int);
}
Ejemplo n.º 9
0
GeoPoint
RasterMap::Intersection(const GeoPoint& origin,
                        const int h_origin, const int h_glide,
                        const GeoPoint& destination) const
{
  const auto c_origin = projection.ProjectCoarse(origin);
  const auto c_destination = projection.ProjectCoarse(destination);
  const int c_diff = c_origin.ManhattanDistance(c_destination);
  if (c_diff==0) {
    return destination; // no distance
  }
  const int slope_fact = (((int)h_glide) << RASTER_SLOPE_FACT) / c_diff;

  auto c_int =
    raster_tile_cache.Intersection(c_origin.x, c_origin.y,
                                   c_destination.x, c_destination.y,
                                   h_origin, slope_fact);

  if (c_int == c_destination) // made it to grid location, return exact location
                              // of destination
    return destination;

  return projection.UnprojectCoarse(c_int);
}
Ejemplo n.º 10
0
static unsigned
_PolygonToTriangles(const PT *points, unsigned num_points,
                    GLushort *triangles, typename PT::scalar_type min_distance)
{
  // no redundant start/end please
  if (num_points >= 1 && points[0] == points[num_points - 1])
    num_points--;

  if (num_points < 3)
    return 0;

  assert(num_points < 65536);
  // next vertex pointer
  auto next = new GLushort[num_points];
  // index of the first vertex
  GLushort start = 0;

  // initialize next pointer counterclockwise
  if (PolygonRotatesLeft(points, num_points)) {
    for (unsigned i = 0; i < num_points-1; i++)
      next[i] = i + 1;
    next[num_points - 1] = 0;
  } else {
    next[0] = num_points - 1;
    for (unsigned i = 1; i < num_points; i++)
      next[i] = i - 1;
  }

  // thinning
  if (min_distance > 0) {
    for (unsigned a = start, b = next[a], c = next[b], heat = 0;
         num_points > 3 && heat < num_points;
         a = b, b = c, c = next[c], heat++) {
      bool point_removeable = TriangleEmpty(points[a], points[b], points[c]);
      if (!point_removeable) {
        typename PT::scalar_type distance = ManhattanDistance(points[a],
                                                              points[b]);
        if (distance < min_distance) {
          point_removeable = true;
          if (distance > 0) {
            for (unsigned p = next[c]; p != a; p = next[p]) {
              if (InsideTriangle(points[p], points[a], points[b], points[c])) {
                point_removeable = false;
                break;
              }
            }
          }
        }
      }
      if (point_removeable) {
        // remove node b from polygon
        if (b == start)
          // keep track of the smallest index
          start = std::min(a, c);

        next[a] = c;
        num_points--;
        // 'a' should stay the same in the next loop
        b = a;
        // reset heat
        heat = 0;
      }
    }
    //LogDebug(_T("polygon thinning (%u) removed %u of %u vertices"),
    //         min_distance, orig_num_points-num_points, orig_num_points);
  }

  // triangulation
  auto t = triangles;
  for (unsigned a = start, b = next[a], c = next[b], heat = 0;
       num_points > 2; a = b, b = c, c = next[c]) {
    typename PT::product_type bendiness =
      LeftBend(points[a], points[b], points[c]);

    // left bend, spike or line with a redundant point in the middle
    bool ear_cuttable = (bendiness >= 0);

    if (bendiness > 0) {
      // left bend
      for (unsigned prev_p = c, p = next[c]; p != a;
           prev_p = p, p = next[p]) {
        typename PT::product_type ab = PointLeftOfLine(points[p], points[a],
                                                       points[b]);
        typename PT::product_type bc = PointLeftOfLine(points[p], points[b],
                                                       points[c]);
        typename PT::product_type ca = PointLeftOfLine(points[p], points[c],
                                                       points[a]);
        if (ab > 0 && bc > 0 && ca > 0) {
          // p is inside a,b,c
          ear_cuttable = false;
          break;
        } else if (ab >= 0 && bc >= 0 && ca >= 0) {
          // p is on one or two edges of a,b,c
          bool outside_ab = (ab == 0) &&
            PointLeftOfLine(points[prev_p], points[a], points[b]) <= 0;
          bool outside_bc = (bc == 0) &&
            PointLeftOfLine(points[prev_p], points[b], points[c]) <= 0;
          bool outside_ca = (ca == 0) &&
            PointLeftOfLine(points[prev_p], points[c], points[a]) <= 0;
          if (!(outside_ab || outside_bc || outside_ca)) {
            // line p,prev_p intersects with triangle a,b,c
            ear_cuttable = false;
            break;
          }

          outside_ab = (ab == 0) &&
            PointLeftOfLine(points[next[p]], points[a], points[b]) <= 0;
          outside_bc = (bc == 0) &&
            PointLeftOfLine(points[next[p]], points[b], points[c]) <= 0;
          outside_ca = (ca == 0) &&
            PointLeftOfLine(points[next[p]], points[c], points[a]) <= 0;
          if (!(outside_ab || outside_bc || outside_ca)) {
            // line p,next[p] intersects with triangle a,b,c
            ear_cuttable = false;
            break;
          }
        }
      }
      if (ear_cuttable) {
        // save triangle indices
        *t++ = a;
        *t++ = b;
        *t++ = c;
      }
    }

    if (ear_cuttable) {
      // remove node b from polygon
      next[a] = c;
      num_points--;
      // 'a' should stay the same in the next loop
      b = a;
      // reset heat
      heat = 0;
    }

    if (heat++ > num_points) {
      // if polygon edges overlap we may loop endlessly
      //LogDebug(_T("polygon_to_triangle: bad polygon"));
      delete[] next;
      return 0;
    }
  }

  delete[] next;
  return t - triangles;
}
Ejemplo n.º 11
0
void inline OpenNode(struct Map * themap,struct Path * route,unsigned int parent_node,unsigned int the_node)
{
  if ( ( !themap->world[the_node].opened ) && (themap->world[the_node].unpassable==0) && (themap->world[the_node].in_unpassable_radious==0) )
    {
      if (route->openlist_top+1<route->openlist_size)
        {
          themap->world[the_node].opened=1;

          // ADDING NEW NODE TO PENDING LIST!
          route->openlist[route->openlist_top].node = the_node;
          unsigned int x=parent_node % themap->world_size_x; // Ypologizoume tin syntetagmeni x , y
          unsigned int y=parent_node / themap->world_size_x; // Ypologizoume tin syntetagmeni x , y
          route->openlist[route->openlist_top].score = themap->world[the_node].movement_cost+ManhattanDistance(x,y,route->target_x,route->target_y);

          ++route->openlist_top;
          // WE HEAVE SUCCESSFULLY ADDED THE NEW NODE TO THE TAIL OF THE OPENLIST
        }
      else
        {
          fprintf(stderr,"Out of space on open list , lets hope open nodes have a solution ( it might not be optimal )!!!\n");
          /* Mas teleiwse o xoros.. krima.. as elpisoume oti ta open nodes exoun lysi!! */
        }
    }
}
Ejemplo n.º 12
0
bool
XShape::BuildIndices(unsigned thinning_level, ShapeScalar min_distance)
{
  assert(indices[thinning_level] == nullptr);

  unsigned short *idx, *idx_count;
  unsigned num_points = 0;

  for (unsigned i=0; i < num_lines; i++)
    num_points += lines[i];

  if (type == MS_SHAPE_LINE) {
    if (num_points <= 2)
      return false;  // line cannot be simplified, so don't create indices
    index_count[thinning_level] = idx_count =
      new GLushort[num_lines + num_points];
    indices[thinning_level] = idx = idx_count + num_lines;

    const unsigned short *end_l = lines + num_lines;
    const ShapePoint *p = points;
    unsigned i = 0;
    for (const unsigned short *l = lines; l < end_l; l++) {
      assert(*l >= 2);
      const ShapePoint *end_p = p + *l - 1;
      // always add first point
      *idx++ = i;
      p++; i++;
      const unsigned short *after_first_idx = idx;
      // add points if they are not too close to the previous point
      for (; p < end_p; p++, i++)
        if (ManhattanDistance(points[idx[-1]], *p) >= min_distance)
          *idx++ = i;
      // remove points from behind if they are too close to the end point
      while (idx > after_first_idx &&
             ManhattanDistance(points[idx[-1]], *p) < min_distance)
        idx--;
      // always add last point
      *idx++ = i;
      p++; i++;
      *idx_count++ = idx - after_first_idx + 1;
    }
    // TODO: free memory saved by thinning (use malloc/realloc or some class?)
    return true;
  } else if (type == MS_SHAPE_POLYGON) {
    index_count[thinning_level] = idx_count =
      new GLushort[1 + 3*(num_points-2) + 2*(num_lines-1)];
    indices[thinning_level] = idx = idx_count + 1;

    *idx_count = 0;
    const ShapePoint *pt = points;
    for (unsigned i=0; i < num_lines; i++) {
      unsigned count = PolygonToTriangles(pt, lines[i], idx + *idx_count,
                                          min_distance);
      if (i > 0) {
        const GLushort offset = pt - points;
        const unsigned max_idx_count = *idx_count + count;
        for (unsigned j=*idx_count; j < max_idx_count; j++)
          idx[j] += offset;
      }
      *idx_count += count;
      pt += lines[i];
    }
    *idx_count = TriangleToStrip(idx, *idx_count, num_points, num_lines);
    // TODO: free memory saved by thinning (use malloc/realloc or some class?)
    return true;
  } else {
    gcc_unreachable();
  }
}