// Author: Dmitry Anisimov. // We use an almost degenerate triangle with one side of length 1 and an exact data type // in order to test coordinates computed for some strictly interior points. // The test itself consists of generating some strictly interior points and then checking // the linear precision property of obtained coordinates. Some points close to the boundary // up to 1.0e-300 are used, and coordinates for the center point are checked to be exactly 1/3. // Does not work with inexact kernel! Get inconsistency when comparing difference with zero. #include #include #include #include typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; typedef Kernel::FT Scalar; typedef Kernel::Point_2 Point; typedef std::vector Coordinate_vector; typedef std::back_insert_iterator Vector_insert_iterator; typedef CGAL::Barycentric_coordinates::Triangle_coordinates_2 Triangle_coordinates; typedef boost::optional Output_type; using std::cout; using std::endl; using std::string; using std::pow; int main() { const Point first_vertex = Point(0, 0); const Point second_vertex = Point(1, 0); const Point third_vertex = Point(Scalar(-1)/Scalar(2), Scalar(1)/Scalar(pow(10.0, 200.0))); Triangle_coordinates triangle_coordinates(first_vertex, second_vertex, third_vertex); const Point query_points[12] = { Point(0, Scalar(1)/Scalar(pow(10.0, 201.0))), Point(0, Scalar(1)/Scalar(pow(10.0, 220.0))), Point(0, Scalar(1)/Scalar(pow(10.0, 240.0))), Point(0, Scalar(1)/Scalar(pow(10.0, 260.0))), Point(0, Scalar(1)/Scalar(pow(10.0, 280.0))), Point(0, Scalar(1)/Scalar(pow(10.0, 300.0))), Point(Scalar(1)/Scalar(2), Scalar(1)/Scalar(pow(10.0, 200.5))), Point(Scalar(1)/Scalar(2), Scalar(1)/Scalar(pow(10.0, 201.0))), Point(Scalar(1)/Scalar(2), Scalar(1)/Scalar(pow(10.0, 260.0))), Point(Scalar(1)/Scalar(2), Scalar(1)/Scalar(pow(10.0, 280.0))), Point(Scalar(1)/Scalar(2), Scalar(1)/Scalar(pow(10.0, 300.0))), Point( (Scalar(1)/Scalar(3))*Scalar(first_vertex.x() + second_vertex.x() + third_vertex.x()) , (Scalar(1)/Scalar(3))*Scalar(first_vertex.y() + second_vertex.y() + third_vertex.y()) ) }; Coordinate_vector coordinates; int count = 0; const Point zero(0, 0); for(int i = 0; i < 12; ++i) { const Output_type result = triangle_coordinates(query_points[i], std::back_inserter(coordinates)); const Point linear_combination( first_vertex.x()*coordinates[count + 0] + second_vertex.x()*coordinates[count + 1] + third_vertex.x()*coordinates[count + 2] , first_vertex.y()*coordinates[count + 0] + second_vertex.y()*coordinates[count + 1] + third_vertex.y()*coordinates[count + 2] ); const Point difference(linear_combination.x() - query_points[i].x(), linear_combination.y() - query_points[i].y()); assert(difference == zero); if(difference != zero) { cout << endl << "Almost_degenerate_triangle_test: FAILED." << endl << endl; exit(EXIT_FAILURE); } count += 3; } const Scalar third = Scalar(1)/Scalar(3); assert(coordinates[33] - third == Scalar(0) && coordinates[34] - third == Scalar(0) && coordinates[35] - third == Scalar(0)); if( coordinates[33] - third != Scalar(0) || coordinates[34] - third != Scalar(0) || coordinates[35] - third != Scalar(0) ) { cout << endl << "Almost_degenerate_triangle_test: FAILED." << endl << endl; exit(EXIT_FAILURE); } cout << endl << "Almost_degenerate_triangle_test: PASSED." << endl << endl; return EXIT_SUCCESS; }