int zz::map::distance_between( const zz::map::location& start, const zz::map::location& end ) const {
    if( is_wall( end ) ) return -1; // don't waste time with A* if it's easy to see the end is unreachable

    int g_scores[width() * height()];
    int f_scores[width() * height()];
    int came_from[width() * height()];
    int done[width() * height()];

    // init arrays
    for( int* i = done; i < done + width() * height(); ) {
        ( *i++ ) = false;
    }
    for( int* i = came_from; i < came_from + width() * height(); ) {
        ( *i++ ) = -1;
    }
    for( int* i = g_scores; i < g_scores + width() * height(); ) {
        ( *i++ ) = INT_MAX;
    }
    for( int* i = f_scores; i < f_scores + width() * height(); ) {
        ( *i++ ) = INT_MAX;
    }

    // calc the starting point scores
    g_scores[start.x( ) + width( ) * start.y( )] = 0;
    f_scores[start.x( ) + width( ) * start.y( )] = manhattan_distance( start, end );

    // Use a basic A* implementation to calculate the shortest path
    while( true ) {
        int *min = std::min_element( f_scores, f_scores + width() * height() ); // find the address of the best guess location
        if( ( *min ) == INT_MAX ) {
            break; // nothing left todo
        } else {
            ( *min ) = INT_MAX; // clear that address, so it won't be found again
        }
        int location_index = min - f_scores;
        done[location_index] = true;
        zz::map::location location( location_index % width( ), location_index / width( ) ); // get the location from the address

        if( location == end ) { // found the destination, so reconstruct the path to here
            return zz::map::reconstruct_distance_from( came_from, location_index );
        }

        for( int i = 0; i < 4; ++i ) {
            zz::map::location neighbor = location.adjacent( i );
            int neighbor_index = neighbor.x( ) + width( ) * neighbor.y( );
            if( is_wall( neighbor_index ) || done[neighbor_index] ) {
                continue;
            }

            if( g_scores[location_index] + 1 < g_scores[neighbor_index] ) {
                came_from[neighbor_index] = location_index;
                g_scores[neighbor_index] = g_scores[location_index] + 1;
                f_scores[neighbor_index] = g_scores[neighbor_index] + manhattan_distance( neighbor, end );
            }
        }
    }
    return -1;  // A* could not find a path between start and end
}
double ghost_cost(loc ghost_location, loc amidar_loc) {
    if (ghost_location.first < 20 || ghost_location.first > 160) {
//        cout << "here1" << endl;
        return GHOST_COST / pow(manhattan_distance(ghost_location, amidar_loc), 2);
    }
    else if (ghost_location.second < 20 || ghost_location.second > 138) {
//        cout << "here2" << endl;
//        cout << ghost_location.first << ", " << ghost_location.second << endl;
//        cout << amidar_loc.first << ", " << amidar_loc.second << endl;
        return GHOST_COST / pow(manhattan_distance(ghost_location, amidar_loc), 2);
    }
    else return GHOST_COST / pow(euclidean_distance(ghost_location, amidar_loc), 2);
}
Beispiel #3
0
  /**
   * Call this in the "mouse down" handler.
   *
   * @return true if a double click was detected
   */
  bool Check(RasterPoint _location) {
    const bool result = !clock.CheckAlwaysUpdate(INTERVAL_MS) &&
      manhattan_distance(location, _location) <= MAX_DISTANCE_PX;

    location = _location;
    return result;
  }
    /// Go through the queue of waiting chunks, and add them to the
    /// appropriate data structures.
    //  The renderer should call this from within the OpenGL context.
    std::vector<chunk_coordinates> process_vbo_queue()
    {
        std::vector<chunk_coordinates> processed;

        boost::mutex::scoped_lock l (lock);
        boost::mutex::scoped_lock lock(vbo_queue_lock);

        for (auto& b : vbo_queue)
        {
            unsigned int dist (manhattan_distance(plr_pos_, b.pos));
            if (dist < view_dist_)
            {
                occlusion_queries[dist].erase(b.pos);

                if (b.opaque->empty())
                    opaque_vbos[dist].erase(b.pos);
                else
                    opaque_vbos[dist][b.pos] = b.opaque->make_buffer();

                if (b.transparent->empty())
                    transparent_vbos[dist].erase(b.pos);
                else
                    transparent_vbos[dist][b.pos] = b.transparent->make_buffer();

                processed.push_back(b.pos);
            }
        }
        vbo_queue.clear();

        return processed;
    }
