Boost Geometry: using a 2D polar coordinate system - c++

Im playing around with the new geometry library made available in boost 1.47 and wanted to know if it is possible to define a 2D polar system.
In the header files and documentation I found a definition for a polar system but when trying to use it with the sample code below I'm getting compilation errors:
using namespace boost;
typedef geometry::cs::polar<geometry::radian> geometry_type;
typedef geometry::model::point<double, 2, geometry_type> point_type;
const double PI = math::constants::pi<double>();
point_type p1(0, 0);
point_type p2(1, PI/2);
double dist = geometry::distance(p1, p2); // COMPILATION FAILS HERE
in VC2010 I get: "error C2039: 'type' : is not a member of 'boost::geometry::traits::cs_tag'" when trying to compile the distance function above.
This is the definition for the polar system extracted from the boost header files (boost/geometry/core/cs.hpp):
/*!
\brief Polar coordinate system
\details Defines the polar coordinate system "in which each point
on a plane is determined by an angle and a distance"
\see http://en.wikipedia.org/wiki/Polar_coordinates
\ingroup cs
*/
template<typename DegreeOrRadian>
struct polar
{
typedef DegreeOrRadian units;
};
But I think that the definition is incomplete since "polar" is not mentioned anywhere else. Am I supposed to define a distance strategy and other needed traits all by myself for a simple 2D polar system?

Well, answering my own question (hope that this is ok) after a bit more of research: It seems that I got the wrong idea about coordinate systems in the geometry library's sense. The different coordinate systems seem to specify the intrinsic geometry like the surface of a sphere where for example the distance between two points are not computed in a cartesian way.
What I wanted to accomplish (use a polar system) can be done by defining a new point class that takes the polar coordinates and converts them to X and Y coordinates. After registering the new point class with the BOOST_GEOMETRY_REGISTER_POINT_2D macro (like in the boost samples) and using a normal cartesian system all geometry algorithms work as expected.

The trouble with type traits is you have to write your own specialisation for each client type.
(This is not true of the standard <traits> library in C++0x.)

Related

g2o: How to optimize camera intrinsic (fx,fy,cx,cy) during Bundle Adjustment

Some pre-defined edges, such as EdgeProjectXYZ2UV, EdgeSE3ProjectXYZ, are widely used during BA. However, they can only set unchangeable camera parameters. I'm wondering if I can set optimizable camera parameters.
Thanks for any reply in advance!
I found Vertex VertexIntrinsics in g2o/types/sba/vertex_intrinsics.h. And its oplusImpl() function is implemented which means it can be optimized.
/**
* \brief Vertex encoding the intrinsics of the camera fx, fy, cx, xy, baseline;
*/
class G2O_TYPES_SBA_API VertexIntrinsics : public BaseVertex<4, Eigen::Matrix<number_t, 5, 1, Eigen::ColMajor> >
It seems to be the one I'm looking for. Yet I cannot find a type of Ternary-Edge that link this vertex, camera pose vertex, and 3D world point vertex. Or any other edge that takes this type of vertex.
It would be great if somebody could share an example or some explanation about how this vertex works. Or any other way to optimize camera intrinsic in g2o.
I managed to solve it by defining a Ternary edge that links the camera intrinsic Vertex (VertexIntrinsics), camera pose Vertex (VertexSE3 or VertexSE3Expmap), and Observation Target (Vertex SE3 in my case, or VertexPointXYZ ).
There will be only one VertexIntrinsics in the graph.
If you are looking for a ternary edge example, check edge_project_psi2uv.h.
Thank #RainerKuemmerle for such great work.

Substract closed mesh from surface (CGAL?)

I have the following problem, best described with the picture below.
I have a surface in 3D, so it can have vertical overlap and is a non-closed mesh. And I have an object which I want to subtract from it. The green+yellow area is the original surface, the red lines outline a sphere (as triangulated mesh, not a primitive). The yellow area is the part of the surface intersecting the sphere that needs to be removed from the original surface. The green area is the result of the subtraction: the surface that is needed.
I am already using the CGAL library, but still new to it, so a solution using CGAL would be the most preferred. However if somebody has a solution without CGAL that would be welcome as well.
The best way I can see would be to give the surface a slight thickness (keeping the current surface as the bottom). And then use Nef_polyhedron_3 to substract the other object, then convert to Polyhedron_3 and only keep the bottom faces. But this seems like a bit of a hack.
EDIT:
Using the proposed solution I get very close, but I am unable to clip to the correct side using the reversed normals as proposed, using the following code.
I also tried to see if face vertex ordering (clockwise / counter clockwise) has any effect, but it seems not to have any.
typedef CGAL::Simple_cartesian<double> SC;
typedef CGAL::Surface_mesh<SC::Point_3> SurfaceMesh;
typedef SurfaceMesh::Property_map<SM_fid, SC::Vector_3> SM_fnormals;
typedef SurfaceMesh::Vertex_index SM_vid;
typedef SurfaceMesh::Face_index SM_fid;
namespace PMP = CGAL::Polygon_mesh_processing;
namespace params = PMP::parameters;
void clip(SurfaceMesh P&, SurfaceMesh& Q) {
SM_fnormals fnormals = CGALobstacle->add_property_map<SM_fid, SC::Vector_3>
("f:normals", CGAL::NULL_VECTOR).first;
PMP::compute_face_normals(Q, fnormals);
PMP::clip(P, Q, false, params::all_default(), params::face_normal_map(fnormals));
}
There is an undocumented function starting from CGAL 4.10 in Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/clip.h. The function signature is :
/// requires face_index_map, vertex_index_map for np_tm
/// requires face_index_map for np_c
/// if edge_is_constrained_map is not provided in np_tm a default one is
/// provided using boost::unordered_set<edge_descriptor>
template <class TriangleMesh,
class NamedParameters1,
class NamedParameters2>
bool
clip( TriangleMesh& tm,
/*const*/ TriangleMesh& clipper,
bool close,
const NamedParameters1& np_tm,
const NamedParameters2& np_c)
The second parameter would be your sphere and the first your surface. The third indicates if you want the output surface to be closed (so false in your case). Note that the function is clipping so if you want the outside part of the sphere you need to reverse the orientation of your sphere (inward normals).
There is a usage example here.
I recommend using Surface_mesh rather than Polyhedron_3.
Note that the function is not documented and the header might disappear in an upcoming release (if it does it means that it got officially documented).
EDIT: The officially documented function since CGAL 4.13 is here.

Point Cloud Library: How visualize a set of 3D point stored in a C++ <vector>?

I've searched here about this question, but seems no one have this question.
How can I draw with PCL visualizer a set of 3D points stored in a C++ ?
The vector it's filled of structs like this:
struct point {
float x;
float y;
float z;
};
How can I draw this set of points using PCL in a window? At every elaboration of vector, the PCL window will be updated with new points of interest in the vector.
I'm on Visual C++ 2010, Win7 64bit...I've correctly installed PCL library and visual c++ enviromental variables/linker/etc to use PCL.
Can someone help me?
Just define pcl::PointXYZ pt, and pt.x=point.x, pt.y=point.y, pt.z=point.z
then apply PointView to show your point clouds.
this is very essential part in PCL

How to change the default QGLViewer's near and far clipping distance in QT and QGLViewer programs?

I got a fairly large model that need to be displayed in a QT UI program that uses QGLViewer.
So the model got cut because of the default near and far clipping distance is too narrow.
My question is how to change the default near and far clipping range.
For example my problem could look like this one
I tried to use something like,
::glMatrixMode(GL_PROJECTION) ;
::glLoadIdentity() ;
::glClearColor(1.0f,1.0f,1.0f,0.0f);
::glFrustum(-0.5,0.5,-0.5,0.5,-100000000.0,100000000.0) ;
::glMatrixMode(GL_MODELVIEW) ;
::glLoadIdentity() ;
This doesn't work at all, and it breaks the mouse interaction in the QGLViewer too.
Since I'm using QT and QGLViewer, there's no glu functions that I can use.
So I'm asking for anyone knows how to make the QGLViewer change its default clipping range.
I found some examples QGLViewer provided like clipping plane example, standard camera example, but I still don't have a clue how to change the default viewer.
I think I worked out this by myself. From the documentation here.
I just used this code to initialise the viewer,
void Viewer::initializeGL()
{
QGLViewer::initializeGL();
this->setSceneRadius(10000.0);
}
But this sets the default scene camera too, if the radius is high, the default perspective's position is changed too, so this setSceneRadius is not only changing the near/far clipping plane.
Actually, there are different methods from the documentation here.
So this one maybe better. The formula to calculate the real near and far is in the documentation of the last link. Smaller near coef and larger Clipping coef means larger range of the viewing area.
void Viewer::initializeGL()
{
QGLViewer::initializeGL();
this->camera()->setZNearCoefficient(0.00001);
this->camera()->setZClippingCoefficient(1000.0);
}
Of course you can override your own version of near and far definition.
class myCamera :: public qglviewer::Camera
{
virtual float Camera::zNear() const { return 0.001; };
virtual float Camera::zFar() const { return 100.0; };
}
And construct your QGLViewer object with this customised camera.

