C++ function not getting called - c++

I have a function that takes 2d-vector and outputs a 2d-vector. For some reason, the function is not getting called.
Here is the link to reproduce the issue: Google Colab.
In the link to check for correctness, I have added another code that uses the exact same function but doesn't take a 2d-vector array as an argument instead it runs on static input.
mycode.cpp:
#include <vector>
#include "geomutils.h"
#include "mycode.h"
#include <iostream>
using namespace std;
vector< vector<double> > customComputeConvexHull(vector< vector<double> > i_matrix){
cout <<"\nDone1.1";
Polygon custompts, customhull;
for (int r = 0; r < i_matrix.size(); r++){
custompts.push_back(Point(i_matrix[r][0], i_matrix[r][1]));
}
computeConvexHull(custompts, customhull);
// vector< vector<double> > res;
vector<vector<double>> res( customhull.size() , vector<double> (2));
for(int i = 0;i < customhull.size();i ++) {
res[i][0] = customhull[i].x;
res[i][1] = customhull[i].y;
}
return res;
}
void print_polygon(Polygon &h, int name){
std::cout << "\nHull in "<< name << ": \n"<<"[";
for(int i = 0;i < h.size();i ++) {
std::cout << "("<< h[i].x<< ", "<< h[i].y<<"), ";
}
std::cout <<"]\n";
}
void get_convex_hull_custom(){
Polygon custompts;
Polygon customhull;
custompts.push_back(Point(0,0));
custompts.push_back(Point(4.58,7.14));
custompts.push_back(Point(0,7.14));
computeConvexHull(custompts, customhull);
print_polygon(customhull, -99999);
}
int main()
{
// Create an empty vector
vector< vector<double> > mat,mat2;
vector<double> myRow1(0,0);
mat.push_back(myRow1);
vector<double> myRow2(7.61,9.48);
mat.push_back(myRow2);
vector<double> myRow3(0,9.48);
mat.push_back(myRow3);
cout <<"Done1\n";
get_convex_hull_custom();
mat2 = customComputeConvexHull(mat);
cout <<"Done2";
return 0;
}
mycode.h:
#ifndef _code
#define _code
#include <vector>
std::vector< std::vector<double> > customComputeConvexHull (std::vector< std::vector<double> > i_matrix);
#endif
geomutils.cpp:
#include "geomutils.h"
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
void computeConvexHull(Polygon &pts, Polygon &chull) {
chull.clear();
if(pts.size() == 1) {
chull.push_back(pts[0]);
chull.push_back(pts[0]);
return;
} else if(pts.size() == 2) {
chull.push_back(pts[0]);
chull.push_back(pts[1]);
chull.push_back(pts[0]);
return;
}
typedef boost::tuple<double, double> point;
typedef boost::geometry::model::multi_point<point> mpoints;
typedef boost::geometry::model::polygon<point> polygon;
mpoints mpts;
for(int i = 0;i < pts.size();i ++) {
boost::geometry::append(mpts,point(pts[i].x,pts[i].y));
}
polygon hull;
// Polygon is closed
boost::geometry::convex_hull(mpts, hull);
for(auto pt : hull.outer()) {
chull.push_back(Point(pt.get<0>(), pt.get<1>()));
}
}
geomutils.h:
#ifndef GEOMUTILS_H
#define GEOMUTILS_H
#include <vector>
struct Point {
double x,y;
Point(){}
Point(double x, double y):x(x),y(y){}
};
typedef std::vector<Point> Polygon;
void computeConvexHull(Polygon &pts, Polygon &chull);
#endif // GEOMUTILS_H
When I compile the code and try to run it.
Only Done1 gets printed on the console. It neither gives any error nor any message.
Output:
Done1
Hull in -99999:
[(0, 0), (0, 7.14), (4.58, 7.14), (0, 0), ]