bool
TargetMapWindow::OnMouseMove(PixelScalar x, PixelScalar y, unsigned keys)
{
  switch (drag_mode) {
  case DRAG_NONE:
    break;

  case DRAG_TARGET:
    if (isInSector(x, y)) {
      drag_last.x = x;
      drag_last.y = y;

      /* no full repaint: copy the map from the buffer, draw dragged
         icon on top */
      PaintWindow::Invalidate();
    }
    return true;

  case DRAG_OZ:
    if (manhattan_distance(drag_last, RasterPoint{x,y}) > Layout::GetHitRadius()) {
      /* cancel the target move click when the finger has moved too
         far since it was pressed down */
      ReleaseCapture();
      drag_mode = DRAG_NONE;
      PaintWindow::Invalidate();
    }

    return true;
  }

  return false;
}
Beispiel #6
0
static int heuristic_oblique(Path &p,int x,int y) {
	int dx,dy;
	p.getDestination(dx,dy);
	dir_adjust(p,x,y,dx,dy);
//	x = abs(x-dx),y = abs(y-dy);
//	return x>y? x+y/2 : y+x/2;
	return manhattan_distance(x,y,dx,dy);
}
 /// Whenever the player moves from one chunk to the next, the chunks
 /// that are outside the view distance must be removed.
 //  Chunks are stored as groups with the same Manhattan distance, so
 //  potentially the shape of the visible world would be a octahedron.
 //  However, the scene object might choose to shape the visible part
 //  of the world differently, hence the need for this function.
 void remove_chunks(const std::vector<chunk_coordinates>& list)
 {
     boost::mutex::scoped_lock l (lock);
     for (auto& pos : list)
     {
         size_t dist (manhattan_distance(plr_pos_, pos));
         if (dist < view_dist_)
         {
             opaque_vbos[dist].erase(pos);
             transparent_vbos[dist].erase(pos);
             occlusion_queries[dist].erase(pos);
         }
     }
 }
 void sort_vbos (std::vector<t>& set) const
 {
     typedef typename t::value_type elem_t;
     std::vector<t> temp (view_dist_);
     for (t& l : set)
     {
         for (elem_t& p : l)
         {
             size_t dist (manhattan_distance(p.first, plr_pos_));
             if (dist < view_dist_)
                 temp[dist][p.first] = std::move(p.second);
         }
     }
     set.swap(temp);
 }
bool
GlueMapWindow::OnMouseMove(PixelScalar x, PixelScalar y, unsigned keys)
{
    /* allow a bigger threshold on touch screens */
    const unsigned threshold = Layout::Scale(IsEmbedded() ? 50 : 10);
    if (drag_mode != DRAG_NONE && arm_mapitem_list &&
            (manhattan_distance(drag_start, RasterPoint{x, y}) > threshold ||
             mouse_down_clock.Elapsed() > 200))
        arm_mapitem_list = false;

    switch (drag_mode) {
    case DRAG_NONE:
        break;

#ifdef HAVE_MULTI_TOUCH
    case DRAG_MULTI_TOUCH_PAN:
#endif
    case DRAG_PAN:
        visible_projection.SetGeoLocation(drag_projection.GetGeoLocation()
                                          + drag_start_geopoint
                                          - drag_projection.ScreenToGeo(x, y));
        QuickRedraw();

#ifdef ENABLE_OPENGL
        kinetic_x.MouseMove(x);
        kinetic_y.MouseMove(y);
#endif
        return true;

    case DRAG_GESTURE:
        gestures.Update(x, y);

        /* invoke PaintWindow's Invalidate() implementation instead of
           DoubleBufferWindow's in order to reuse the buffered map */
        PaintWindow::Invalidate();
        return true;

    case DRAG_SIMULATOR:
        return true;
    }

    return MapWindow::OnMouseMove(x, y, keys);
}
Beispiel #10
0
void MapWindow::LKDrawLongTrail( LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj) {
    static RasterPoint snail_polyline[array_size(LongSnailTrail)+1]; // +1 for last point of "normal" snail trail

    if (TrailActive != 3) return; // only when full trail is selected
    if (iLongSnailNext < 2) return; // no reason to draw a single point

    if (MapWindow::mode.Is(MapWindow::Mode::MODE_CIRCLING)) {
        return;
    }

    // pixel manhattan distance
    // It is the sum of x and y differences between previous and next point on screen, in pixels.
    // below this distance, no painting
    const unsigned nearby=10;

    const LONG_SNAIL_POINT* end_iterator = std::begin(LongSnailTrail);
    const LONG_SNAIL_POINT* cur_iterator = std::prev(std::next(LongSnailTrail,iLongSnailNext));
    RasterPoint* polyline_iterator = std::begin(snail_polyline);

    const SNAIL_POINT* last_point = std::next(std::next(SnailTrail, iSnailNext));
    if(last_point == std::end(SnailTrail)) {
        last_point = std::begin(SnailTrail);
    }
    (*polyline_iterator) = _Proj.LonLat2Screen(last_point->Longitude, last_point->Latitude);

    polyline_iterator = std::next(polyline_iterator);

    const auto oldPen = Surface.SelectObject(hSnailPens[3]); // blue color

    while(cur_iterator != end_iterator) {

        (*polyline_iterator) = _Proj.LonLat2Screen(cur_iterator->Longitude, cur_iterator->Latitude);

        if(manhattan_distance(*std::prev(polyline_iterator),(*polyline_iterator)) > nearby) {
            polyline_iterator = std::next(polyline_iterator);
        }
        cur_iterator = std::prev(cur_iterator);
    }
    Surface.Polyline(snail_polyline, std::distance(snail_polyline, polyline_iterator) , rc);

    Surface.SelectObject(oldPen);
}
Beispiel #11
0
static unsigned
_PolygonToTriangles(const PT *points, unsigned num_points,
                    GLushort *triangles, unsigned min_distance)
