对于我的应用程序,我需要创建一个固定大小的缓冲区(3个元素)的点云。
为此,我在回调中尝试了天真的方式(我正在研究ROS):
vector< vector<Point2d> > points_buffer(3); // buffer of point clouds ,fixed size = 3
void laserToWorldCallback(const icars_laser_roi::stx_points::ConstPtr& laser_points, const icars_2d_map_manager::Status::ConstPtr& car_pos){
double x_w, y_w;
double x, y;
vector<Point2d> temp;
for(int i = 0; i < laser_points->points_x.size(); i++){
// get the coordinates
x = laser_points->points_x[i];
y = laser_points->points_y[i];
// tranform the coordinates
x_w = car_pos->xGlobal + x*cos(car_pos->yaw) - y*sin(car_pos->yaw);
y_w = car_pos->yGlobal + x*sin(car_pos->yaw) + y*cos(car_pos->yaw);
temp.push_back(Point2d(x_w, y_w));
}
if(points_buffer.size() != 3){ // the buffer is not empty
points_buffer.push_back(temp);
}else{ // the buffer is empty, delete last element and push_back
// delete last element
points_buffer[0] = points_buffer[1];
points_buffer[1] = points_buffer[2];
points_buffer[3] = temp;
}
}
}
但这种方式在我看来有点粗糙,根本没有效率。
有人可能会建议我更优雅高效地做我想做的事吗?
谢谢
此致
答案 0 :(得分:1)
解决一些效率问题。在声明temp
之后,您首先可以保留将与
temp.reserve(laser_points->points_x.size());
因此push_back
方法中不会重新分配内存。
如果您使用的是c ++ 11或更高版本,则在缓冲区尚未填满的情况下,您可以使用std::move
移动临时文件的内容。
points_buffer.push_back(std::move(temp));
这是O(1)操作。此后temp
的内容有效但未指定。
然后在删除最后一个元素时使用vector :: swap而不是copy,因为它将交换内容并保证在时间上保持不变。
points_buffer[0].swap(points_buffer[1]);
points_buffer[1].swap(points_buffer[2]);
points_buffer[2].swap(temp); //There is a typo here index should be 2 not 3.
如果要将point_buffer包装在一个类中,该程序将更具可读性。然后你也可以考虑不旋转整个矢量的内容,但要跟踪第一个索引。这对于较大的point_buffer也适用于3.然后将新元素添加到缓冲区只是
point_buffer[fist_element_].swap(temp);
first_element=(first_element_+1)%3;
然后要访问位置i
的元素,您可以将operator[]
实现为
vector<Point2d>& operator[](int i){
return point_buffer[(i+first_element)%3];
}