我有一个基础多边形B
和许多其他多边形p_0, p_1, p_2, ...
,每个多边形都有一个权重w_0, w_1, w_2, ...
。
我想:
B
和p_0
的交叉区域,并将此区域乘以w_0
。B
和p_0
形成一个新的多边形B_1
B
,其中p_0
被切除。B_1
和p_1
的交叉区域,并将此区域乘以w_1
。B_1
和p_1
形成一个新的多边形B_2
B_1
,其中p_1
被切除。我正在尝试使用 boost :: polygon 库来执行此操作。他们举例说明了如何进行交叉here和差异here。
交叉函数定义如下:
bool intersection(Geometry1 const & geometry1, Geometry2 const & geometry2, GeometryOut & geometry_out)
为了在循环中使用intersection
并测量区域,我认为我需要将GeometryOut
类型转换为Geometry1
类型。目前尚不清楚如何做到这一点。
到目前为止我的代码的简化版本是:
#include <boost/polygon/polygon.hpp>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
#include <iostream>
#include <vector>
#include <cstdlib>
namespace gtl = boost::polygon;
typedef gtl::polygon_data<float> Polygon;
Polygon MakeBox(float xmin, float ymin, float xmax, float ymax){
typedef gtl::polygon_traits<Polygon>::point_type Point;
Point pts[] = {
gtl::construct<Point>(xmin, ymin),
gtl::construct<Point>(xmin, ymax),
gtl::construct<Point>(xmax, ymax),
gtl::construct<Point>(xmax, ymin)
};
Polygon poly;
gtl::set_points(poly, pts, pts+4);
return poly;
}
double GetValue(const Polygon &base, const std::vector<Polygon> &polys, const std::vector<double> &vals){
double value = 0;
double base_area = gtl::area(base);
boost::geometry::model::multi_polygon<Polygon> multipoly, isect, multipolynew;
//I've also tried the following line in place of the line above: doesn't work.
//std::deque<Polygon> multipoly, isect, multipolynew;
multipoly.push_back(base);
for(int i=0;i<polys.size();i++){
boost::geometry::intersection(multipoly, polys[i], isect);
value += gtl::area(isect)/base_area*vals[i];
boost::geometry::difference(multipoly,polys[i],multipolynew);
multipoly = multipolynew;
}
return value;
}
int main() {
Polygon base = MakeBox(0,0,10,10); //Base polygon
std::vector<Polygon> polys;
std::vector<double> vals;
//Set up some random input
for(int i=0;i<3;i++){
int xmin=rand()%10;
int xmax=xmin+rand()%10;
int ymin=rand()%10;
int ymax=ymin+rand()%10;
polys.push_back(MakeBox(xmin,ymin,xmax,ymax));
vals.push_back(rand()%100);
}
std::cout<<GetValue(base,polys,vals)<<std::endl;
}
答案 0 :(得分:3)
从各个角度来看,我会得出结论,这是Boost几何的限制adaptation of Boost Polygon types。
即使用Boost Polygon(boost::polygon_data<>
)中更全功能的多边形概念实现替换“vanilla”环类型(boost::polygon_with_holes_data<>
),也不允许将修改后的Polygon用于{ {1}}实例化。
如果您有兴趣,我会在搜索过程中发现更多信息:
使用Boost Geometry模型而不是Boost Polygon类型时,您可以按照自己的意愿行事。将boost::geometry::multi_poygon<T>
直接用作Geometry没有问题:
<强> Live On Coliru 强>
multi_polygon
或者,您可以实现相交的O(n log n)访问版本,该版本与多边形的两个集合(例如矢量)相交,即使它们不是单个几何体。
这个邮件列表交换了这个http://boost-geometry.203548.n3.nabble.com/intersection-of-two-vectors-of-polygons-tp2875513p2880997.html的详细信息(即使这里的用例是这样的,单个多边形可以与唯一的信息位(#include <fstream>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/io/io.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/foreach.hpp>
typedef boost::geometry::model::d2::point_xy<double> PointType;
using Polygon = boost::geometry::model::polygon<PointType>;
Polygon MakeBox(float xmin, float ymin, float xmax, float ymax){
Polygon poly;
poly.outer().assign({
{xmin, ymin},
{xmin, ymax},
{xmax, ymax},
{xmax, ymin}
});
return poly;
}
double GetValue(const Polygon &base, const std::vector<Polygon> &polys, const std::vector<double> &vals){
double value = 0;
double base_area = boost::geometry::area(base);
boost::geometry::model::multi_polygon<Polygon> multipoly, isect, multipolynew;
multipoly.push_back(base);
for(size_t i=0;i<polys.size();i++){
boost::geometry::intersection(multipoly, polys[i], isect);
value += boost::geometry::area(isect)/base_area*vals[i];
boost::geometry::difference(multipoly,polys[i],multipolynew);
multipoly = multipolynew;
}
return value;
}
int main()
{
Polygon base = MakeBox(0,0,10,10); //Base polygon
std::vector<Polygon> polys;
std::vector<double> vals;
//Set up some random input
for(int i=0;i<3;i++){
int xmin=rand()%10;
int xmax=xmin+rand()%10;
int ymin=rand()%10;
int ymax=ymin+rand()%10;
polys.push_back(MakeBox(xmin,ymin,xmax,ymax));
vals.push_back(rand()%100);
}
std::cout<<GetValue(base,polys,vals)<<std::endl;
}
s)相关联,这很难做到id
S)。
以下是对交叉点有效的代码的简化修改。我想你需要为multi_polygon
调用(?)做类似的方法。我将把它作为读者的练习。
<强> Live On Coliru 强>
另一个相关主题可能是http://boost-geometry.203548.n3.nabble.com/Unioning-many-polygons-td3405482.html