There's some issue on your code. First of all in main to correctly initialize the vector you have to use the {} syntax. Further in customComputeConvexHull you are setting values inside the res vector which are not yet present. You have to use push_back to populate res. Below a version of your code which works (I put everything into one cpp file for semplicity.
#include <vector>
//#include "geomutils.h"
//#include "mycode.h"
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
using namespace std;
struct Point {
double x, y;
Point() {}
Point(double x, double y) :x(x), y(y) {}
};
typedef std::vector<Point> Polygon;
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian);
void computeConvexHull(Polygon& pts, Polygon& chull) {
chull.clear();
if (pts.size() == 1) {
chull.push_back(pts[0]);
chull.push_back(pts[0]);
return;
}
else if (pts.size() == 2) {
chull.push_back(pts[0]);
chull.push_back(pts[1]);
chull.push_back(pts[0]);
return;
}
typedef boost::tuple<double, double> point;
typedef boost::geometry::model::multi_point<point> mpoints;
typedef boost::geometry::model::polygon<point> polygon;
mpoints mpts;
for (int i = 0; i < pts.size(); i++) {
boost::geometry::append(mpts, point(pts[i].x, pts[i].y));
}
polygon hull;
// Polygon is closed
boost::geometry::convex_hull(mpts, hull);
for (auto pt : hull.outer()) {
chull.push_back(Point(pt.get<0>(), pt.get<1>()));
}
}
vector< vector<double> > customComputeConvexHull(vector< vector<double> > i_matrix) {
cout << "\nDone1.1";
Polygon custompts, customhull;
for (int r = 0; r < i_matrix.size(); r++) {
custompts.push_back(Point(i_matrix[r][0], i_matrix[r][1]));
}
computeConvexHull(custompts, customhull);
vector< vector<double> > res;
for (int i = 0; i < 3; i++)
{
vector<double> v1{ customhull[i].x, customhull[i].y };
res.push_back(v1);
}
return res;
}
int main()
{
// Create an empty vector
vector< vector<double> > mat, mat2;
vector<double> myRow1{0, 0};
mat.push_back(myRow1);
vector<double> myRow2{ 7.61, 9.48 };
mat.push_back(myRow2);
vector<double> myRow3{ 0, 9.48 };
mat.push_back(myRow3);
cout << "Done1";
mat2 = customComputeConvexHull(mat);
cout << "Done2";
return 0;
}

Related

Implementing K-means in C++

I would be appreciate if someone could help me!
I implement kmeans algorithm in c++.
-The points that I have to split in groups are known.
-I want to make 3 clusters of them.
-But the clusters have to be instantiated randomly in the first time.
When I try it, the following message appears and I can not solve it.
Unhandled exception at 0x00007FF92B484E20 (MengeCore.dll) in menge.exe: 0xC0000005: Access violation writing location 0x0000000000000000.
The problem is in lines when I try to instantiate clusters.
Thank you in advance!!!
#include <cassert>
#include <limits>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <list>
#include <ostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <stdio.h>
using namespace std;
class Point{
private:
double x;
double y;
public:
Point::Point(double x, double y) : x(x), y(y) {}
double Point::getX() const {
return x;
}
double Point::getY() const {
return y;
}
Point::Point() {}
bool Point::operator==(const Point &rhs) const {
return x == rhs.x &&
y == rhs.y;
}
bool Point::operator!=(const Point &rhs) const {
return !(rhs == *this);
}
friend std::ostream &operator<<(std::ostream &os, const Point &point) {
os << "(" << point.x << "," << point.y << ")";
return os;
}
double getDistance(Point &p) {
return sqrt(pow(p.x - this->x, 2) + pow(p.y - this->y, 2));
}
};
class Cluster {
public:
Point centroid;
vector<int> points;
Cluster::Cluster(const Point &centroid, const vector<int> &points) : centroid(centroid), points(points) {}
Cluster::Cluster() {
}
string getPoints() {
string s = "";
for (int p : points) {
s += to_string(p + 1) + " ";
}
return s;
}
Cluster::Cluster(const Point &centroid) : centroid(centroid) {}
};
vector<Point> points{ { 9, 9 },
{ 1, 1 },
{ -1, -1 },
{ 3, 3 },
{ 10, 10 },
{ -2, -2 },
{ 7, 8 },
{ 0.2, 0 },
{-1, 0},
{ 6, 10 } };
vector<Cluster> clusters{};
int main() {
int K=2;
for (int i = 0; i < K; i++)
{
srand(time(NULL));
int RandIndex = rand() % 10; //generates a random number between 0 and 9
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//HERE IS THE PROBLEM
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!
clusters[i].centroid = points[RandIndex];
}
return 0;
}
}
you should did not initialize the size for the cluster vector.
int main()
{
...
int K=2;
clusters.resize(K);
for (int i = 0; i < K; i++)
...
}

