提升多边形交集 API 的工作方式与其应有的相反
boost polygon intersection API is working in opposite way of what it should be
我不确定为什么下面代码示例中的提升多边形交集只是给出相反的输出,即它给出的区域与交集相反。
我不知道我的多边形数据是否有问题,因为我觉得一切都很好(但不确定您是否能发现任何奇怪的地方)。
您可以取消注释代码以查看 2 个多边形的外观。输出可以在文件 my_map.svg 中看到,它只会显示 2 个多边形之间交集的反面。不确定为什么它的行为相反。
#include <iostream>
#include <fstream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
int main()
{
typedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > polygon;
polygon a, b;
boost::geometry::read_wkt("POLYGON((422.029 420.829,416.779 427.824,413.079 432.754,411.514 434.839,405.294 443.123,367.717 493.174,361.119 501.961,359.867 503.693,349.783 498.44,328.039 487.113,312.182 481.212,295.134 477.466,278.859 475.139,266.868 475.801,187.698 491.788,166.692 495.595,157.994 464.487,147.902 436.336,139.553 416.747,117.365 366.518,95.1775 316.288,68.2962 245.995,45.4972 177.281,31.9009 125.252,24.7675 98.0465,7.031 30.4037,-5.09537 -23.5814,-13.3492 -74.931,-22.0924 -132.107,-30.068 -226.135,-30.8215 -230.193,-33.1719 -318.815,-35.5218 -407.437,-19.2902 -403.222,36.0998 -393.283,126.809 -387.227,145.351 -390.15,164.088 -394.348,231.549 -417.759,299.009 -441.17,298.703 -456.121,302.675 -457.547,346.766 -473.386,395.71 -490.966,444.654 -508.547,456.541 -512.812,475.159 -513.201,481.397 -513.329,485.21 -513.408,490.793 -513.523,508.346 -513.874,508.437 -513.876,515.036 -514.009,517.093 -514.051,524.719 -514.205,604.376 -529.072,619.023 -527.544,640.877 -516.607,706.036 -517.941,771.196 -519.276,773.204 -519.323,773.291 -515.039,755.121 -444.833,734.542 -425.062,730.418 -414.227,750.154 -385.311,751.05 -303.546,749.413 -300.971,751.095 -299.408,803.104 -251.069,855.113 -202.731,892.855 -140.167,930.598 -77.6028,939.232 -69.3115,938.067 -67.6543,905.009 -20.5411,871.951 26.572,816.821 105.141,761.691 183.71,706.561 262.28,702.345 264.782,675.313 280.828,671.489 283.098,670.221 282.255,626.86 253.44,583.5 224.624,545.885 184.348,508.27 144.071,470.699 141.098,468.429 140.919,466.877 142.813,406.125 216.993,394.011 244.292,392.277 261.076,357.41 315.935,359.299 316.721,412.859 339.189,466.419 361.656,465.655 362.675,465.175 363.315,465.094 363.422,464.335 364.435,460.925 368.981,450.837 382.429,447.236 387.23,443.635 392.03,440.034 396.83,436.434 401.63,432.832 406.431,429.231 411.23,425.63 416.03,422.029 420.829))", a);
boost::geometry::read_wkt("POLYGON((0 504,861 504,861 -0,0 -0,0 504))", b);
std::deque<polygon> output;
boost::geometry::intersection(a, b, output);
// Declare a stream and an SVG mapper
std::ofstream svg("my_map.svg");
boost::geometry::svg_mapper<boost::geometry::model::d2::point_xy<double>> mapper(svg, 400, 400);
// Add geometries such that all these geometries fit on the map
//mapper.add(a);
//mapper.add(b);
mapper.add(output[0].outer());
// Draw the geometries on the SVG map, using a specific SVG style
//mapper.map(a, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
//mapper.map(b, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
mapper.map(output[0].outer(), "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
return 0;
}
点的顺序很重要。
您正在使用 polygon
模型,其 ClockWise
参数默认设置为 true
。
多边形的点方向 b
满足此条件。但是,对于多边形 a
,您使用的是逆时针方式。可以通过boost::geometry::correct
:
更正
boost::geometry::read_wkt("POLYGON((422.029 420.829,508. ...",a);
boost::geometry::correct(a);
你不是对立,而是不明行为。那是因为点的方向是无效的:
#include <iostream>
#include <fstream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry;
namespace bgm = bg::model;
int main()
{
using Point = bgm::d2::point_xy<double>;
using Polygon = bgm::polygon<Point>;
using Multi = bgm::multi_polygon<Polygon>;
Polygon a;
Polygon b;
boost::geometry::read_wkt(
"POLYGON((422.029 420.829,416.779 427.824,413.079 432.754,411.514 "
"434.839,405.294 443.123,367.717 493.174,361.119 501.961,359.867 "
"503.693,349.783 498.44,328.039 487.113,312.182 481.212,295.134 "
"477.466,278.859 475.139,266.868 475.801,187.698 491.788,166.692 "
"495.595,157.994 464.487,147.902 436.336,139.553 416.747,117.365 "
"366.518,95.1775 316.288,68.2962 245.995,45.4972 177.281,31.9009 "
"125.252,24.7675 98.0465,7.031 30.4037,-5.09537 -23.5814,-13.3492 "
"-74.931,-22.0924 -132.107,-30.068 -226.135,-30.8215 -230.193,-33.1719 "
"-318.815,-35.5218 -407.437,-19.2902 -403.222,36.0998 -393.283,126.809 "
"-387.227,145.351 -390.15,164.088 -394.348,231.549 -417.759,299.009 "
"-441.17,298.703 -456.121,302.675 -457.547,346.766 -473.386,395.71 "
"-490.966,444.654 -508.547,456.541 -512.812,475.159 -513.201,481.397 "
"-513.329,485.21 -513.408,490.793 -513.523,508.346 -513.874,508.437 "
"-513.876,515.036 -514.009,517.093 -514.051,524.719 -514.205,604.376 "
"-529.072,619.023 -527.544,640.877 -516.607,706.036 -517.941,771.196 "
"-519.276,773.204 -519.323,773.291 -515.039,755.121 -444.833,734.542 "
"-425.062,730.418 -414.227,750.154 -385.311,751.05 -303.546,749.413 "
"-300.971,751.095 -299.408,803.104 -251.069,855.113 -202.731,892.855 "
"-140.167,930.598 -77.6028,939.232 -69.3115,938.067 -67.6543,905.009 "
"-20.5411,871.951 26.572,816.821 105.141,761.691 183.71,706.561 "
"262.28,702.345 264.782,675.313 280.828,671.489 283.098,670.221 "
"282.255,626.86 253.44,583.5 224.624,545.885 184.348,508.27 "
"144.071,470.699 141.098,468.429 140.919,466.877 142.813,406.125 "
"216.993,394.011 244.292,392.277 261.076,357.41 315.935,359.299 "
"316.721,412.859 339.189,466.419 361.656,465.655 362.675,465.175 "
"363.315,465.094 363.422,464.335 364.435,460.925 368.981,450.837 "
"382.429,447.236 387.23,443.635 392.03,440.034 396.83,436.434 "
"401.63,432.832 406.431,429.231 411.23,425.63 416.03,422.029 420.829))",
a);
bg::read_wkt("POLYGON((0 504,861 504,861 -0,0 -0,0 504))", b);
if (std::string reason; !bg::is_valid(a, reason)) {
std::cout << "Correcting a: " << reason << "\n";
bg::correct(a);
assert(bg::is_valid(a));
}
if (std::string reason; !bg::is_valid(b, reason)) {
std::cout << "Correcting b: " << reason << "\n";
bg::correct(b);
assert(bg::is_valid(b));
}
Multi c;
bg::intersection(a, b, c);
{
// Declare a stream and an SVG mapper
std::ofstream svg("my_map.svg");
bg::svg_mapper<Point> mapper(svg, 400, 400);
// Add geometries such that all these geometries fit on the map
mapper.add(a);
mapper.add(b);
mapper.add(c);
// Draw the geometries on the SVG map, using a specific SVG style
mapper.map(a, "fill-opacity:0.3;fill:rgb(51,0,0);stroke:rgb(51,0,0);stroke-width:2");
mapper.map(b, "fill-opacity:0.3;fill:rgb(0,51,0);stroke:rgb(0,51,0);stroke-width:2");
mapper.map(c, "fill-opacity:0.3;fill:rgb(0,0,51);stroke:rgb(0,0,51);stroke-width:2");
}
}
版画
Correcting a: Geometry has wrong orientation
并生成以下 SVG:
我不确定为什么下面代码示例中的提升多边形交集只是给出相反的输出,即它给出的区域与交集相反。
我不知道我的多边形数据是否有问题,因为我觉得一切都很好(但不确定您是否能发现任何奇怪的地方)。
您可以取消注释代码以查看 2 个多边形的外观。输出可以在文件 my_map.svg 中看到,它只会显示 2 个多边形之间交集的反面。不确定为什么它的行为相反。
#include <iostream>
#include <fstream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
int main()
{
typedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > polygon;
polygon a, b;
boost::geometry::read_wkt("POLYGON((422.029 420.829,416.779 427.824,413.079 432.754,411.514 434.839,405.294 443.123,367.717 493.174,361.119 501.961,359.867 503.693,349.783 498.44,328.039 487.113,312.182 481.212,295.134 477.466,278.859 475.139,266.868 475.801,187.698 491.788,166.692 495.595,157.994 464.487,147.902 436.336,139.553 416.747,117.365 366.518,95.1775 316.288,68.2962 245.995,45.4972 177.281,31.9009 125.252,24.7675 98.0465,7.031 30.4037,-5.09537 -23.5814,-13.3492 -74.931,-22.0924 -132.107,-30.068 -226.135,-30.8215 -230.193,-33.1719 -318.815,-35.5218 -407.437,-19.2902 -403.222,36.0998 -393.283,126.809 -387.227,145.351 -390.15,164.088 -394.348,231.549 -417.759,299.009 -441.17,298.703 -456.121,302.675 -457.547,346.766 -473.386,395.71 -490.966,444.654 -508.547,456.541 -512.812,475.159 -513.201,481.397 -513.329,485.21 -513.408,490.793 -513.523,508.346 -513.874,508.437 -513.876,515.036 -514.009,517.093 -514.051,524.719 -514.205,604.376 -529.072,619.023 -527.544,640.877 -516.607,706.036 -517.941,771.196 -519.276,773.204 -519.323,773.291 -515.039,755.121 -444.833,734.542 -425.062,730.418 -414.227,750.154 -385.311,751.05 -303.546,749.413 -300.971,751.095 -299.408,803.104 -251.069,855.113 -202.731,892.855 -140.167,930.598 -77.6028,939.232 -69.3115,938.067 -67.6543,905.009 -20.5411,871.951 26.572,816.821 105.141,761.691 183.71,706.561 262.28,702.345 264.782,675.313 280.828,671.489 283.098,670.221 282.255,626.86 253.44,583.5 224.624,545.885 184.348,508.27 144.071,470.699 141.098,468.429 140.919,466.877 142.813,406.125 216.993,394.011 244.292,392.277 261.076,357.41 315.935,359.299 316.721,412.859 339.189,466.419 361.656,465.655 362.675,465.175 363.315,465.094 363.422,464.335 364.435,460.925 368.981,450.837 382.429,447.236 387.23,443.635 392.03,440.034 396.83,436.434 401.63,432.832 406.431,429.231 411.23,425.63 416.03,422.029 420.829))", a);
boost::geometry::read_wkt("POLYGON((0 504,861 504,861 -0,0 -0,0 504))", b);
std::deque<polygon> output;
boost::geometry::intersection(a, b, output);
// Declare a stream and an SVG mapper
std::ofstream svg("my_map.svg");
boost::geometry::svg_mapper<boost::geometry::model::d2::point_xy<double>> mapper(svg, 400, 400);
// Add geometries such that all these geometries fit on the map
//mapper.add(a);
//mapper.add(b);
mapper.add(output[0].outer());
// Draw the geometries on the SVG map, using a specific SVG style
//mapper.map(a, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
//mapper.map(b, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
mapper.map(output[0].outer(), "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
return 0;
}
点的顺序很重要。
您正在使用 polygon
模型,其 ClockWise
参数默认设置为 true
。
多边形的点方向 b
满足此条件。但是,对于多边形 a
,您使用的是逆时针方式。可以通过boost::geometry::correct
:
boost::geometry::read_wkt("POLYGON((422.029 420.829,508. ...",a);
boost::geometry::correct(a);
你不是对立,而是不明行为。那是因为点的方向是无效的:
#include <iostream>
#include <fstream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry;
namespace bgm = bg::model;
int main()
{
using Point = bgm::d2::point_xy<double>;
using Polygon = bgm::polygon<Point>;
using Multi = bgm::multi_polygon<Polygon>;
Polygon a;
Polygon b;
boost::geometry::read_wkt(
"POLYGON((422.029 420.829,416.779 427.824,413.079 432.754,411.514 "
"434.839,405.294 443.123,367.717 493.174,361.119 501.961,359.867 "
"503.693,349.783 498.44,328.039 487.113,312.182 481.212,295.134 "
"477.466,278.859 475.139,266.868 475.801,187.698 491.788,166.692 "
"495.595,157.994 464.487,147.902 436.336,139.553 416.747,117.365 "
"366.518,95.1775 316.288,68.2962 245.995,45.4972 177.281,31.9009 "
"125.252,24.7675 98.0465,7.031 30.4037,-5.09537 -23.5814,-13.3492 "
"-74.931,-22.0924 -132.107,-30.068 -226.135,-30.8215 -230.193,-33.1719 "
"-318.815,-35.5218 -407.437,-19.2902 -403.222,36.0998 -393.283,126.809 "
"-387.227,145.351 -390.15,164.088 -394.348,231.549 -417.759,299.009 "
"-441.17,298.703 -456.121,302.675 -457.547,346.766 -473.386,395.71 "
"-490.966,444.654 -508.547,456.541 -512.812,475.159 -513.201,481.397 "
"-513.329,485.21 -513.408,490.793 -513.523,508.346 -513.874,508.437 "
"-513.876,515.036 -514.009,517.093 -514.051,524.719 -514.205,604.376 "
"-529.072,619.023 -527.544,640.877 -516.607,706.036 -517.941,771.196 "
"-519.276,773.204 -519.323,773.291 -515.039,755.121 -444.833,734.542 "
"-425.062,730.418 -414.227,750.154 -385.311,751.05 -303.546,749.413 "
"-300.971,751.095 -299.408,803.104 -251.069,855.113 -202.731,892.855 "
"-140.167,930.598 -77.6028,939.232 -69.3115,938.067 -67.6543,905.009 "
"-20.5411,871.951 26.572,816.821 105.141,761.691 183.71,706.561 "
"262.28,702.345 264.782,675.313 280.828,671.489 283.098,670.221 "
"282.255,626.86 253.44,583.5 224.624,545.885 184.348,508.27 "
"144.071,470.699 141.098,468.429 140.919,466.877 142.813,406.125 "
"216.993,394.011 244.292,392.277 261.076,357.41 315.935,359.299 "
"316.721,412.859 339.189,466.419 361.656,465.655 362.675,465.175 "
"363.315,465.094 363.422,464.335 364.435,460.925 368.981,450.837 "
"382.429,447.236 387.23,443.635 392.03,440.034 396.83,436.434 "
"401.63,432.832 406.431,429.231 411.23,425.63 416.03,422.029 420.829))",
a);
bg::read_wkt("POLYGON((0 504,861 504,861 -0,0 -0,0 504))", b);
if (std::string reason; !bg::is_valid(a, reason)) {
std::cout << "Correcting a: " << reason << "\n";
bg::correct(a);
assert(bg::is_valid(a));
}
if (std::string reason; !bg::is_valid(b, reason)) {
std::cout << "Correcting b: " << reason << "\n";
bg::correct(b);
assert(bg::is_valid(b));
}
Multi c;
bg::intersection(a, b, c);
{
// Declare a stream and an SVG mapper
std::ofstream svg("my_map.svg");
bg::svg_mapper<Point> mapper(svg, 400, 400);
// Add geometries such that all these geometries fit on the map
mapper.add(a);
mapper.add(b);
mapper.add(c);
// Draw the geometries on the SVG map, using a specific SVG style
mapper.map(a, "fill-opacity:0.3;fill:rgb(51,0,0);stroke:rgb(51,0,0);stroke-width:2");
mapper.map(b, "fill-opacity:0.3;fill:rgb(0,51,0);stroke:rgb(0,51,0);stroke-width:2");
mapper.map(c, "fill-opacity:0.3;fill:rgb(0,0,51);stroke:rgb(0,0,51);stroke-width:2");
}
}
版画
Correcting a: Geometry has wrong orientation
并生成以下 SVG: