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); }
/** * 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; }
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); }
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); }
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; }
/** * 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(); }
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; } }
/** * 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); }
inline int h(search_node * node) { return manhattan_distance(node); }
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; }