std::pair<PairPoints, size_t> getNearestPoints(std::vector<Point>& points, size_t debInter, size_t finInter, Integer xBorneLeft, Integer xBorneRight) { /*nbTab++; std::cerr << "\n"; errTab(); std::cerr << "--------- getNearestPoints entre " << xBorneLeft << " et " << xBorneRight << "\n"; errTab(); for (Integer i = debInter; i < finInter; i++) std::cerr << points[i].x << "-" << points[i].y << " "; std::cerr << "\n";*/ if (finInter - debInter < 2) { std::cerr << "Erreure sur la taille de l'entrée: trop petite" << std::endl; } if (finInter - debInter <= MAX_POINTS_N2) { PairPoints pairMin = brutalGetClosestPoints(points, debInter, finInter); std::sort(points.begin()+debInter, points.begin()+finInter, [](const Point& p1, const Point& p2) { return isP1BeforeP2_Y(p1, p2); }); //errTab(); std::cerr << "delta trouvé: " << pairMin.distanceSquare << "\n"; //nbTab--; return std::make_pair(pairMin, finInter); } // couper en deux, appels récursifs size_t indexCoupe = (debInter+finInter)/2; Integer xCoupe = points[indexCoupe].x; auto coupe1 = getNearestPoints(points, debInter, indexCoupe, xBorneLeft, xCoupe); auto coupe2 = getNearestPoints(points, indexCoupe, finInter, xCoupe, xBorneRight); PairPoints pairMin = std::min(coupe1.first, coupe2.first); std::vector<Point> nearLine = merge_ySorted_nearLine(points, debInter, coupe1.second, indexCoupe, coupe2.second, [&](const Point& p) { return carr(p.x - xCoupe) < pairMin.distanceSquare; }); /*errTab(); std::cerr << "Fusion: "; for (Point p : nearLine) { std::cerr << p.x << "-" << p.y << " "; } std::cerr << "\n";*/ for (size_t p1 = 0; p1 < nearLine.size(); p1++) { for (size_t nx = p1+1; nx < nearLine.size() && nx < p1+8; nx++) { pairMin = std::min(pairMin, PairPoints(nearLine[p1], nearLine[nx])); } } // mettre les deux parties au début, triée par y (uniquement ceux près des bords) std::vector<Point> nearBords = merge_ySorted_nearLine(points, debInter, coupe1.second, indexCoupe, coupe2.second, [&](const Point& p) { return carr(p.x - xBorneLeft) < pairMin.distanceSquare || carr(p.x - xBorneRight) < pairMin.distanceSquare; }); for (size_t iPoint = 0; iPoint < nearBords.size(); iPoint++) { points[debInter+iPoint] = nearBords[iPoint]; } //errTab(); std::cerr << "delta trouvé: " << pairMin.distanceSquare << " avec " << pairMin.p1.x << "-" << pairMin.p1.y << " " << pairMin.p2.x << "-" << pairMin.p2.y << "\n"; //nbTab--; return std::make_pair(pairMin, debInter+(Integer)nearBords.size()); }
Float2 UnstructuredMeshInterpolator::interpolateNearestPoints(float xN, float yN) { Float2 ret = {xN, yN}; // Look in the spatial-acceleration grid to see if we can // find three points without having to search the entire set of // points. int xIndex, yIndex; if (!getIndex(xN, yN, xIndex, yIndex)) { return ret; } MonoPointDistortionMeshDescription points; points = getNearestPoints(xN, yN, m_grid[xIndex][yIndex]); // If we didn't get enough points from the acceleration // structure, look in the whole points array if (points.size() < 3) { points = getNearestPoints(xN, yN, m_points); } // If we didn't get three points, just return the output of // the first point we found. if (points.size() < 3) { float xNew = static_cast<float>(points[0][1][0]); float yNew = static_cast<float>(points[0][1][1]); ret[0] = xNew; ret[1] = yNew; return ret; } // Found three points -- interpolate them. float xNew = static_cast<float>(interpolate( points[0][0][0], points[0][0][1], points[0][1][0], points[1][0][0], points[1][0][1], points[1][1][0], points[2][0][0], points[2][0][1], points[2][1][0], xN, yN)); float yNew = static_cast<float>(interpolate( points[0][0][0], points[0][0][1], points[0][1][1], points[1][0][0], points[1][0][1], points[1][1][1], points[2][0][0], points[2][0][1], points[2][1][1], xN, yN)); ret[0] = xNew; ret[1] = yNew; return ret; }
std::pair<PairPoints, double> execAlgo(std::string algo, std::vector<Point> points) { PairPoints nearests = PairPoints(points[0], points[1]); uint64_t start_time = pasl::util::microtime::now(); if (algo == "brutal") nearests = brutalGetClosestPoints(points, 0, (int)points.size()); else if (algo == "classical") nearests = getNearestPoints(points, 0, (int)points.size(), points[0].x, points.back().x).first; else if (algo == "optim1") nearests = getNearestPoints_optimum(points, 0, (int)points.size(), points[0].x, points.back().x).first; else if (algo == "optim2") { getNearestPoints_optimum2(points, 0, (int)points.size(), points[0].x, points.back().x, nearests); } else if (algo == "projections") { getClosestPoints_projections(points, 0, (int)points.size(), nearests); } else { std::cerr << "---------------> Erreur: algo " << algo << " inexistant <---------------" << std::endl; exit(-1); } double exec_time = pasl::util::microtime::seconds_since(start_time); return std::make_pair(nearests, exec_time); }