c++ segmentation fault trying to access vector

Im trying to create a adjacency representation of a graph.
I wrote a small program using vectors of vectors , however I keep getting "segmentation fault" but the compiler(clang++ version 5.0.1 on Windows) it seems wereever I try to access the vector vertex_matrix its giving a segmentation fault, why is it not being instantiated?
Here is the header:
#ifndef GRAPH_MATRIX
#define GRAPH_MATRIX
#include <vector>
//header for graph represented via adjacency matrix with minimal functionality
class graph
{
public:
graph(int);
~graph();
void add_edge(int v1, int v2, int weight);
void print_graph();
private:
std::vector<std::vector<int>> vertex_matrix;
int num_of_vertices;
int num_of_edges;
};
#endif
Here is the cpp implementation:
#include <iostream>
#include "graph_matrix.h"
#include <climits>
using namespace std;
//header for graph represented via adjacency matrix with minimal functionality
graph::graph(int _num_of_vertices) : num_of_vertices(_num_of_vertices)
{
if (_num_of_vertices==0)
{
_num_of_vertices=10;
}
for (int i = 0; i < _num_of_vertices; i++)
{
vertex_matrix[i]=(vector<int> (_num_of_vertices,INT_MAX));
}
}
graph::~graph()
{
vertex_matrix.clear();
}
void graph::add_edge(int v1, int v2, int weight)
{
//vertex_matrix[v1-1][v2-1] == INT_MAX
vector<int> columnVector = vertex_matrix[v1-1];
if (columnVector[v2-1] == INT_MAX)
{
columnVector[v2-1] = weight;
}
}
void graph::print_graph()
{
cout << "vertex_matrix size:" << vertex_matrix.size() << endl;
for (int i=0; i< num_of_vertices; i++)
{
for (int j = 0; j < num_of_vertices; j++)
{
//vertex_matrix[i][j]
std::vector<int> columnVector = vertex_matrix[i];
if (columnVector[j] != INT_MAX)
{
std::cout << columnVector[j] ;
}
else
{
std::cout << "0";
}
}
std::cout << endl;
}//end for printing
}
Here is the main entry:
#include <iostream>
#include "graph_matrix.h"
using namespace std;
int main ()
{
std::cout << " Matrix representation of graph" << std::endl;
graph _graph(4);
_graph.add_edge(1,2,1);
_graph.add_edge(2,3,1);
_graph.add_edge(3,1,1);
_graph.add_edge(3,3,1);
_graph.add_edge(3,4,1);
_graph.add_edge(4,0,0);
_graph.print_graph();
}
I edited the above code to use pass by reference, however the matrix still prints as 0's.
Please help with pass by reference, updates below:
Header:
#ifndef GRAPH_MATRIX
#define GRAPH_MATRIX
#include <vector>
//header for graph represented via adjacency matrix with minimal functionality
class graph
{
public:
graph(int);
~graph();
void add_edge(int v1, int v2, int weight,std::vector<std::vector<int>> & matrix);
void print_graph();
std::vector<std::vector<int>> vertex_matrix;
private:
int num_of_vertices;
int num_of_edges;
};
#endif
Cpp file:
#include <iostream>
#include "graph_matrix.h"
#include <climits>
using namespace std;
//header for graph represented via adjacency matrix with minimal functionality
graph::graph(int _num_of_vertices) : num_of_vertices(_num_of_vertices) {
if (num_of_vertices == 0) {
num_of_vertices = 10;
}
for (int i = 0; i < num_of_vertices; i++) {
std::vector<std::vector<int>>& matrix = vertex_matrix;
matrix.push_back(vector<int> (num_of_vertices, INT_MAX));
}
}
graph::~graph() {
std::vector<std::vector<int>>& matrix = vertex_matrix;
matrix.clear();
}
void graph::add_edge(int v1, int v2, int weight,std::vector<std::vector<int>> & _matrix) {
//vertex_matrix[v1-1][v2-1] == INT_MAX
vector<int> columnVector = _matrix[v1 - 1];
if (columnVector[v2 - 1] == INT_MAX) {
columnVector[v2 - 1] = weight;
}
}
void graph::print_graph() {
std::vector<std::vector<int>>& matrix = vertex_matrix;
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix.size(); j++) {
//vertex_matrix[i][j]
std::vector<int> columnVector = matrix[i];
if (columnVector[j] != INT_MAX) {
std::cout << columnVector[j];
} else {
std::cout << "0";
}
}
std::cout << endl;
}//end for printing
}
main:
#include <iostream>
#include "graph_matrix.h"
using namespace std;
int main ()
{
std::cout << " Matrix representation of graph" << std::endl;
graph _graph(4);
std::vector<std::vector<int>>& m = _graph.vertex_matrix;
_graph.add_edge(1,2,1,m);
_graph.add_edge(2,3,1,m);
_graph.add_edge(3,1,1,m);
_graph.add_edge(3,3,1,m);
_graph.add_edge(3,4,1,m);
_graph.add_edge(4,0,0,m);
_graph.print_graph();
}
Any help will be appreciated.
Thanks
You create an empty vector and then try to access elements in it. Change your constructor to
graph::graph(size_t _num_of_vertices) :
vertex_matrix(
std::vector<std::vector<int>>(
_num_of_vertices,std::vector<int>(_num_of_vertices)
)
)
{}
to create a correctly sized vector.
Also in case _num_vertices == 0 you set it to 10 but thats after you initialized the member num_vertices so you leave the object in an inconsistent state. There are different ways to fix that, I would probably just throw an exception when the number of vertices passed is zero, or just ignore it. User wants a zero sized matrix? Why not?
Moreover the size should be unsigned not signed, there is size_t for container sizes. Even better you shouldnt have that member at all, because a vector already knows its size, the only reason to repeat that information is to introduce mistakes ;)

