std :: partition с двумя операторами возврата - PullRequest
0 голосов
/ 16 мая 2018

Можно ли использовать std :: partition с условиями, использующими два оператора возврата?
В моем примере я хочу разбить отрезки на группы в зависимости от их расстояния друг от друга. Наименьшее расстояние между непересекающимися отрезками линии можно рассчитать как расстояние между одной из конечных точек линии 1 (левая линия) и линией 2 (правая линия).
Но также возможно, что другая конечная точка строки 1 ближе к строке 2. Вот некоторый код:

#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

float getDistance(float x1, float y1, float x2, float y2) {
    float diff_x = x2 - x1;
    float diff_y = y2 - y1;

    float distance = sqrtf(diff_x*diff_x + diff_y * diff_y);

    return distance;
}

float getMinimumDistance(Point2f point, Point2f startpoint, Point2f endpoint) {
    // Return minimum distance between line segment vw and point p
    const float l2 = (endpoint.x - startpoint.x)*(endpoint.x - startpoint.x) + (endpoint.y - startpoint.y)*(endpoint.y - startpoint.y);  // i.e. |w-v|^2 -  avoid a sqrt
    if (l2 == 0.0) {
        return getDistance(point.x, point.y, startpoint.x, startpoint.y); // v == w case
    }

    const float t = std::max(float(0), std::min((float)1, ((point.x - startpoint.x)*(endpoint.x - startpoint.x) + (point.y - startpoint.y)*(endpoint.y - startpoint.y) / l2)));

    const Point2f projection = Point2f(startpoint.x + t * (endpoint.x - startpoint.x), startpoint.y + t * (endpoint.y - startpoint.y));  // Projection falls on the segment
    return getDistance(point.x, point.y, projection.x, projection.y);
}

int main(int argc, char** argv)
{
    // Create some values - both vectors have the same size
    vector<Vec4f> line_segments_1;

    line_segments_1.push_back(Vec4f(1.0, 1.0, 5.0, 5.0));
    line_segments_1.push_back(Vec4f(2.0, 0.5, 5.0, 2.5));
    line_segments_1.push_back(Vec4f(0.0, 0.5, 1.0, 2.5));
    line_segments_1.push_back(Vec4f(5.0, 1.0, 5.0, 4.0));
    line_segments_1.push_back(Vec4f(3.0, 1.0, 4.0, 3.0));
    line_segments_1.push_back(Vec4f(5.0, 5.0, 1.0, 5.0));
    line_segments_1.push_back(Vec4f(4.0, 8.0, 8.0, 4.0));
    line_segments_1.push_back(Vec4f(8.0, 4.0, 8.0, 1.0));
    line_segments_1.push_back(Vec4f(7.0, 2.0, 9.0, 3.0));

    int pixel_tolerance = 2;
    vector<int> labels;

    // Using std::partition
    if (line_segments_1.size() > 1) {
        int n_labels = partition(line_segments_1, labels, [pixel_tolerance](const Vec4f &left_line, const Vec4f &right_line) {  // Clustering using partition, the pixel tolerance and two conditions
            return getMinimumDistance(Point2f(left_line[0], left_line[1]), Point2f(right_line[0], right_line[1]), Point2f(right_line[2], right_line[3])) < pixel_tolerance;  // If one statement is true, the lines belong to a cluster
            return getMinimumDistance(Point2f(left_line[2], left_line[3]), Point2f(right_line[0], right_line[1]), Point2f(right_line[2], right_line[3])) < pixel_tolerance;
        });
    }
}

1 Ответ

0 голосов
/ 16 мая 2018

Первое return всегда завершает функцию, второе недоступно.

То, что вы, вероятно, хотите, является логическим или, что пишется ||

return (getMinimumDistance(Point2f(left_line[0], left_line[1]), Point2f(right_line[0], right_line[1]), Point2f(right_line[2], right_line[3])) < pixel_tolerance)
    || (getMinimumDistance(Point2f(left_line[2], left_line[3]), Point2f(right_line[0], right_line[1]), Point2f(right_line[2], right_line[3])) < pixel_tolerance);
...