Go to the documentation of this file.00001 #include <algorithm>
00002 #include <cstdlib>
00003 #include "polygon_filter.h"
00007 template <class point_type1>
00008 bool point_inside_polygon(const pcl::PointCloud<point_type1>& cropping_polygon, const point_type1& query_point, int x, int y)
00009 {
00010
00011 int num_intersections = 0;
00012
00013 point_type1 p1,p2;
00014
00015 for(unsigned int i = 0; i< cropping_polygon.size(); i++)
00016 {
00017 p1 = cropping_polygon[i];
00018 int next_vertex_idx = (i+1) % cropping_polygon.size();
00019 p2 = cropping_polygon[next_vertex_idx];
00020
00021
00022
00023 if (query_point.data[y] > std::min(p1.data[y],p2.data[y])) {
00024
00025 if (query_point.data[y] <= std::max(p1.data[y],p2.data[y])) {
00026
00027 point_type1 segment_direction, normal;
00028 segment_direction.data[x] = p2.data[x]-p1.data[x];
00029 segment_direction.data[y] = p2.data[y]-p1.data[y];
00030 normal.data[x] = segment_direction.data[y];
00031 normal.data[y] = -segment_direction.data[x];
00032
00033 if(normal.data[x] > 0){
00034 normal.data[x] *= -1.0;
00035 normal.data[y] *= -1.0;
00036 }
00037
00038
00039 point_type1 query_point_rel;
00040 query_point_rel.data[x] = query_point.data[x] - p1.data[x];
00041 query_point_rel.data[y] = query_point.data[y] - p1.data[y];
00042
00043 double dot = normal.data[x] * query_point_rel.data[x] + normal.data[y] * query_point_rel.data[y];
00044 if(dot > 0)
00045 num_intersections++;
00046 }
00047 }
00048 }
00049
00050 if (num_intersections% 2 == 0)
00051 return false;
00052 else
00053 return true;
00054 }
00055
00057 template <class point_type1>
00058 pcl::PointCloud<point_type1> crop_by_polygon(const pcl::PointCloud<point_type1>& cropping_polygon, const pcl::PointCloud<point_type1>& cloud_to_crop, int x, int y, bool invert)
00059 {
00060 pcl::PointCloud<point_type1> cloud_inside;
00061 cloud_inside.header = cloud_to_crop.header;
00062
00063 for(unsigned int i = 0; i < cloud_to_crop.size(); i++)
00064 {
00065 if(point_inside_polygon(cropping_polygon, cloud_to_crop[i], x, y) xor invert)
00066 {
00067 cloud_inside.push_back(cloud_to_crop[i]);
00068 }
00069 }
00070 return cloud_inside;
00071 }
00072
00073 void cropping_test(){
00074
00075 pcl::PointCloud<pcl::PointXYZ> test_cloud;
00076 pcl::PointXYZ vertex;
00077 srand(time(NULL));
00078 for(int i = 0; i < 200; i++){
00079 vertex.x = rand()/(RAND_MAX/2.0);
00080 vertex.y = rand()/(RAND_MAX/2.0);
00081 test_cloud.points.push_back(vertex);
00082 }
00083
00084 pcl::PointCloud<pcl::PointXYZ> cropping_polygon;
00085 vertex.x = 0.0; vertex.y = 0.0; cropping_polygon.points.push_back(vertex);
00086 vertex.x = 1.0; vertex.y = 0.0; cropping_polygon.points.push_back(vertex);
00087 vertex.x = 1.0; vertex.y = 1.0; cropping_polygon.points.push_back(vertex);
00088 vertex.x = 0.0; vertex.y = 1.0; cropping_polygon.points.push_back(vertex);
00089
00090 pcl::PointCloud<pcl::PointXYZ> inside_cloud = crop_by_polygon(cropping_polygon, test_cloud, 0, 1);
00091 pcl::PointCloud<pcl::PointXYZ> outside_cloud = crop_by_polygon(cropping_polygon, test_cloud, 0, 1, true);
00092 for(unsigned int i = 0; i < inside_cloud.size(); i++){
00093 std::cout << "Point Inside (" << i << "/" << inside_cloud.size() << "): "<< inside_cloud.points[i].x << ", " <<inside_cloud.points[i].y << ", " <<inside_cloud.points[i].z << "\n";
00094 }
00095 std::cout << std::endl;
00096 for(unsigned int i = 0; i < outside_cloud.size(); i++){
00097 std::cout << "Point Outside (" << i << "/" << outside_cloud.size() << "): "<< outside_cloud.points[i].x << ", " <<outside_cloud.points[i].y << ", " <<outside_cloud.points[i].z << "\n";
00098 }
00099 }