Creating multiple instances of c++ library

I am trying to create multiple instances of a static c++ library I wrote, but I can't create multiple instances of it... When I create two instances and write different data to them, I read the same data from both of the instances. Here is my code:
.cpp file:
// MathFuncsLib.cpp
// compile with: cl /c /EHsc MathFuncsLib.cpp
// post-build command: lib MathFuncsLib.obj
/*
DECLARING VECTORS
|3,6,4|
|9,1,5|
|2,0,2|
|5,3,6|
Should be inputted as:
int a[] = {3,6,4,9,1,5,2,0,2,5,3,6} with x = 3 and y = 4
Inputting training vals:
|0.1 (inp1),0.1 (inp2) ,0.1 (targeted output)| depends on the number of inputs and outputs
|9,1,5|
|2,0,2|
|5,3,6|
*/
//#include "stdafx.h"
#include "vector.h"
#include "iostream"
#define DEBUG
#include <stdexcept>
//using namespace std;
double* vectorLib::arrayPtr;
int vectorLib::x;
int vectorLib::y;
vectorLib::vectorLib(int xInp, int yInp) {
vectorLib::arrayPtr = new double[xInp*yInp];
vectorLib::x = xInp;
vectorLib::y = yInp;
//return 0;
}
double vectorLib::sigmoid(double inp) {
return 1 / (1 + exp(-inp));
}
double* vectorLib::getArrayPtr() {
return vectorLib::arrayPtr;
}
double vectorLib::read(int xInp, int yInp) {
#ifdef DEBUG
if (xInp >= vectorLib::x) {
std::cout << "X_OUT_OF_BOUNDS_VECTOR_READ\n";
while (1);
}
if (yInp >= vectorLib::y) {
std::cout << "X_OUT_OF_BOUNDS_VECTOR_READ\n";
while (1);
}
#endif // DEBUG
return *(arrayPtr + xInp + vectorLib::x*yInp);
}
void vectorLib::write(int xInp, int yInp, double data) {
#ifdef DEBUG
if (xInp >= vectorLib::x) {
std::cout << "X_OUT_OF_BOUNDS_VECTOR_WRITE\n";
while (1);
}
if (yInp >= vectorLib::y) {
std::cout << "X_OUT_OF_BOUNDS_VECTOR_WRITE\n";
while (1);
}
#endif // DEBUG
vectorLib::arrayPtr[xInp + vectorLib::x*yInp] = data;
}
void vectorLib::writeArr(double* inpArr) {
int i;
for (i = 0; i < vectorLib::x*vectorLib::y; i++) {
vectorLib::arrayPtr[i] = *(inpArr + i);
}
}
void vectorLib::sigmoidVect() {
int yy;
int xx;
for (yy = 0; yy < vectorLib::y; yy++) {
for (xx = 0; xx < vectorLib::x; xx++) {
write(xx, yy, sigmoid(read(xx, yy)));
}
}
write(0, vectorLib::y - 1, 1);
}
int vectorLib::getX() {
return vectorLib::x;
}
int vectorLib::getY() {
return vectorLib::y;
}
int vectorLib::totalVectSize() {
return vectorLib::x * vectorLib::y;
}
void vectorLib::printVector() {
int yy;
int xx;
for (yy = 0; yy < y; yy++) {
for (xx = 0; xx < x; xx++) {
std::cout << vectorLib::read(xx, yy);
if (xx + 1 != x) {
std::cout << ",";
}
}
std::cout << "\n";
}
}
vectorLib* vectorLib::vectorMult(vectorLib* vect1, vectorLib* vect2) {
#ifdef DEBUG
if (vect1->getX() != vect2->getY()) {
std::cout << "INPUTS_DONT_MATCH_VECTORMULT\n";
while (1);
}
#endif // DEBUG
vectorLib toRet(vect1->getX(), vect2->getY());
int i;
for (i = 0; i < vect2->getX(); i++) {
int p;
for (p = 0; p < vect1->getY(); p++) {
double tempOut = 0;
int q;
for (q = 0; q < vect1->getX(); q++)
{
tempOut += vect1->read(q, p) * vect2->read(i, q);
}
toRet.write(i, p, tempOut);
}
}
return &toRet;
}
.h file:
//#include "stdafx.h"
using namespace std;
class vectorLib
{
//int x, y;
public:
static double* arrayPtr;
static int x;
static int y;
//Constructor takes x and y of the vector
vectorLib(int xInp, int yInp);
//The pointer to the array that holds all the doubles in the vector
static double* getArrayPtr();
//Read the vector at a specified x and y
static double read(int xInp, int yInp);
//Write one double to a specific location
static void write(int xInp, int yInp, double data);
//Write the array inside the vector class
static void writeArr(double* inpArr);
//Takes sigmoid of whole vector
static void sigmoidVect();
//Returns x of vector
static int getX();
//Returns y of vector
static int getY();
//Returns total size of vector
static int totalVectSize();
//Returns a vector pointer to the multiplication result
static vectorLib* vectorMult(vectorLib* vect1, vectorLib* vect2);
//Prints vector
static void printVector();
private:
static double sigmoid(double inp);
};
Main file:
#define DEBUG
#include "stdafx.h"
#include "vector.h"
#include "iostream"
using namespace std;
int main()
{
vectorLib testVectLol(1, 3);
vectorLib testVect(3, 4);
double vectInp[] = { 1,1,1,
1,1,1,
1,1,1,
1,1,1};
double vectInp2[] = { 0.5,0.5,0.5 };
testVect.writeArr(vectInp);
testVectLol.writeArr(vectInp2);
testVect.printVector();// Both print 0.5, 0.5, 0,5
testVectLol.printVector();// Both print 0.5, 0.5, 0,5
while (1);
return 0;
}
Thanks in advance! I've been struggling with this for hours. I would really appreciate any help!
Jasper

For-Loop Segmentation -- Excessive run ( i < SIZE, but i = SIZE)

This is a function in a program replicating Sierpinski's gasket. This function is supposed to attach the points in the triangle for the fractal.
After much deliberation I've figured out where the issue lies:
void add_pts(int &x, int &y)
{
Vector_ref<Rectangle> pt;
for (int i = 0; i < POINTS; ++i)
{
pt_test; //generates changing x, y vals within the limits of the triangle
cout << "pass" << i <<endl;
pt.push_back(new Rectangle(Point(x,y),5,5));
pt[i].set_fill_color(Color::yellow);
win.attach(pt[i]);
}
}
The output is "pass1...pass[POINTS-1]", but for whatever reason it runs when i = POINTS and runs into the segmentation error. I have no clue as to why. Can anyone assist, please?
Here is my code. The pt_test and coord are a bit sloppy but seeing as it can't run properly it's very hard to ascertain what I can streamline.
#include <stdlib.h>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <time.h>
#include "Simple_window.h"
#include "Graph.h"
#include "Point.h"
#include "GUI.h"
#include "Window.h"
using namespace std;
using namespace Graph_lib;
// globals
const int POINTS = 5000;
unsigned int seed = (unsigned int)time(0);
Simple_window win(Point(100,100),1100,700,"Homework 9");
// function declarations
double random(unsigned int &seed);
bool coords(int &x, int &y);
void pt_test(int x, int y);
void add_pts(int &x, int &y);
int main()
{
int x, y;
// title
Text title(Point(400,50), "The Sierpinski Gasket");
title.set_font(Graph_lib::Font::helvetica_bold);
title.set_font_size(25);
title.set_color(Color::cyan);
win.attach(title);
// triangle
Closed_polyline tri;
tri.add(Point(250,75)); // A
tri.add(Point(850,75)); // B
tri.add(Point(550,675)); // C
tri.set_fill_color(Color::white);
tri.set_color(Color::dark_red);
tri.set_style(Line_style(Line_style::solid,3));
win.attach(tri);
// vertices
Text vert_a(Point(225,70), "A (250, 75)");
vert_a.set_font(Graph_lib::Font::helvetica_bold);
vert_a.set_font_size(15);
vert_a.set_color(Color::cyan);
Text vert_b(Point(855,70), "B (850, 75)");
vert_b.set_font(Graph_lib::Font::helvetica_bold);
vert_b.set_font_size(15);
vert_b.set_color(Color::cyan);
Text vert_c(Point(575,670), "C (550, 675)");
vert_c.set_font(Graph_lib::Font::helvetica_bold);
vert_c.set_font_size(15);
vert_c.set_color(Color::cyan);
win.attach(vert_a);
win.attach(vert_b);
win.attach(vert_c);
// point selection
add_pts(x, y);
// window title and display
win.wait_for_button();
}
double random(unsigned int &seed)
{
const int MODULUS = 15749;
const int MULTIPLIER = 69069;
const int INCREMENT = 1;
seed = ((MULTIPLIER*seed)+INCREMENT)%MODULUS;
return double(seed)/double(MODULUS);
}
bool coords(int &x, int &y) // generates the points
{
x = int(251 + 600*random(seed));
y = int(76 + 600*random(seed));
if( y > (2*x-425) && x<= 550 || x>=550 && y < (-2*x + 1775))
return true;
}
void pt_test(int x, int y) // tests the points until they are within the range
{
coords;
while(coords == 0)
coords;
}
void add_pts(int &x, int &y) // attaches the points as shapes
{
Vector_ref<Rectangle> pt;
for (int i = 0; i < POINTS; ++i)
{
pt_test;
cout << "i == " << i << " points == " << POINTS << endl;
pt.push_back(new Rectangle(Point(x,y),5,5));
pt[i].set_fill_color(Color::yellow);
win.attach(pt[i]);
}
}
I've also noticed that the function add_pts doesn't work when the body is in the loop, but if you put the body in int_main(), it runs indefinitely but doesn't reach the segmentation fault as quickly, if at all.

