- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
尝试从环的底部到顶部裁剪一个环 (50%),但结果并不像我预期的那样有效。
我的解决方案是
using bg_point_type = boost::geometry::model::d2::point_xy<double>;
using bg_polygon_type = boost::geometry::model::ring<bg_point_type>;
//Find the envelope of the region of the object
bg_polygon_type obj_region = //... it is a rectangle
boost::geometry::model::box<bg_point_type> envelope_box;
boost::geometry::envelope(obj_region, envelope_box);
auto const top_y = envelope_box.min_corner().y();
auto const bottom_y = envelope_box.max_corner().y();
auto const left = envelope_box.min_corner().x();
auto const right = envelope_box.max_corner().x();
//with min_corner and max_corner, we can know the top of the ring
auto const line_y = bottom_y - (bottom_y - top_y) * ratio;
//find the intersection of the line and the polygon
boost::geometry::model::linestring<bg_point_type> const line{{left, line_y}, {right, line_y}};
std::vector<bg_point_type> intersect;
boost::geometry::intersection(obj_region, line, intersect);
//remove those points higher than top
bg_polygon_type result = obj_region;
auto it = std::remove_if(std::begin(result ), std::end(result ), [=](auto const &pt)
{
return pt.y() < line_y;
});
result .erase(it, std::end(result ));
//insert the intersect points into the results
std::copy(std::begin(intersect), std::end(intersect), std::back_inserter(result));
boost::geometry::correct(result);
这个解决方案给了我需要的点,但没有给我想要的形状。
点为“0.1,0.1,0.1,0.5,0.5,0.5,0.5,0.1,0.1,0.1”,我有一个这样的环(为简单起见,我选择矩形为例)
裁剪环后,我希望它可以是(有点,0.1,0.5,0.1,0.3,0.5,0.3,0.5,0.5,0.1,0.5)
但它给了我 0.1,0.5,0.5,0.5,0.1,0.3,0.5,0.3,0.1,0.5
问题是,“正确的”多边形不是唯一的,我怎么能得到我想要的结果,如果在这里说的太长/太复杂,我应该搜索什么样的关键字?我试过“裁剪多边形”、“裁剪多边形的一部分”、“从多边形裁剪多边形”等。谢谢
编辑 1:obj_region 是简单的多边形
编辑2:sehe的解题
我将 crop_box 函数更改为从下到上裁剪并期望intersections api 会给我相同的结果,但它会返回一个奇怪的结果。
template <typename G>
bg_box_type crop_box(G const& geom, double ratio) {
bg_box_type env;
bg::envelope(geom, env);
auto const miny = env.min_corner().y();
auto const height = env.max_corner().y() - miny;
env.min_corner().set<1>(env.max_corner().y() - height*ratio);
return env;
}
输入:多边形((100.0 100.0,100.0 200.0,200.0 200.0,200.0 100.0,100.0 100.0))输出:POLYGON((100 200,100 150,200 200,200 150,100 200))--无效正确后输出:POLYGON((100 200,100 150,200 200,200 150,100 200))--无效
完整的源代码
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/algorithms/for_each.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/io/io.hpp>
#include <iostream>
#include <fstream>
namespace bg = boost::geometry;
using bg_point_type = bg::model::d2::point_xy<double>;
using bg_polygon_type = bg::model::ring<bg_point_type>;
using bg_box_type = bg::model::box<bg_point_type>;
template <typename G>
bg_box_type crop_box(G const& geom, double ratio) {
bg_box_type env;
bg::envelope(geom, env);
auto const miny = env.min_corner().y();
auto const height = env.max_corner().y() - miny;
env.min_corner().set<1>(env.max_corner().y() - height*ratio);
return env;
}
template <typename G>
void diags(std::string name, G& geom) {
std::cout << name << ": " << bg::wkt(geom) << "\n";
std::string reason;
if (!bg::is_valid(geom, reason)) {
std::cout << name << ": " << reason << "\n";
bg::correct(geom);
std::cout << bg::wkt(geom) << "\n";
if (!bg::is_valid(geom, reason)) {
std::cout << name << " corrected: " << reason << "\n";
}
}
}
int main() {
bool const visualize = true;
//Find the envelope of the region of the object
bg_polygon_type obj_region;
bg::read_wkt("POLYGON((100.0 100.0,100.0 200.0,200.0 200.0,200.0 100.0,100.0 100.0))", obj_region);
diags("Input", obj_region);
bg_polygon_type out;
bg::intersection(crop_box(obj_region, 0.5), obj_region, out);
diags("output", out);
std::cout << "Output: " << bg::wkt(out) << "\n";
if (visualize) {
std::ofstream svg("svg.svg");
boost::geometry::svg_mapper<bg_point_type> mapper(svg, 600, 600);
mapper.add(obj_region);
mapper.add(out);
mapper.map(obj_region, "fill-opacity:0.5;fill:rgb(204,153,0);stroke:rgb(204,153,0);stroke-width:2");
mapper.map(out, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
}
}
最佳答案
您只想将原始 region_obj
与其 envelope_box
的下半部分相交。
相反,通过仅找到交点的顶线,并强行随机删除多边形内的点,您正在创建一个无效的多边形:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/io/io.hpp>
#include <iostream>
namespace bg = boost::geometry;
using bg_point_type = bg::model::d2::point_xy<double>;
using bg_polygon_type = bg::model::ring<bg_point_type>;
template <typename G>
void diags(std::string name, G& geom) {
std::cout << name << ": " << bg::wkt(geom) << "\n";
std::string reason;
if (!bg::is_valid(geom, reason)) {
std::cout << name << " invalid: " << reason << "\n";
bg::correct(geom);
std::cout << name << " corrected: " << bg::wkt(geom) << "\n";
if (!bg::is_valid(geom, reason)) {
std::cout << name << " invalid: " << reason << "\n";
}
}
}
int main() {
double const ratio = 0.5;
//Find the envelope of the region of the object
bg_polygon_type obj_region;
bg::read_wkt("POLYGON((0.1 0.1,0.1 0.5,0.5 0.5,0.5 0.1,0.1 0.1))", obj_region);
diags("Input", obj_region);
bg::model::box<bg_point_type> envelope_box;
bg::envelope(obj_region, envelope_box);
auto const top_y = envelope_box.min_corner().y();
auto const bottom_y = envelope_box.max_corner().y();
auto const left = envelope_box.min_corner().x();
auto const right = envelope_box.max_corner().x();
//with min_corner and max_corner, we can know the top of the ring
auto const line_y = bottom_y - (bottom_y - top_y) * ratio;
//find the intersection of the line and the polygon
bg::model::linestring<bg_point_type> const line{{left, line_y}, {right, line_y}};
bg::model::multi_point<bg_point_type> intersect;
bg::intersection(obj_region, line, intersect);
std::cout << bg::wkt(intersect) << "\n";
//remove those points higher than top
bg_polygon_type result = obj_region;
auto it = std::remove_if(std::begin(result ), std::end(result ), [=](auto const &pt) { return pt.y() < line_y; });
result.erase(it, std::end(result ));
//insert the intersect points into the results
std::copy(std::begin(intersect), std::end(intersect), std::back_inserter(result));
diags("Result", result);
}
打印
Input: POLYGON((0.1 0.1,0.1 0.5,0.5 0.5,0.5 0.1,0.1 0.1))
MULTIPOINT((0.1 0.3),(0.5 0.3))
Result: POLYGON((0.1 0.5,0.5 0.5,0.1 0.3,0.5 0.3))
Result invalid: Geometry is defined as closed but is open
Result corrected: POLYGON((0.1 0.5,0.5 0.5,0.1 0.3,0.5 0.3,0.1 0.5))
Result invalid: Geometry has invalid self-intersections. A self-intersection point was found at (0.3, 0.4); method: i; operations: u/i; segment IDs {source, multi, ring, segment}: {0, -1, -1, 1}/{0, -1, -1, 3}
只需询问您的意思:
bg_polygon_type obj_region;
bg::read_wkt("POLYGON((0.1 0.1,0.1 0.5,0.5 0.5,0.5 0.1,0.1 0.1))", obj_region);
diags("Input", obj_region); // check validity/attempt correction
bg_polygon_type out;
bg::intersection(crop_box(obj_region, 0.5), obj_region, out);
std::cout << "Output: " << bg::wkt(out) << "\n";
当然,以类似的方式定义 crop_box
(只是到达裁剪包络线,而不是多点):
template <typename G>
bg_box_type crop_box(G const& geom, double ratio) {
bg_box_type env;
bg::envelope(geom, env);
auto miny = env.min_corner().y();
auto height = env.max_corner().y() - miny;
env.max_corner().set<1>(miny + height*ratio);
return env;
}
也添加可视化:
For visualization we scale all input by 100x
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/algorithms/for_each.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/io/io.hpp>
#include <iostream>
#include <fstream>
namespace bg = boost::geometry;
using bg_point_type = bg::model::d2::point_xy<double>;
using bg_ring_type = bg::model::ring<bg_point_type>;
using bg_polygon_type = bg::model::polygon<bg_point_type>;
using bg_multipolygon_type = bg::model::multi_polygon<bg_polygon_type>;
using bg_box_type = bg::model::box<bg_point_type>;
template <typename G>
bg_box_type crop_box(G const& geom, double ratio) {
bg_box_type env;
bg::envelope(geom, env);
auto const maxy = env.max_corner().y();
auto const height = maxy - env.min_corner().y() ;
env.min_corner().set<1>(maxy - height*ratio);
return env;
}
template <typename G>
void diags(std::string name, G& geom) {
std::cout << name << ": " << bg::wkt(geom) << "\n";
std::string reason;
if (!bg::is_valid(geom, reason)) {
std::cout << name << ": " << reason << "\n";
bg::correct(geom);
std::cout << bg::wkt(geom) << "\n";
if (!bg::is_valid(geom, reason)) {
std::cout << name << " corrected: " << reason << "\n";
}
}
}
int main(int argc, char** argv) {
bool const visualize = argc>1 && argv[1]==std::string("-v");
//Find the envelope of the region of the object
bg_polygon_type obj_region;
bg::read_wkt("POLYGON((0.1 0.1,0.1 0.5,0.5 0.5,0.5 0.1,0.1 0.1))", obj_region);
if (visualize) {
bg::for_each_point(obj_region, [](bg_point_type& p) { bg::multiply_value(p, 100.0); });
}
diags("Input", obj_region);
bg_multipolygon_type out;
bg::intersection(crop_box(obj_region, 0.5), obj_region, out);
diags("Output", out);
if (visualize) {
std::ofstream svg("svg.svg");
boost::geometry::svg_mapper<bg_point_type> mapper(svg, 600, 600);
mapper.add(obj_region);
mapper.add(out);
mapper.map(obj_region, "fill-opacity:0.5;fill:rgb(204,153,0);stroke:rgb(204,153,0);stroke-width:2");
mapper.map(out, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
}
}
打印
Input: POLYGON((0.1 0.1,0.1 0.5,0.5 0.5,0.5 0.1,0.1 0.1))
Output: MULTIPOLYGON(((0.1 0.5,0.5 0.5,0.5 0.3,0.1 0.3,0.1 0.5)))
或者当 enabling visualization :
Input: POLYGON((10 10,10 50,50 50,50 10,10 10))
Output: MULTIPOLYGON(((10 50,50 50,50 30,10 30,10 50)))
以及以下 svg 输出:
关于c++ - 通过 boost 几何从多边形(环)裁剪部分多边形(环),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50533441/
我想知道是否可以将简单的位图转换为几何对象 最佳答案 是的,您可以使用跟踪。 Potrace是一个开源的位图到矢量跟踪器库。 然而,位图追踪并不完美。对于高质量的矢量图像,line tracer 一般
这类似于this question,但是却相反。 我有两个地理位置(纬度,经度)A和B。假设它们相距40海里。我想计算在A和B之间的直线上,从A点起10海里处的坐标。数学(我每天使用的其他一些数学),
我想计算一个点到由 2 个点定义的直线的距离。 我正在使用 javascript,这就是我使用维基百科得出的结论:https://en.wikipedia.org/wiki/Distance_from
我对 boost::geomentry 有疑问。 #include #include #include #include int main(){ typedef boost::geometry
我有一个问题。我想将四边形与四边形相交。 int main(){ typedef boost::geometry::model::point_xy TBoostPoint; typedef b
我无法在 OpleGL 中获得正确的转换。 我有 point3D - P(X,Y,Z) 和投影矩阵 M,它等于 K*(R|T) 其中 K - 相机标定矩阵 (R|T)——点(物)坐标系变换(R——旋转
我想做一个凸面(由一些直线或圆弧组成)围绕它的几何中心(Cx,Cy)旋转。同时凸面两侧有两个圆(由半径给出:R 和左中心:(Lx,Cy),右中心:(Rx,Cy))。表示与几何(Cy) X 轴相同的圆心
我有一个 DrawingVisual表示路径的元素,该路径的几何描述由此 syntax : "m106,59.3c0-1.98,0,0-4.95,0.989-3.96,0.989-13.8,3.96-
如何将我自己的数据集转换为可供 pytorch 几何图形神经网络使用的数据集? 所有教程都使用已转换为 pytorch 可用的现有数据集。例如,如果我有自己的点云数据集,我如何使用它来训练图神经网络的
我正在使用 PyQt5 和 OpenCV。我想创建一个读取视频帧并执行橡皮筋拉伸(stretch)以生成几何图形的类,该几何图形将由不同的类用于裁剪视频流(此示例中不包括第二类)。 在此示例中,从网络
我们有两个 (PostgreSQL 9.2) 表。第一城市: loc_id | integer | not null name | character
我有一张 table : create table if not exists places( id bigserial not null constraint places_pkey primary
我在 postgresql 中有一个带有 PostGIS geometry(point, 4326) 列(位置,使用 SRID 4326)的表,我有一个使用 SQL Alchemy 更新表(其余列)的
我开始使用 c++11 并尝试使用 boost geometry 运行一些示例代码 #include #include #include #include BOOST_GEOMETRY_REG
我有一个存储为 csv 文件的数据框,其中一列是多边形对象。但是,此列存储为字符串而不是 GeoPandas 几何对象。如何将此列转换为 Geopandas 几何对象以便执行地理分析? 这是我的数据的
我从两台相同品牌的相机拍摄的两张图像相距一定距离,拍摄相同的场景。我想计算两个相机之间的真实世界旋转和平移。为了实现这一点,我首先提取了两个图像的 SIFT 特征并匹配它们。 我现在有了基本矩阵以及单
我目前正在使用 boost 几何/空间索引库,以便对 3d 边界框执行范围查询。例如,我能够获得与查询边界框重叠的所有边界框的列表。 文档 ( http://www.boost.org/doc/lib
boost::geometry::model::point 将点的维度作为编译时参数。例如, typedef bg::model::point point; 有没有什么方法可以在运行时指定维度,比如说
我一直在寻找一种在 three.js 中将 uv 映射添加到我的自定义几何体的方法。我找到了这样做的方法,但我找到的解决方案都没有用。谁能解释一下 uv-mapping 的工作原理以及如何正确使用它?
在我的应用程序中,用户可以使用 iPhone 的 GPS 定义足球场的三个角落,方法是一个接一个地走到角落,然后点击按钮。这很好用,我可以在屏幕上绘制生成的矩形,类似于它在 Google map 中的
我是一名优秀的程序员,十分优秀!