从2D C列表创建boost.geometry.model.polygon

时间:2012-09-17 17:22:09

标签: c++ boost geometry boost-geometry

假设我有以下数据集

double * data = (double *) malloc(sizeof(double) * 100 * 2);
for (ii = 0; ii < 100; ii++) {
    data[2*ii] = ii;
    data[2*ii + 1] = ii;
}

如何从这些数据创建一个提升多边形?

感谢

1 个答案:

答案 0 :(得分:8)

一个完整的例子

#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;
}

只是为了说明你实际拥有的灵活性:通过一些额外的typedef工作,可以定义你自己的双精度点类型,它可以别名到你的数据上,这可以避免中间副本... < / p>

#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;
}

这种趋势可以持续到custom polygon class