Creating boost.geometry.model.polygon from 2D C List

Supposed I have the following dataset
double * data = (double *) malloc(sizeof(double) * 100 * 2);
for (ii = 0; ii < 100; ii++) {
data[2*ii] = ii;
data[2*ii + 1] = ii;
}
how can I create a boost polygon from this data?
thanks
A complete example
#include <iostream>
#include <boost/polygon/polygon.hpp>
#include <vector>
// Some typedefs
namespace bpl = boost::polygon;
typedef bpl::polygon_data<double> Polygon;
typedef bpl::polygon_traits<Polygon>::point_type Point;
int main() {
// Your C-style data (assumed (x,y) pairs)
double * data = (double *) malloc(sizeof(double) * 100 * 2);
for (int ii = 0; ii < 100; ii++) {
data[2*ii] = ii;
data[2*ii + 1] = ii;
}
// Convert to points
std::vector<Point> points;
for (int i=0;i<100;++i)
points.push_back(Point(data[2*i],data[2*i+1]));
// Create a polygon
Polygon polygon;
polygon.set(points.begin(),points.end());
// Do something with the polygon
std::cout << "Perimeter : " << bpl::perimeter(polygon) << std::endl;
std::cout << "Area : " << bpl::area(polygon) << std::endl;
return 0;
}
Just to illustrate the flexibility you actually have: with a bit of extra typedef work, its possible to define your own pair-of-doubles point type which can be aliased onto your data, which avoids the intermediate copy...
#include <iostream>
#include <boost/polygon/polygon.hpp>
#include <vector>
// Define a point type which can be aliased to your 'C' points
struct Pt {
double x;
double y;
};
// Some typedefs
namespace bpl = boost::polygon;
typedef bpl::polygon_data<double> Polygon;
// Add the necessary to use Pt
namespace boost {
namespace polygon {
template <> struct geometry_concept<Pt> {typedef point_concept type;};
template <> struct point_traits<Pt> {
typedef double coordinate_type;
static inline coordinate_type get(const Pt& pt,orientation_2d orient) {
return (orient == HORIZONTAL ? pt.x : pt.y);
}
};
template <> struct point_mutable_traits<Pt> {
static inline void set(Pt& pt, orientation_2d orient, int value) {
if(orient == HORIZONTAL)
pt.x = value;
else
pt.y = value;
}
static inline Pt construct(double x,double y) {
Pt r;
r.x=x;
r.y=y;
return r;
}
};
}
}
int main() {
// Your C-style data (assumed (x,y) pairs)
double * data = (double *) malloc(sizeof(double) * 100 * 2);
for (int ii = 0; ii < 100; ii++) {
data[2*ii] = ii;
data[2*ii + 1] = ii;
}
// Reinterpret your data as an array of Pt
const Pt*const pts=reinterpret_cast<const Pt*>(data);
// Create a polygon
Polygon polygon;
polygon.set(pts,pts+100);
// Do something with the polygon
std::cout << "Perimeter : " << bpl::perimeter(polygon) << std::endl;
std::cout << "Area : " << bpl::area(polygon) << std::endl;
return 0;
}
And this trend could be continued to a custom polygon class.