简体   繁体   English

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

[英]Sort container, then shift elements while preserving original sort

I have a std::vector filled with 2d line endpoints that emit from a circle's center. 我有一个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 );
} );

The center variable is in-class, so the lambda is fine. center变量在类中,因此lambda很好。 The lines are of variable length, and the sort places the point at 12:00 (90 degrees) as the first element. 这些线的长度是可变的,并且排序将点放置在12:00(90度)处作为第一个元素。

I would like to maintain this clockwise sort, but I would like to rearrange the elements in the container so that the first element is the element with the shortest distance from the circle's center. 我想保持这种顺时针排序,但是我想重新排列容器中的元素,以使第一个元素是距圆心最短距离的元素。 A predicate to compare the distances is easy, but I don't understand how to shift the elements around. 谓词比较距离很容易,但是我不知道如何移动元素。

eg, if the point with smallest distance from center has angle of 45 degrees, then I would like that 45-degree element to be the first element in the container, maintain the sort order for the remainder of the container, then re-insert the elements from the beginning of the container in the clockwise-sorted order they already have. 例如,如果距中心距离最小的点的夹角为45度,那么我希望该45度元素成为容器中的第一个元素,保持容器其余部分的排序顺序,然后重新插入容器开始时已按顺时针排序的元素。

EDIT for more information: Here's an example, making a circle then arbitrarily taking one point and making it the smallest. 编辑以获取更多信息:这是一个示例,先画一个圆,然后任意取一个点并使之最小。 Like center , radius is an in-class variable, and should be assumed to be a valid float . 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) );
}

sorting output is from 12:00 rotating clockwise, and points[2] has the smallest distance: 排序输出从12:00开始顺时针旋转,points [2]的距离最小:

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

After the second operation, the set would look like: 在第二次操作后,集合将如下所示:

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

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

Use std::min_element to find the element with the shortest distance (that is, a min with a custom comparer), and use std::rotate to perform an in-place rotation. 使用std::min_element查找距离最短的元素(即使用自定义比较器的min ),然后使用std::rotate执行就地旋转。

Something like : 就像是 :

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM