3

For my code I need to compute Convexhull of series of points and for some reasons I need to use qhull libraries. In this library there is a method qconvex that do exactly what I need. I can run this command in terminal and get what I want. for example let's assume I have an input like points.txt:

2   #dimension
5   #number of points
0 0
1 0
0.5 0.5
1 1
0 1

I can run in terminal one these command to get the result: qconvex Fx < points.txt or cat points.txt | qconvex -Fx and the out put is :

4 
0
1
3
4

Now my question is how can I call this command in my C++ code iteratively over my input: in my code I have 2 for inside each other that call a specific function that will generate 10 points each time (stored in float **rs_tmp;) and I need to compute the qconvex for these 10 points each time. how can I run qconvex in my code and pipe the rs_tmp as its input? prefer to avoid writing the rs_tmp into some temporarily file and read from it since I need my code to be super fast.

float **rs_tmp;
for (int i = 0; i < NUMBER; i++)
{
    for (int j = 0; j < NUMBER; j++)
    {
        rs_tmp = generate_points(label, dect[i], dect[j], fun);
        // HERE I NEED TO CALL QCONVEX SOME HOW
        // THE POINTS ARE STORED IN rs_tmp as 2-Dimensional floating points array
    }
     int size = fun.size();
     for(int i = 0; i < size; ++i)     
     {
         delete[] rs_tmp[i]; 
     }   
     delete[] rs_tmp;         
}
Am1rr3zA
  • 7,115
  • 18
  • 83
  • 125

1 Answers1

3

I've had the same problem for quite a while now and just managed so solve it. Qhull provides a pretty neat example that is quite informative. If you cloned from git you can see the example in the directory qhull/src/user_eg3/user_eg3.cpp. It took me a bit to understand what they were doing but once you get the hang of it its actually pretty easy. I've removed all of the extra options but the one you are looking for.

/*--------------------------------------------
-user_eg3-  main procedure of user_eg3 application
*/
int main(int argc, char **argv) {
    try{
        return user_eg3(argc, argv);
    }catch(QhullError &e){
        cerr << e.what() << std::endl;
        return e.errorCode();
    }
}//main

int user_eg3(int argc, char **argv)
{
  RboxPoints rbox;
  Qhull qhull;
  line = "";
  std::istringstream is("2 4 1 0 1 1 0 0 0 1"); // To be passed to rbox: produces a unit square where 2 is the dimension 4 is the count and the points follow. This will also accept any valid rbox flags. 
  std::stringstream output;

  rbox.appendPoints(is); // appendPoints accepts either a const char* or an istream object. See libqhullcpp/RboxPoints.h and libqhullcpp/PointCoordinates.h 

  cerr << "@@@@@@@@@@\n" << rbox << "@@@@@@@@@@\n";
  qhull.runQhull(rbox, ""); //you can set any flag you would set for qhull in the terminal inside the ""
  qhull.setOutputStream(&output); //this will take any output stream 
  qhull.outputQhull("m"); //this will take any qhull output option
  cerr << "My Output : " << output.str() << "%%\n";
  qhull.setOutputStream(&cout);
  qhull.outputQhull("n");
  return 0;
}//user_eg3

Hope this helps.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Jake
  • 43
  • 1
  • 10