Matlab griddata equivalent in C++

I am looking for a C++ equivalent to Matlab's griddata function, or any 2D global interpolation method.
I have a C++ code that uses Eigen 3. I will have an Eigen Vector that will contain x,y, and z values, and two Eigen matrices equivalent to those produced by Meshgrid in Matlab. I would like to interpolate the z values from the Vectors onto the grid points defined by the Meshgrid equivalents (which will extend past the outside of the original points a bit, so minor extrapolation is required).
I'm not too bothered by accuracy--it doesn't need to be perfect. However, I cannot accept NaN as a solution--the interpolation must be computed everywhere on the mesh regardless of data gaps. In other words, staying inside the convex hull is not an option.
I would prefer not to write an interpolation from scratch, but if someone wants to point me to pretty good (and explicit) recipe I'll give it a shot. It's not the most hateful thing to write (at least in an algorithmic sense), but I don't want to reinvent the wheel.
Effectively what I have is scattered terrain locations, and I wish to define a rectilinear mesh that nominally follows some distance beneath the topography for use later. Once I have the node points, I will be good.
My research so far:
The question asked here: MATLAB functions in C++ produced a close answer, but unfortunately the suggestion was not free (SciMath).
I have tried understanding the interpolation function used in Generic Mapping Tools, and was rewarded with a headache.
I briefly looked into the Grid Algorithms library (GrAL). If anyone has commentary I would appreciate it.
Eigen has an unsupported interpolation package, but it seems to just be for curves (not surfaces).
Edit: VTK has a matplotlib functionality. Presumably there must be an interpolation used somewhere in that for display purposes. Does anyone know if that's accessible and usable?
Thank you.
This is probably a little late, but hopefully it helps someone.
Method 1.) Octave: If you're coming from Matlab, one way is to embed the gnu Matlab clone Octave directly into the c++ program. I don't have much experience with it, but you can call the octave library functions directly from a cpp file.
See here, for instance. http://www.gnu.org/software/octave/doc/interpreter/Standalone-Programs.html#Standalone-Programs
griddata is included in octave's geometry package.
Method 2.) PCL: They way I do it is to use the point cloud library (http://www.pointclouds.org) and VoxelGrid. You can set x, and y bin sizes as you please, then set a really large z bin size, which gets you one z value for each x,y bin. The catch is that x,y, and z values are the centroid for the points averaged into the bin, not the bin centers (which is also why it works for this). So you need to massage the x,y values when you're done:
Ex:
//read in a list of comma separated values (x,y,z)
FILE * fp;
fp = fopen("points.xyz","r");
//store them in PCL's point cloud format
pcl::PointCloud<pcl::PointXYZ>::Ptr basic_cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
int numpts=0;
double x,y,z;
while(fscanf(fp, "%lg, %lg, %lg", &x, &y, &z)!=EOF)
{
pcl::PointXYZ basic_point;
basic_point.x = x; basic_point.y = y; basic_point.z = z;
basic_cloud_ptr->points.push_back(basic_point);
}
fclose(fp);
basic_cloud_ptr->width = (int) basic_cloud_ptr->points.size ();
basic_cloud_ptr->height = 1;
// create object for result
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>());
// create filtering object and process
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud (basic_cloud_ptr);
//set the bin sizes here. (dx,dy,dz). for 2d results, make one of the bins larger
//than the data set span in that axis
sor.setLeafSize (0.1, 0.1, 1000);
sor.filter (*cloud_filtered);
So that cloud_filtered is now a point cloud that contains one point for each bin. Then I just make a 2-d matrix and go through the point cloud assigning points to their x,y bins if I want an image, etc. as would be produced by griddata. It works pretty well, and it's much faster than matlab's griddata for large datasets.