#endif
{
  // no redundant start/end please
  if (num_points >= 1 &&
      points[0].x == points[num_points - 1].x &&
      points[0].y == points[num_points - 1].y)
    num_points--;

  if (num_points < 3)
    return 0;

  assert(num_points < 65536);
  // next vertex pointer
  GLushort *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) {
        unsigned distance = manhattan_distance(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
  GLushort *t = triangles;
  for (unsigned a = start, b = next[a], c = next[b], heat = 0;
       num_points > 2; a = b, b = c, c = next[c]) {
    if (LeftBend(points[a], points[b], points[c])) {
      bool ear_cuttable = true;
      for (unsigned p = next[c]; p != a; p = next[p]) {
        if (InsideTriangle(points[p], points[a], points[b], points[c])) {
          ear_cuttable = false;
          break;
        }
      }
      if (ear_cuttable) {
        // save triangle indices
        *t++ = a;
        *t++ = b;
        *t++ = c;
        // 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;
}
Beispiel #12
0
 /**
  * Call this in the "mouse up" handler.  It will take care for
  * resetting this object when the mouse/finger has moved too much.
  */
 void Moved(RasterPoint _location) {
   if (clock.IsDefined() &&
       manhattan_distance(location, _location) > MAX_DISTANCE_PX)
     Reset();
 }
Beispiel #13
0
bool
XShape::BuildIndices(unsigned thinning_level, unsigned min_distance)
{
  assert(indices[thinning_level] == NULL);

  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 (manhattan_distance(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 &&
             manhattan_distance(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 {
    assert(false);
    return false;
  }
}
Beispiel #14
0
  /**
   * Adds the point only if it a few pixels distant from the previous
   * one.  Useful to reduce the complexity of small figures.
   */
   void AddPointIfDistant(RasterPoint pt) {
    assert(num_points < points.size());

    if (num_points == 0 || manhattan_distance(points[num_points - 1], pt) >= 8)
      AddPoint(pt);
  }
Beispiel #15
0
inline int h(search_node * node)
{
    return manhattan_distance(node);
}
Beispiel #16
0
double FrVectorSimilarity(FrClusteringMeasure sim,
                          const double *vec1, const double *vec2,
                          size_t veclen, bool normalize)
{
    if (veclen == 0)
        return 1.0 ;			// empty vectors are always identical
    if (!vec1 || !vec2)
        return -1.0 ;			// maximum diff if vector missing
    switch (sim)
    {
    case FrCM_COSINE:
        return cosine_similarity(vec1,vec2,veclen,normalize) ;
    case FrCM_EUCLIDEAN:
        return 1.0 - euclidean_distance(vec1,vec2,veclen,normalize) ;
    case FrCM_MANHATTAN:
        return 1.0 - manhattan_distance(vec1,vec2,veclen,normalize) ;
    case FrCM_JACCARD:
        return jaccard_coefficient(vec1,vec2,veclen) ;
    case FrCM_SIMPSON:
        return simpson_coefficient(vec1,vec2,veclen) ;
    case FrCM_EXTSIMPSON:
        return extended_simpson_coefficient(vec1,vec2,veclen,normalize) ;
    case FrCM_DICE:
        return dice_coefficient(vec1,vec2,veclen,normalize) ;
    case FrCM_ANTIDICE:
        return antidice_coefficient(vec1,vec2,veclen,normalize) ;
    case FrCM_TANIMOTO:
        return tanimoto_coefficient(vec1,vec2,veclen,normalize) ;
    case FrCM_BRAUN_BLANQUET:
        return braun_blanquet_coefficient(vec1,vec2,veclen,normalize) ;
    case FrCM_KULCZYNSKI1:
        return kulczynski_measure1(vec1,vec2,veclen,normalize) ;
    case FrCM_KULCZYNSKI2:
        return kulczynski_measure2(vec1,vec2,veclen,normalize) ;
    case FrCM_OCHIAI:
        return ochiai_measure(vec1,vec2,veclen,normalize) ;
    case FrCM_SOKALSNEATH:
        return sokal_sneath_measure(vec1,vec2,veclen,normalize) ;
    case FrCM_MCCONNAUGHEY:
        // mcConnaughey_measure() return is in range -1.0...+1.0
        return (mcConnaughey_measure(vec1,vec2,veclen,normalize)+1.0) / 2.0 ;
    case FrCM_LANCEWILLIAMS:
        return 1.0 - lance_williams_distance(vec1,vec2,veclen,normalize) ;
    case FrCM_BRAYCURTIS:
        return bray_curtis_measure(vec1,vec2,veclen,normalize) ;
    case FrCM_CANBERRA:
        return 1.0 - canberra_measure(vec1,vec2,veclen,normalize) ;
    case FrCM_CIRCLEPROD:
        return circle_product(vec1,vec2,veclen,normalize) / veclen ;
    case FrCM_CZEKANOWSKI:
        return czekanowski_measure(vec1,vec2,veclen,normalize) ;
    case FrCM_ROBINSON:
        return robinson_coefficient(vec1,vec2,veclen,normalize) / 2.0 ;
    case FrCM_DRENNAN:
        return 1.0 - drennan_dissimilarity(vec1,vec2,veclen,normalize) ;
    case FrCM_SIMILARITYRATIO:
        return similarity_ratio(vec1,vec2,veclen,normalize) ;
    case FrCM_JENSENSHANNON:
        return 1.0 - jensen_shannon_divergence(vec1,vec2,veclen,normalize) ;
    case FrCM_MOUNTFORD:
        return mountford_coefficient(vec1,vec2,veclen) ;
    case FrCM_FAGER_MCGOWAN:
        return fager_mcgowan_coefficient(vec1,vec2,veclen) ;
    case FrCM_TRIPARTITE:
        return tripartite_similarity_index(vec1,vec2,veclen) ;
    case FrCM_BIN_DICE:
        return binary_dice_coefficient(vec1,vec2,veclen) ;
    case FrCM_BIN_ANTIDICE:
        return binary_antidice_coefficient(vec1,vec2,veclen) ;
    case FrCM_BIN_GAMMA:
        return binary_gamma_coefficient(vec1,vec2,veclen) ;
    case FrCM_NONE:
        return 0.0 ;
    default:
        FrMissedCase("FrVectorSimilarity()") ;
        return 0.0 ;
    }
}
auto euclidean_distance(const Point& p1, const Point& p2){
    return std::sqrt(manhattan_distance(p1, p2));
}
double get_distance(const vector<vector<int> > &screen, pair<int, int> start_loc, pair<int, int> goal) {
    set<pair<int, int> > visited_closed;
    set<pair<int, int> > visited_opened;

    visited_opened.insert(start_loc);

    map<pair<int, int>, pair<int, int> > predecessor;

    map<pair<int, int>, int> g_score;
    g_score[start_loc] = 0;

    map<pair<int, int>, int> f_score;
    f_score[start_loc] = manhattan_distance(start_loc, goal);

    heuristic_comparison cmp(f_score);
    location_queue locations(cmp);
    locations.push(start_loc);
    int nodes_visited = 0;

    bool goal_reached = false;

    while (!locations.empty()) {
        nodes_visited += 1;
        pair<int, int> current_loc = locations.top();
        if (current_loc == goal) {
            goal_reached = true;
            break;
        }
        visited_opened.erase(visited_opened.find(current_loc));
        locations.pop();
        visited_closed.insert(current_loc);
        vector<pair<int, int> > neighbors = get_adjacent_locations(current_loc);
        for (int i = 0; i < neighbors.size(); ++i) {
            if (screen[neighbors[i].first][neighbors[i].second] == 0 &&
                (screen[neighbors[i].first - 1][neighbors[i].second] == 0 ||
                 screen[neighbors[i].first + 1][neighbors[i].second] == 0))
                continue;
            if (visited_closed.find(neighbors[i]) != visited_closed.end()) continue;
            double estimated_g_score = g_score[current_loc] + 1;
            bool neighbor_pushed = false;
            if (visited_opened.find(neighbors[i]) == visited_opened.end()) {
                visited_opened.insert(neighbors[i]);
                neighbor_pushed = true;
            }
            else if (estimated_g_score > g_score[neighbors[i]]) continue;
            predecessor[neighbors[i]] = current_loc;
            g_score[neighbors[i]] = estimated_g_score;
            f_score[neighbors[i]] = g_score[neighbors[i]] + manhattan_distance(neighbors[i], goal);
            if (neighbor_pushed) locations.push(neighbors[i]);
        }
    }

    pair<int, int> current_loc = goal;
    if (!goal_reached)
        return numeric_limits<double>::max();
    double distance = 0;
    while (current_loc != start_loc) {
        current_loc = predecessor[current_loc];
        distance += 1;
    }
    return distance;
}