对容器进行排序,然后在保留原始排序的同时移动元素

时间:2014-08-24 20:19:29

标签: c++ sorting vector

我有一个std::vector填充了从圆圈中心发出的2d线端点。

std::vector<vec2> points(fillPoints( ));
std::sort( points.begin( ), points.end( ), [&]( const vec2& a, const vec2& b ) {
    return clockwiseSortPredicate( a, b, center );
} );

center变量是类中的,所以lambda很好。这些线的长度可变,排序将点放在12:00(90度)作为第一个元素。

我想保持顺时针排序,但我想重新排列容器中的元素,以便第一个元素是距离圆的中心最短距离的元素。比较距离的谓词很容易,但我不明白如何改变元素。

例如,如果距离中心的距离最小的点的角度为45度,那么我希望45度元素成为容器中的第一个元素,保持容器其余部分的排序顺序,然后重新 - 按容器顺序排序的顺序插入容器开头的元素。

编辑以获取更多信息:这是一个例子,制作一个圆圈然后任意取一个点并使其最小。与center类似,radius是一个类内变量,应该假定它是有效的float

const auto numPoints = 30;
std::vector<vec2> points;
const auto increment = 6.283185308f / numPoints;  //2pi radians
for ( auto i = 0; i != numPoints; ++i ) {
    const float theta = i * increment;
    auto newRadius = i == 2 ? radius / 2 : radius;
    const auto x = center.x + std::cos( theta ) * newRadius;
    const auto y = center.y + std::sin( theta ) * newRadius;
    points.push_back( vec2(x,y) );
}

排序输出是顺时针旋转的12:00,点[2]的距离最小:

{ p0, p1, p2(smallest!), ..., p29 }

在第二次操作之后,该集合将如下所示:

{ p2, p3, p4, ..., p29, p0, p1 }

2 个答案:

答案 0 :(得分:3)

看来,您正在寻找std::min_element()来找到短路元素,std::rotate()来移动std::vector<vec2>中的元素。

答案 1 :(得分:3)

使用std::min_element查找距离最短的元素(即带有自定义比较器的min),然后使用std::rotate执行就地旋转。

类似的东西:

auto it = std::min_element( points.begin(), points.end() , IsClosestComparer);
std::rotate(points.begin(), it , points.end() )