私はCGALを使用していて、小さなテストプログラムでは再現できない奇妙なバグに陥りました。与えられたとおりに動作するテスト コードを次に示しますが、より大きなプログラム (ROS ノード) にまったく同じコードを使用すると、エラーが発生します。
#include <vector>
#include <boost/shared_ptr.hpp>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/Boolean_set_operations_2.h>
#include "print.h"
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT Ft;
typedef Kernel::Point_2 Point;
typedef Kernel::Segment_2 Segment;
typedef Kernel::Direction_2 Direction;
typedef Kernel::Line_2 Line;
typedef Kernel::Vector_2 Vector;
typedef CGAL::Polygon_2<Kernel> Polygon;
typedef CGAL::Polygon_with_holes_2<Kernel> PolygonWithHoles;
main() {
Polygon poly;
float scale = 4.0/100;
float max_y = 500*scale;
poly.push_back(Point(76*scale, max_y-496*scale));
poly.push_back(Point(660*scale, max_y-496*scale));
poly.push_back(Point(660*scale, max_y-48*scale));
poly.push_back(Point(71*scale, max_y-54*scale));
// Holes must be clock wise!!
Polygon holes[10];
holes[0].push_back(Point(131*scale, max_y-86*scale));
holes[0].push_back(Point(179*scale, max_y-85*scale));
holes[0].push_back(Point(180*scale, max_y-238*scale));
holes[0].push_back(Point(133*scale, max_y-239*scale));
holes[1].push_back(Point(237*scale, max_y-84*scale));
holes[1].push_back(Point(286*scale, max_y-84*scale));
holes[1].push_back(Point(288*scale, max_y-237*scale));
holes[1].push_back(Point(240*scale, max_y-238*scale));
// Why does this hole make intersection() error?
holes[2].push_back(Point(345*scale, max_y-84*scale));
holes[2].push_back(Point(393*scale, max_y-83*scale));
holes[2].push_back(Point(396*scale, max_y-236*scale));
holes[2].push_back(Point(348*scale, max_y-236*scale));
PolygonWithHoles polyHoles(poly);
polyHoles.outer_boundary() = poly;
for (int i=0; i<3; ++i)
polyHoles.add_hole(holes[i]);
std::cout << "\nPolygon:" << std::endl;
print_polygon_with_holes(polyHoles);
Polygon selection;
float minx = -5.7669;
float miny = -2.13124;
float maxx = 0.396996;
float maxy = 4.88933;
selection.push_back(Point(minx, miny));
selection.push_back(Point(maxx, miny));
selection.push_back(Point(maxx, maxy));
selection.push_back(Point(minx, maxy));
std::cout << "\nSelection:" << std::endl;
print_polygon(selection);
std::vector<PolygonWithHoles> result;
CGAL::intersection(polyHoles, selection, std::back_inserter(result));
std::cout << "Intersection:" << std::endl;
if (!result.empty())
print_polygon_with_holes(result.front());
}
エラー:
terminate called after throwing an instance of 'CGAL::Precondition_exception'
what(): CGAL ERROR: precondition violation!
Expr: comp_f(object, parentP->object) != SMALLER
File: /usr/include/CGAL/Multiset.h
Line: 2128
これを修正する2つの方法を見つけました:
- 1 ポイントを少しシフトします。83 を 84 に置き換えます。
- Exact_predicates_exact_constructions_kernel を使用する
私の質問は、問題がより大きなプログラムにのみ存在する原因は何ですか?
unexact_constructions を引き続き使用したいのですが、この場合に exact_constructions を使用する必要がある理由がわかりません (ポイントが互いに接近していないなど)。 () アルゴリズムについては、私が間違っている可能性があります。