【问题标题】:Similar to Computing the Exact Offset in CGAL, can I compute the "exact buffer" of a polyline?类似于在 CGAL 中计算精确偏移量,我可以计算折线的“精确缓冲区”吗?
【发布时间】:2021-07-15 18:49:46
【问题描述】:

是否有任何已经构建并准备好使用的 C++ 算法,类似于 CGAL 的 offset_2 函数,但不是计算圆和多边形的 Minkowski 和,而是计算圆和折线的 Minkowski 和(即折线的缓冲区)?

在应用程序中,这是我想做的:

  1. 输入具有 n 个顶点的折线:([x_0,y_0],[x_1,y_1],...,[x_n-1,y_n-1])
  2. 找到这条折线的确切缓冲区(输出是一个可能有洞的多边形)
  3. 提取每个单独的圆锥弧以测试与我拥有的其他线的交点。
  4. 显示此缓冲折线

谢谢

编辑:可能的解决方案

我可以在每个顶点处生成一个半径为 r 的圆,并在每个线段上生成一个宽度为 2r 的矩形,然后取它们的并集吗?

如果我正确理解了 CGAL 文档,我可以得到一个精确的解决方案(即由圆锥弧组成的东西),对吗?如果是这样,我们将不胜感激。

【问题讨论】:

  • 我不知道这个包,但是将折线 ABCDE 变成平面多边形 ABCDEDCB 有帮助吗?
  • @MarcGlisse 是否允许这种类型的多边形?我对 CGAL 还很陌生,但这是否也会导致计算效率低下?
  • @MarcGlisse 我按照你的建议做了,但它返回以下错误:CGAL ERROR: precondition violation!,然后是Expr: pgn.is.simple()。所以看来我不能使用平面多边形,因为它们并不简单。
  • @MarcGlisse 我发布了这个问题的解决方案,我们将不胜感激第二个意见。感谢您所做的一切,您似乎总是对我的问题发表评论并提供最大的帮助!

标签: c++ computational-geometry cgal


【解决方案1】:

因此,根据我建议的解决方案,折线和半径为 r 的圆的 Minkowski 总和是每个顶点处的圆或半径 r 和宽度为 r 的矩形的并集。

之后,我使用了Boolean Set-Operations on General Polygons 以及其中的示例,它方便地采用矩形圆的并集。其主要特点是使用了GeneralPolygon_2 概念,这使我可以得到线性函数和圆弧形式的精确解。

这是我的代码的 sn-p(请注意,我输入的折线使用复坐标):

Polygon_set_2 S;
// Generate a Circle for each Vertex
for (int i=0; i<complexPolygon.size(); ++i){
    S.join(construct_polygon(Circle_2(Point_2(real(complexPolygon[i]), imag(complexPolygon[i])),1)));
}
// Generate a Rectangle for Each Ordered Pair of Vertices
for (int i=0; i<complexPolygon.size()-1; ++i){
    complex<double> P1, P2, P12, R1, R2, R3, R4;
    P1 = complexPolygon[i];
    P2 = complexPolygon[i+1];
    P12 = P2-P1;
    R1 = P1 - complex<double>(0,w)*P12/abs(P12);
    R4 = P1 + complex<double>(0,w)*P12/abs(P12);
    R2 = R1 + P12;
    R3 = R4 +P12;

    S.join(construct_polygon(Point_2(real(R1), imag(R1)), Point_2(real(R2), imag(R2)),
                             Point_2(real(R3), imag(R3)), Point_2(real(R4), imag(R4))));
}
fstream minkFile;
minkFile.open("mink.txt",ios::out);//open in write mode
if(minkFile.is_open()){
    list<Polygon_with_holes_2> res;
    S.polygons_with_holes (std::back_inserter (res));
    copy (res.begin(), res.end(),
    ostream_iterator<Polygon_with_holes_2>(minkFile, "\n"));
    cout << endl;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-02
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    相关资源
    最近更新 更多